cmake学习(一)静态库与动态库构建
(.so)共享库,shared object:节省空间,在运行时去连接,如果执行机器上没有这些库文件就不能执行。
(.a)静态库,archive:静态库和程序化为一体,不会分开。
通过 ldd命令可以查看一个可执行程序所依赖的的共享库。
使用环境变量LD_LIBRARY_DIRECTORY可以指定共享库位置
一、编译共享库:
ADD_LIBRARY(hello SHARED ${SHARED_LIBRARY})
二、添加静态库:
ADD_LIBRARY(hello STATIC ${STATIC_LIBRARY})
因为默认规则是不能有相同名字的共享库与静态库,所以当生成静态库的时候(so后缀),共享库会被删除,因为只能允许一个名字存在,相同名字的会被替代(hello),所以需要通过SET_TARGET_PROPERTIES()来解决这个问题,例子:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
cmake在构建一个target的时候,会删除之前生成的target,一样是通过设置SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)来达到目的
三、动态库的版本号:
同样是通过SET_TARGET_PROPERTIES()来设置
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION:动态库版本
SOVERSION:API版本
最后生成的结果是:
libhello.so.1.2
libhello.so.1->libhello.so.1.2
libhello.so->libhello.so.1
四、安装:
INSTALL(TARGETS hello hello_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
INSTALL(TARGETS hello.h
DESTINATION include/hello)
其他常用的属性 PERMISSIONS:设置权限;RATTERN:设置正则表达式
Summary:
ADD_LIBRARY():添加一个库,共享库,静态库,模块
SET_TARGET_PROPERTIES():设置输出名称,版本号,解决相同target被删除的问题
GET_TARGET_PROEERTIES():与SET功能相对
cmake学习(二)常用变量和常用环境变量
一、变量的引用方式是使用“${}”,在IF中,不需要使用这种方式,直接使用变量名即可
二、自定义变量使用SET(OBJ_NAME xxxx),使用时${OBJ_NAME}
三、cmake的常用变量:
CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR:
这三个变量内容一致,如果是内部编译,就指的是工程的顶级目录,如果是外部编译,指的就是工程编译发生的目录。
CMAKE_SOURCE_DIR,PROJECT_SOURCE_DIR,_SOURCE_DIR:
这三个变量内容一致,都指的是工程的顶级目录。
CMAKE_CURRENT_BINARY_DIR:外部编译时,指的是target目录,内部编译时,指的是顶级目录
CMAKE_CURRENT_SOURCE_DIR:CMakeList.txt所在的目录
CMAKE_CURRENT_LIST_DIR:CMakeList.txt的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:如果工程复杂,可能需要编写一些cmake模块,这里通过SET指定这个变量
LIBRARY_OUTPUT_DIR,BINARY_OUTPUT_DIR:库和可执行的最终存放目录
PROJECT_NAME:你猜~~
四、cmake中调用环境变量
1.Using $ENV{NAME} : invoke system environment varible.
We can use "SET(ENV{NAME} value)" as well. note that the "ENV" without "$".
2.CMAKE_INCLUDE_CURRENT_DIR equal to INCLUDE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
五、其他的内置变量
1.BUILD_SHARED_LIBS:set the default value when using ADD_LIBRARY()
2.CMAKE_C_FLAGS: set compiler for c language
2.CMAKE_CXX_FLAGS: set compiler for c++ language
六、区分debug和release
在工程目录下,cmake -DCMAKE__BUILD_TYPE=DEBUG(RELEASE),再执行make
七、指定编译32bit或64bit程序
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
cmake学习(三)常用指令
一、基本指令:
INCLUDE_DIRECTORIES(${includedir}) #-I。
LINK_DIRECTORIES(${libdir}) #-L
TARGET_LINK_LIBRARIES(helloworld ${linkflags}) #-l
ADD_DEFINITIONS(${cflags}) #-D
1、ADD_DEFINATIONS:向C/CPP添加宏定义,相当于gcc中的-D,参数之间用空格分割
2、ADD_DEPENDICIES(target_name, depend_name):定义target对其他target的依赖关系
3、AUX_SOURCE_DIRECTORY(dir VARIBLE):把目录下的所有源文件保存在变量中,基本用来创建源文件列表
4、ADD_EXECUTABLE:指定目录,生成执行文件
5、EXEC_PROGRAM:外部调用指令,可移执行任何外部命令,后面加参数,例子如下:
EXEC_PROGERAM(ls ARGS"*.c" OUTPUT_VARIBLE LS_OUTPUT RETURN_VALUE LS_RVALUE)
IF(not LS_RVALUE)
MESSAGE(STATUS "xxx")
ENDIF(not LS_RVAULE)
PS.这里执行ls *.c指令,执行成功的话,返回0。
6、FILE指令:
FILE(WRITE file_name "content")
FILE(APPEND file_name "content")
FILE(READ file_name varible)
FILE(WRITE file_name "content")
7、FIND_系列指令:
LIBRARY( name path):
FIND_LIBRARY(Xorg X11 /usr/lib64)
IF(not Xorg)
MESSAGE(STATUS "no Xorg")
ENDIF(not Xorg)
FILE( name path)
PATH( name path)
PROGRAM( name path)
PACKAGE( [major.minor][QUIET][NO MODULE][[REQUIRED][COMPONTS][componts....]])
最后一条,用来调用放在CMAKE_MODULE_PATH下的Find.cmake模块,也可以自定义Find模块
首先通过SET(CMAKE_MODULE_PATH /home/...)来指定位置
8、控制指令:
IF(expression),ELSE(expression),ENDIF(expression)
express举例:
否定:空,0,N,NO,OFF,FALSE,NOTFOUND或_NOTFOUND
肯定:COMMAND cmd,EXISTS dir/file,variable MARCHES regex等等等等还有很多~~~随用随查吧
cmake学习(四)模块的使用和自定义模块
FIND_PACKAGE
每一个模块都会产生如下变量
_FOUND
_INCLUDE_DIR
_LIBRARY or _LIBRARIES
如果_FOUND为真,把_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中。
编写属于自己的FindHello模块:
1.FIND_PATH(HELLO_INCLUDE_DIR hello.h /usr/include/hello /usr/local/include/hello)
2.FIND_LIBRARY(HELLO_LIBRARY_DIR NAMES hello PATH /usr/lib /usr/local/lib)
IF(HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
SET(HELLO_FOUND TRUE)
ENDIF(HELLO_INCLUDE_DIR)
3.FIND_PACKAGE([major.minor][QUIET][NO_MODULE]
[[REQUIRED|COMPONENTS][componets...]])
QUIET参数:去掉输出信息
REQUIRED参数:共享库是否是工程必须的,如果是必须的,那么找不到
如果在src中想调用hello模块中的内容
FIND_PACKAGE(HELLO)
为了可以让工程找到FindHELLO.cmake
在主工程的CMakeList.txt中,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_PATH}/cmake)
通过设置FIND_PACKAGE(HELLO QUIET)可以去掉输出信息
Cmake CMAKE_BUILD_TYPE specification
That’s because no build type has been specified to CMake. The build type is a feature most IDE have, it allows you to compile your program in “debug” mode, for easily single-stepping through it with a debugger, or in “release” mode, with speed optimization enabled.
To fix this you simply need to specify a build type in the CMakeLists.txt file, in this way:
if( NOT CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Debug CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo
MinSizeRel."
FORCE )
endif()
when cmake is run without specifying the build type using -D CMAKE_BUILD_TYPE, it is the Debug mode that is selected as the default.