如何做网站泛目录解析,wordpress新建站网页不显示图片,加工活外放的正规公司,企业邮箱多少钱1.Makefile
1.1 什么是 Makefile
一个工程中有很多文件#xff0c;文件之间都是相辅相成有着编译的先后顺序#xff0c;但是如果自己手动根据编译顺序编译文件造成速度非常慢。Makefile 是”自动化编译“#xff0c;只需一个 make 指令系统就会根据编译顺序帮自己编译文件…1.Makefile
1.1 什么是 Makefile
一个工程中有很多文件文件之间都是相辅相成有着编译的先后顺序但是如果自己手动根据编译顺序编译文件造成速度非常慢。Makefile 是”自动化编译“只需一个 make 指令系统就会根据编译顺序帮自己编译文件
1.2 Makefile 文件命名规则 1.3 代码演示
1.生成一个 Makefile 文件
vim Makefile2.将执行规则书写入 Makefile 3.使用 make 编译 Makefile 文件
sudo apt install make // 安装 make
make // 在 Makefile 所在文件夹执行指令可以看到下图中输出了 Makefile 中的相关指令与此同时在对应的文件下生成的 app 可执行文件 4.执行 app 可执行文件
./app这个 Makefile 是 make 默认执行的文件如果不想叫 Makefile 也可以自定义名称那么在 make 时后面就要拼接相应的文件名称。比如新建的 Makefile 替代文件是 abc
make abc1.4 Makefile 的工作原理 1.命令执行之前检查规则中的依赖是否存在
当发现前面的命令找不到时 Makefile 文件会顺着继续向下查找后面的目标有没有有关生成前面相关文件的如下图一开始是没有 add.o 文件的但是 makefile 文件会继续向下查找有没有生成 .o 的文件指令
Makefile 的指令都是为第一条指令服务的 2.检测更新
Makefile 会对文件进行检测比如使用 make 编译过 Makefile 文件的情况下再使用 make 编译 Makefile 文件就发现提示 这是因为 make 是检查更新的如果其中的文件没有更改则就不会执行 Makefile 中的指令
1.5 Makefile 的优化
下面就要对下图的这些定义进行优化。优化一共分为三个步骤使用变量将长字符串代替使用通配符将重复的后缀代替使用查找替换将长字符串中的后缀名进行查找替换 1.使用变量进行优化
如上图所示可以使用变量代替一个长的字符串 重新定义 Makefile 文件使用变量形式将长字符串进行取代
在最开头定义了两个变量 src 和 target 并为其赋值。在后面使用 $(变量名) 的方法得到该变量的值。这样长字符串就在前面被定义了 2.使用通配符简化命令代码
在文件中有很多 .c .o 的文件% 可以理解为是 * 的操作%.o 类似于 *.o这样的话会将所有的 .o 文件生成 .c 文件 3.使用“查找替换”将所有文件名替换
查找
在自定义变量中定义了可以进行通配的文件名下面对这些文件名进行替换
示例的意思是将本路径所有 *.c 和 sub 文件下的 *.c 文件名查找出来 替换 查找到 text 中的单词 patten 并用 replacement 进行替换 最后 make 执行的结果 1.6 中间文件的清除
从 .c 文件到 app 可执行文件生成过程中产生大量 .o 的中间文件下面使用 clean 的方法将中间过程的 .o 文件进行删除。同样是在 Makefile 中进行定义 执行下面的指令就可以进行 clean 操作 对 clean 操作生成伪目标
指示 clean 是一个假的定义操作。真的定义操作利用了自定义 Makefile 的方法定义的
.PHONY:clean 2.Cmake 的使用
2.1 执行一个文件
S1写一个 .cpp 文件
#main.cpp
#include iostream
int main(){std::cout hello word std::endl;
}S2写一个 CMakeLists.txt 文件
#CMakeLists.txtPROJECT (HELLO)SET(SRC_LIST main.cpp)MESSAGE(STATUS This is BINARY dir ${HELLO_BINARY_DIR})MESSAGE(STATUS This is SOURCE dir ${HELLO_SOURCE_DIR})ADD_EXECUTABLE(hello ${SRC_LIST})S3对该文件进行 cmake
cmake . // 其中 . 就代表 CMakeLists.txt 在当前目录中然后就进行 build 目录下就会生成文件关键是生成了 Makefile 的文件 S4再使用 make 对文件进行编译生成可执行文件
make 2.2 CMake 常用指令
PROJECT关键字
可以用来指定工程的名字和支持的语言默认支持所有语言
PROJECT (HELLO) 指定了工程的名字并且支持所有语言—建议
PROJECT (HELLO CXX) 指定了工程的名字并且支持语言是C
PROJECT (HELLO C CXX) 指定了工程的名字并且支持语言是C和C
该指定隐式定义了两个CMAKE的变量
_BINARY_DIR本例中是 HELLO_BINARY_DIR
_SOURCE_DIR本例中是 HELLO_SOURCE_DIR
MESSAGE关键字就可以直接使用者两个变量当前都指向当前的工作目录后面会讲外部编译
问题如果改了工程名这两个变量名也会改变
解决又定义两个预定义变量PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR这两个变量和HELLO_BINARY_DIRHELLO_SOURCE_DIR是一致的。所以改了工程名也没有关系
SET关键字
用来显示的指定变量的
SET(SRC_LIST main.cpp) SRC_LIST变量就包含了main.cpp
也可以 SET(SRC_LIST main.cpp t1.cpp t2.cpp)
MESSAGE关键字
向终端输出用户自定义的信息
主要包含三种信息
SEND_ERROR产生错误生成过程被跳过。SATUS输出前缀为—的信息。FATAL_ERROR立即终止所有 cmake 过程.
在我们进行 cmake 的时候这两句话也会被显示出来 ADD_EXECUTABLE关键字
生成可执行文件
ADD_EXECUTABLE(hello ${SRC_LIST}) 生成的可执行文件名是hello源文件读取变量SRC_LIST中的内容
也可以直接写 ADD_EXECUTABLE(hello main.cpp)
上述例子可以简化的写成
PROJECT(HELLO) ADD_EXECUTABLE(hello main.cpp)
注意工程名的 HELLO 和生成的可执行文件 hello 是没有任何关系的
语法的基本原则 变量使用${}方式取值但是在 IF 控制语句中是直接使用变量名 指令(参数 1 参数 2…) 参数使用括弧括起参数之间使用空格或分号分开。 以上面的 ADD_EXECUTABLE 指令为例如果存在另外一个 func.cpp 源文件 就要写成ADD_EXECUTABLE(hello main.cpp func.cpp)或者ADD_EXECUTABLE(hello main.cpp;func.cpp) 指令是大小写无关的参数和变量是大小写相关的。但推荐你全部使用大写指令
语法注意事项
SET(SRC_LIST main.cpp) 可以写成 SET(SRC_LIST “main.cpp”)如果源文件名中含有空格就必须要加双引号ADD_EXECUTABLE(hello main) 后缀可以不行他会自动去找.c和.cpp最好不要这样写可能会有这两个文件main.cpp和main
2.3 cmake 的内部构建和外部构建
上面的方法在 hello.cpp 的所在目录下进行 cmake 属于内部构建但是我们经常看到在 build 中进行构建从而生成那一堆 cmake 文件那样的方法叫做外部构建
mkdir build
cd build
cmake .. // CMakeLists.txt 在 build 外面2.4 创建一个 cpp 工程
一个工程中有多个文件我们要对这所有的文件进行编译下面是文件的目录
文件保存在 /Users/xuguagua/Documents/C/mianshi/cmake_demo 中
[rootlocalhost cmake]# tree
.
├── build
├── CMakeLists.txt
└── src├── CMakeLists.txt└── main.cpp在每一个文件夹下都要创建 CMakeLists.txt,所以在 src 中也要创建一个 CMakeLists.txt 文件
1.在最外层 CMakeLists.txt 写的内容
这里会单独创建一个 bin 目录即使 bin 中没有创建文件夹也会自动创建并将可执行文件放入
cmake_minimum_required(VERSION 3.23)
project(cmake_demo)
set(CMAKE_CXX_STANDARD 14)
ADD_SUBDIRECTORY(src bin) # 将最外层的 cmake 关联到 src 的 cmake。bin 文件夹如果不存在则自动创建2.在 src CMakeLists.txt 中
这个文件只需要指明可执行文件是谁叫啥
ADD_EXECUTABLE(hello main.cpp) # hello 是生成的可执行软件的名字2.5 cmake install 方法
将项目生成的库文件、头文件、可执行文件或相关文件等安装到指定位置系统目录或发行包目录。在cmake中这主要是通过install方法在CMakeLists.txt中配置make install命令安装相关文件来实现的。
S1首先我们创建下面的工程目录
├── build
├── CMakeLists.txt
├── COPYRIGHT
├── doc
│ └── hello.txt
├── README
├── runhello.sh
└── src├── CMakeLists.txt└── main.cpp安装文件COPYRIGHT和README
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)
FILES文件
DESTINATION
1、写绝对路径
2、可以写相对路径相对路径实际路径是${CMAKE_INSTALL_PREFIX}/DESTINATION 定义的路径
CMAKE_INSTALL_PREFIX 默认是在 /usr/local/
cmake -DCMAKE_INSTALL_PREFIX/usr 在cmake的时候指定CMAKE_INSTALL_PREFIX变量的路径
安装脚本runhello.sh
PROGRAMS非目标文件的可执行程序安装(比如脚本之类)
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
说明实际安装到的是 /usr/bin
安装 doc 中的 hello.txt 一、是通过在 doc 目录建立CMakeLists.txt 通过install下的file 二、是直接在工程目录通过 INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)
DIRECTORY 后面连接的是所在 Source 目录的相对路径
注意abc 和 abc/有很大的区别
目录名不以/结尾这个目录将被安装为目标路径下的
目录名以/结尾将这个目录中的内容安装到目标路径
安装过程
cmake ..
make
sudo make install最终文件
那么在 CMakeLists.txt 中的显示就是如下
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/) # 安装这两个文件到这个网址
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)在执行完安装后相应的路径下就会看到这几个文件 2.6 创建动态库
有时候我们想让自己的库生成 .so 文件或者 .dll 文件供外面使用那么我们就要为该 pro 创建一个共享库步骤如下
文件目录如下
[rootlocalhost cmake2]# tree
.
├── build
├── CMakeLists.txt
└── lib├── CMakeLists.txt├── hello.cpp└── hello.h其中 hello.cpp 的内容
#include hello.h
#include iostream
void HelloFunc(){std::cout Hello World std::endl;
}hello.h 的内容
#ifndef HELLO_H
#define Hello_H
void HelloFunc();
#endif然后就在 CMakeLists.txt 文件中放入相应的链接
项目中的cmake内容
PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)lib中CMakeLists.txt中的内容
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})ADD_LIBRARY
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
hello就是正常的库名生成的名字前面会加上lib最终产生的文件是libhello.soSHARED动态库 STATIC静态库${LIBHELLO_SRC} 源文件
2.7 同时生成静态库和动态库
S1在上一步创建好 hello.cpp 文件之后需要同时生成 .so 和 .a 文件
在 lib 的 CMake 中执行指令
SET(LIBHELLO_SRC hello.cpp)ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
//对hello_static的重名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME hello)
//cmake 在构建一个新的target 时会尝试清理掉其他使用这个名字的库因为在构建 libhello.so 时 就会清理掉 libhello.a
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME hello)
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
最后生成效果如下图所示.so 是动态库.a 是静态库 动态库的版本号
一般动态库都有一个版本号的关联
libhello.so.1.2
libhello.so -libhello.so.1
libhello.so.1-libhello.so.1.2CMakeLists.txt 插入如下
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本SOVERSION 指代 API 版本。
S2将库安装到 /usr 文件夹下
安装共享库和头文件
本例中我们将 hello 的共享库安装到/lib目录
将 hello.h 安装到/include/hello 目录
//文件放到该目录下
INSTALL(FILES hello.h DESTINATION include/hello)//二进制静态库动态库安装都用TARGETS
//ARCHIVE 特指静态库LIBRARY 特指动态库RUNTIME 特指可执行目标二进制。
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)注意
安装的时候指定一下路径放到系统下
cmake -DCMAKE_INSTALL_PREFIX/usr ..
2.8 使用共享库
刚才我们已经生成了 .so 文件和 .a 文件并放到了 /usr 的目录下下面就尝试在工程下调用这两个库