linux/mac环境下CMake编译简记

目录

1.CMakeLists.txt 以及编译动态链接库

2.同时生成动态库与静态库 

3.工程集成动态连接库

4.工程集成静态连接库

5.分目录编译


1.CMakeLists.txt 以及编译动态链接库

CMakeLists.txt  是 跨平台编译工具cmake 用于生成工程编译文件makefile的命令文件,有了makefile就可以使用make命令构建程序

以测试工程为例,当前目录环境如下:


这里的cmake/mat/CMakeLists.txt就是用于生成libmat.so 或libmat.a的命令文件

CMakeLists.txt内容:这里用于生成动态链接库

使用CMake 与 CMakeLists.txt生成makefile:

在build文件夹下执行: make .. 后输出如下:

       现在生成了makefile文件,可以直接执行make 启动编译了:

编译后的结果在cmake/mat/build 下,这里是一个动态链接库:libmat.dylib 等同于linux系统下的libmat.so


2.同时生成动态库与静态库 

修改CMakeLists.txt如下:

# 编译mat库
cmake_minimum_required(VERSION 3.4.1)

set(target_name mat)
project(${target_name})

set(SDK_DIR "/Users/sssrank/AndroidStudioProjects/baidu/vscodespace/codespace/project")
set(SDK_SRC_DIR "src/mat")

set(ABS_SRC_DIR ${SDK_DIR}/${SDK_SRC_DIR})

set(SDK_INC
    ${ABS_SRC_DIR}
)

set(SDK_SRC
    ${ABS_SRC_DIR}/mat.cpp
)
# 生成动态库
add_library(${target_name} SHARED ${SDK_SRC})
# 生成静态库
add_library(${target_name}_static STATIC ${SDK_SRC})

# target_include_directories(${target_name} PRIVATE_HEADER ${SDK_INC})
include_directories(${SDK_INC})

target_link_libraries(${target_name})

# 静态库文件重命名
set_target_properties(${target_name}_static PROPERTIES OUTPUT_NAME ${target_name})
target_link_libraries(${target_name}_static)

这里添加了add_library,属性是STATIC,表示引入静态库; 注意要生成的静态库在makefile中不能重名,这里加了_static后缀,并且在输出时,通过set_target_properties修改静态库的输出名为${target_name},以保持与动态库一致

输出文件:

这里动态库、静态库大小差异不是很明显,但如果工程文件较多,或者依赖第三方库的话,二者差别较大


3.工程集成动态连接库

先写main.cpp,其中调用libmat.so库中的方法

目录结构:

make/main/CMakeLists.txt内容:

# 编译mat库
cmake_minimum_required(VERSION 3.4.1)

set(target_name main)
project(${target_name})

set(SDK_DIR "/Users/sssrank/AndroidStudioProjects/gnss/vscodespace/codespace/project")
set(SDK_SRC_DIR "src")

set(ABS_SRC_DIR ${SDK_DIR}/${SDK_SRC_DIR})

set(SDK_INC
    ${ABS_SRC_DIR}
)

set(SDK_SRC
    ${ABS_SRC_DIR}/main.cpp
)

include_directories(${SDK_INC})

# 加载动态链接库
set(LIB_MAT mat)
add_library(${LIB_MAT} SHARED IMPORTED)

set_target_properties(${LIB_MAT} PROPERTIES IMPORTED_LOCATION ${SDK_DIR}/cmake/mat/build/libmat.dylib)

# 输出目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 编译可执行文件
add_executable(${target_name} ${SDK_SRC})

target_link_libraries(${target_name} 
    ${LIB_MAT}
)

其中动态加载libmat.dylib库文件,最后使用add_executable编译出可执行文件, target_link_libraries链接libmat.so

输出:

执行:这里打印一个3x3矩阵

注意:这里也可以使用link_directories,如下,相当于 g++中的 -L${SDK_DIR}/cmake/mat/build,增加动态库的搜索目录,如下:

link_directories(${SDK_DIR}/cmake/mat/build)


4.工程集成静态连接库

在第三方库的引入位置直接使用libmat.a静态库的地址即可:

# 编译mat库
cmake_minimum_required(VERSION 3.4.1)

set(target_name main)
project(${target_name})

set(SDK_DIR "/Users/sssrank/AndroidStudioProjects/baidu/vscodespace/codespace/project")
set(SDK_SRC_DIR "src")

set(ABS_SRC_DIR ${SDK_DIR}/${SDK_SRC_DIR})

set(SDK_INC
    ${ABS_SRC_DIR}
)

set(SDK_SRC
    ${ABS_SRC_DIR}/main.cpp
)

include_directories(${SDK_INC})

# 加载动态链接库
set(LIB_MAT mat)
add_library(${LIB_MAT} STATIC IMPORTED)

set_target_properties(${LIB_MAT} PROPERTIES IMPORTED_LOCATION ${SDK_DIR}/cmake/mat/build/libmat.a)

# 输出目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 编译可执行文件
add_executable(${target_name} ${SDK_SRC})

target_link_libraries(${target_name} 
    ${LIB_MAT}
)

这里引用动态库也可以使用find_libraries指令

编译结果:

可以看到集成静态库的可执行程序的大小要比使用动态库的main程序大很多


5.分目录编译

cmake下的目录结构:

编译由cmake/CMakeLists.txt控制,其内容如下:

执行时会分别执行子目录下的CMakeLists.txt:

这里修改 cmake/main/CMakeLists.txt引入库的方式: 去掉了红框中的内容,执行编译时会去搜索libmat.dylib


6.其他问题

6.1SDK编译 链接参数--whole-archive

介绍两个ld指令:

--whole-archive :把之后包含的静态库中的函数、变量等符号也输出到动态库中

--no-whole-archive :停止输出

这俩参数一般是在我们打包SDK时, 例如要发布的库:libsdk.so,其中包含了其他的静态库libinternal1.a libinternal2.a,想一同打包发布,供用户调用:

 gcc  -shared -o libsdk.so -L.  -Wl,--whole-archive libinternal1.a libinternal2.a  -Wl,--no-whole-archive

6.2开源库编译参数

在一个sdk工程中,打包成动态链接库时 想集成所使用的第三方静态库,遇到报错:

提示需要 使用-fPIC重新编译sqlite3

在sqlite编译 configure时增加-D宏定义:

$$CFLAGS="-DSQLITE_ENABLE_COLUMN_METADATA  -fPIC" ./configure

不同平台下或者gcc,生成的makefile不会添加-fpic地址无关的选项, 最好自己编译时手动加上这一项


本文只记录了常用配置, CMake中还有很多其他关键字,需要时可以查阅文档:

https://cmake.org/cmake/help/v3.4/manual/cmake-buildsystem.7.html#normal-libraries

发布了10 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/orgst/article/details/105447736