浅谈cmake

cmake是⾼级编译配置⼯具,是处理⼤型C/C++/JAVA项⽬的一个编译工具。
cmake的所有操作都是通过编译CMakeLists.txt来完成的,这里需要注意的是,CMakeLists.txt文件名不能有错,特别是大小写。

关键字

在介绍之前,先说明一下。指令是⼤⼩写⽆关的,参数和变量是⼤⼩写相关的,但仍然推荐全部使⽤⼤写指令。

1.PROJECT

可以⽤来指定⼯程的名字和⽀持的语⾔,默认⽀持所有语⾔,如PROJECT (HELLO)
PROJECT (HELLO CXX)指定了⼯程的名字,并且⽀持语⾔是C++,如果需要支持多种语言,用空格分隔。

2.SET

显式指定变量命名,多个变量用空格分隔。

3.MESSAGE

向终端输出用户自定义信息,类似"cout"等。
cmake输出的信息有三种:
SEND_ERROR,产⽣错误,⽣成过程被跳过。
STATUS,输出前缀为—的信息。
FATAL_ERROR,⽴即终⽌所有 cmake 过程。

4.ADD_EXECUTABLE

生成可执行文件。用法如ADD_EXECUTABLE(hello main.cpp)
这样就会生成hello的可执行文件。

5.ADD_SUBDIRECTORY

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
这个指令⽤于向当前⼯程添加存放源⽂件的⼦⽬录,并可以指定中间⼆进制和⽬标⼆进制存放的位置。一句话说,就是告诉cmake还有别的目录。
binary_dir指定编译结果存放的目录。如果不指定,自动放到./src目录(没有则创建)下。
EXCLUDE_FROM_ALL函数是将写的⽬录从编译中排除。

6. INSTALL

使用cmake安装文件,这些文件可以是⼆进制、动态库、静态库以及⽂件、⽬录、脚本等
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)
FILES是类型名,指头文件,如果是不同的文件会有不同:TARGETS指二进制文件(.so和.a),ARCHIVE 特指静态库,LIBRARY 特指动态库,PROGRAMS是非目标可执行程序,目录也用这个。FILES后是文件名。要注意目录的话加不加"/“会有区别,加”/"只是代表目录下的所有文件,不加则表示这个目录。
DESTINATION后是安装路径,有两种写法:一是写绝对路径;二是写相对路径,相对路径实际路径是:${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>。这里注意CMAKE_INSTALL_PREFIX默认是在/usr/local/,可以通过cmake -DCMAKE_INSTALL_PREFIX=/usr 在cmake的时候指定CMAKE_INSTALL_PREFIX变量的路径。这里-D后面可以用空格隔开,也可以不用,建议隔开。
后期需要使用make install。

7.ADD_LIBRARY

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
建立一个动态库,建立静态库的话,把SHARED换成STATIC,不写的话,默认是静态库。
这里还需要注意,一是cmake会给库名自动加上前后缀,如上例中为libhello.so。另外还有一点,实际开发过程中,希望静态库与动态名字相同。这里玩要注意,如果要同时建立多个库,库名不能相同,即使一个动态一个静态,也会实际只生成一个。

8.SET_PROPERTIES

这条指令可以⽤来设置输出的名称,对于动态库,还可以⽤来指定动态库版本和 API 版本,同时构建静态和动态库。具体用法如下:

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)

9.INCLUDE_DIRECTORIES

这条指令可以⽤来向⼯程添加多个特定的头⽂件搜索路径,路径之间⽤空格分隔。在编译时找不到头文件时使用,括号里直接写路径名即可。

10.TARGET_LINK_LIBRARIES

这条指令用来添加需要链接的共享库。
TARGET_LINK_LIBRARIES(main libhello.so)
注意这句话要在ADD_EXECUTABLE指令之前,还要注意考虑32位和64位的问题,因为有lib和lib64两个目录。另外,如果动态库和静态库名字相同,优先调用动态库,这一点要注意。

11.AUX_SOURCE_DIRECTORY

找在某个路径下的所有源⽂件
aux_source_directory(<dir> <variable>)

12.FOREACH

cmake中的遍历功能,与ENDFOREACH()配合使用
用法如下

FOREACH(SUB_DIR ${SUB_DIR_LIST})
#遍历源⽂件
AUX_SOURCE_DIRECTORY(${SUB_DIR} SRC_LIST)
ENDFOREACH()

13.ADD_COMPILE_OPTIONS

cmake中的编译选项。
编译动态库AUX_SOURCE_DIRECTORY(-fPIC)

变量

cmake里有很多变量,可通过MESSAGE指令打印出来的方法来查看这些变量到底是什么。这里只介绍部分常用地的变量。

1.x_BINARY_DIR和x_SOURCE_DIR

分别代表build路径和源路径。x是项目名,如果项目名改变,上面两个变量名也会发生变化。解决这个问题,可以用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR,它们和刚才两个变量一样,只是名字不会变化。

2.CMAKE_INSTALL_PREFIX

cmake生成文件是默认加的路径前缀,默认是/usr/local/。

3.CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH

这两个是linux的环境变量,可以在linux的bash中进⾏设置,也可以使⽤export CMAKE_INCLUDE_PATH=/usr/include/hello

4.CMAKE_CURRENT_SOURCE_DIR

当前源码所在目录。

5.LIBRARY_OUTPUT_PATH和EXECUTABLE_OUTPUT_PATH

库文件生成目录和执行文件生成目录。

语法

1.变量使⽤${}⽅式取值,但是在 IF 控制语句中是直接使⽤变量名。
2.指令(参数 1 参数 2…) 参数使⽤括弧括起,参数之间使⽤空格或分号分开。

内部构建和外部构建

内部构建就是在源码所在目录构建cmake项目,由于产生的文件较多,不方便清理。
外部构建就是再另起一个目录进行构建,不会对源⽂件有任何影响,强烈使⽤外部构建⽅式。

工程化构建cmake

1.为⼯程添加⼀个⼦⽬录src,⽤来放置⼯程源代码。
2.添加⼀个⼦⽬录doc,⽤来放置这个⼯程的⽂档hello.txt。
3.在⼯程⽬录添加⽂本⽂件COPYRIGHT,README。
4.在⼯程⽬录添加⼀个runhello.sh脚本,⽤来调⽤hello⼆进制。
5.将构建后的⽬标⽂件放⼊构建⽬录的bin⼦⽬录。
6.将doc⽬录的内容以及COPYRIGHT/README安装到/usr/share/doc/cmake/。

构建debug版本

上面所构建的项目默认是release版本,有时为了调试,会构建debug版本,可以使用gdb等调试工具。
cmake -DCMAKE_BUILD_TYPE=debug还是注意一下-D可以分开。

跨平台

cmake还可以在WIN32、APPLE等平台上使用,主要是标志上的区别。但是对于服务器开发而言,一般很少用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值