一、静态库与动态库构建
本节建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc向终端输出Hello World字符串。安装头文件和共享库。
1、准备工作
在/backup/cmake中建立t3,用于存放本节涉及到的工程。
2、建立共享库
指令:
cd /backup/cmake/t3
mkdir lib
在t3目录下建立CMakeLists.txt,内容如下:
在lib目录下建立两个两个源文件hello.c和hello.h,
在lib的目录下建立CMakeLists.txt,内容如下:
3、编译共享库
在build目录下:
cmake ..
make
编译成功后,在build文件下的lib文件下可以发现存在一个libhello.so的动态链接库。
ADD_LIBRARY(libname [SHARED|STATIC|MODULE][EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
不需要在全libhello.so,只需要填写hello即可,cmake系统会自动为你生成libhello.X
类型有三种:
SHARED
,动态库
STATIC
,静态库
MODULE
,在使用dyld的系统有效,如果不支持dyld,则被当做SHARED对待。
EXCLUDE_FROM_ALL
参数的意思是这个不会被默认构建,除非有其他的组件依赖或者手工构建。
4、 添加静态库
在以上的基础上再添加一个静态库,按照一般的习惯,则这个静态库的名字的后缀为.a。
我们往lib/CMakeLists.txt中添加一条:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
这样就可以同时得到libhello.so/libhello.a两个库了。
PS:为什么不使用
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
因为使用了这个语句,hello作为target是不能重名的。所以会造成静态库的构建指令无效。
SET_TARGET_PROPERTIES(target1 target2 ...PROPERTIES prop1 value1 prop2 value2 ...)
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库的版本和API版本。
与他对应的指令是:
GET_TARGET_PROPERTY(VAR target property)
举例:向lib/CMakeLists.txt中添加:
GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
MESSAGE(STATUS "This is the hello_static OUTPUT_NAME:"${OUTPUT_VALUE})
如果没有这个属性则会返回NOTFOUND.而使用以上的例子会出现一个问题,那就是会发现libhello.a存在,但是libhello.so会消失,因为cmake在构建一个新的target时,会尝试清理掉其他使用这个名字的库。解决方案如下:
向lib/CMakeLists.txt中添加
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_PUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
这个时候再进行构建,会发现build/lib目录中同时生成了libhello.so和libhello.a。
5、增加动态库的版本号
SET_TARGET_PROPERTIES(hello PROPERTIES VERION 1.2 SOVERSION 1)
VERSION指代动态库版本,SOVERSION指代API版本。
6、安装共享库和头文件
以上面的例子,将libhello.a、libhello.so以及hello.h安装到系统目录,才能真正让其他人开发使用。例如将共享库安装到/lib目录,将hello.h安装到/include/hello目录。
在lib/CMakeLists.txt中添加指令:
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)
编译指令:
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
make install
这样就可以将头文件和共享库安装到系统目录/usr/lib和/usr/include/hello中了。
7、小结
ADD_LIBRARY
指令构建动态库和静态库
SET_TARGET_PROPERTIES
同时构建同名的静态库和动态库。
SET_TARGET_PROPERTIES
控制动态版本库
INSTALL
安装头文件和动态库和静态库。