1. 项目目录结构
test2 ├── add │ ├── add.c │ ├── add.h │ └── CMakeLists.txt ├── build ├── CMakeLists.txt ├── example │ ├── CMakeLists.txt │ ├── test_add.c │ └── test_sub.c └── sub ├── CMakeLists.txt ├── sub.c └── sub.h
说明:
add
: 这个模块是加法模块,会生成动态库和静态库。
sub
:这个模块是减法模块,会生成动态库和静态库。
example
:这个模块是测试add
和sub
模块程序。
CMakeLists.txt
:这里有4个CMakeLists.txt
,顶层CMakeLists.txt
文件管理其它模块CMakeLists.txt
文件,每个模块CMakeLists.txt
文件都只需管理自己编译。
2. 相关代码
2.1 add 模块
add.h
#ifndef _ADD_H #define _ADD_H int add(const int a, const int b); #endif
add.c
#include "add.h" int add(const int a, const int b) { return a+b; }
CMakeLists.txt
# 递归获取目录下所有的C文件 file(GLOB_RECURSE c_files ./*.c) # 递归获取目录下所有的h文件 file(GLOB_RECURSE h_files ./*.h) #生成动态库和静态库 add_library(add_lib_shared SHARED ${c_files}) add_library(add_lib_static STATIC ${c_files}) #将动态库和静态库的名字设置为 add set_target_properties(add_lib_shared PROPERTIES OUTPUT_NAME "add") set_target_properties(add_lib_static PROPERTIES OUTPUT_NAME "add") #设置动态库版本 set_target_properties(add_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1) #安装动态库和静态库 INSTALL(TARGETS add_lib_shared add_lib_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) #安装头文件 INSTALL(FILES ${h_files} DESTINATION include)
2.2 sub 模块
sub.h
#ifndef _SUB_H #define _SUB_H int sub(const int a, const int b); #endif
sub.c
#include "sub.h" int sub(const int a, const int b) { return a - b; }
CMakeLists.txt
#递归获取目录下所有的C文件 file(GLOB_RECURSE c_files ./*.c) # 递归获取目录下所有的h文件 file(GLOB_RECURSE h_files ./*.h) #生成动态库和静态库 add_library(sub_lib_shared SHARED ${c_files}) add_library(sub_lib_static STATIC ${c_files}) #将动态库和静态库的名字设置为 sub set_target_properties(sub_lib_shared PROPERTIES OUTPUT_NAME "sub") set_target_properties(sub_lib_static PROPERTIES OUTPUT_NAME "sub") #设置动态库版本 set_target_properties(sub_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1) #设置动态库版本 set_target_properties(sub_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1) #安装动态库和静态库 INSTALL(TARGETS sub_lib_shared sub_lib_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) #安装头文件 INSTALL(FILES ${h_files} DESTINATION include)
2.3 测试模块
test_add.c
#include "add.h" #include <stdio.h> int main(int argc, char **argv) { int a = 10; int b = 8; printf("%d + %d = %d\n", a, b, add(a, b)); return 0; }
test_sub.c
#include "sub.h" #include <stdio.h> int main(int argc, char **argv) { int a = 10; int b = 8; printf("%d - %d = %d\n", a, b, sub(a, b)); return 0; }
CMakeLists.txt
# 添加头文件路径 include_directories(${PROJECT_SOURCE_DIR}/add) include_directories(${PROJECT_SOURCE_DIR}/sub) # 添加第三方库(add)头文件路径 link_directories(${PROJECT_SOURCE_DIR}/lib) # 生成执行文件 add_executable(test_add test_add.c) add_executable(test_sub test_sub.c) # 链接库文件 target_link_libraries(test_add add) target_link_libraries(test_sub sub) # 安装执行文件 INSTALL(TARGETS test_add test_sub RUNTIME DESTINATION bin)
2.4 顶层 CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) #设置库文件输出目录 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) #设置执行文件输出目录 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 添加子目录 add_subdirectory(add) add_subdirectory(sub) add_subdirectory(example)
说明:
顶层CMakeLists.txt
管理子目录的CMakeLists.txt
, 从而实现模块化编译和管理。
3. 编译 & 安装
$ cd build $ cmake -DCMAKE_INSTALL_PREFIX=/home/mark/code/cmake/test2/_install .. $ make $ make install $ cd .. $ tree _install
查看效果
_install/
├── bin
│ ├── test_add
│ └── test_sub
├── include
│ ├── add.h
│ └── sub.h
└── lib
├── libadd.a
├── libadd.so -> libadd.so.1 ├── libadd.so.1 -> libadd.so.1.0 ├── libadd.so.1.0 ├── libsub.a ├── libsub.so -> libsub.so.1 ├── libsub.so.1 -> libsub.so.1.0 └── libsub.so.1.0
说明:
-DCMAKE_INSTALL_PREFIX
:指定安装目录,需要是绝对路径。
4. 项目安装基本语法
4.1 安装target
语法:
INSTALL(TARGETS targets...
[[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION <dir>] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [OPTIONAL] ] [...])
targets
: 一般填执行文件、动态库、静态库。
ARCHIVE
: 特指静态库。
LIBRARY
: 特指动态库。
RUNTIME
: 特指执行文件。
dir
: 安装路径,一般配合CMAKE_INSTALL_PREFIX
使用,即表示为${CMAKE_INSTALL_PREFIX}/dir
。若是dir
以/
开头,表示绝对路径,即不使用CMAKE_INSTALL_PREFIX
变量。
一个例子:
#安装动态库和静态库 INSTALL(TARGETS sub_lib_shared sub_lib_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) # 安装执行文件 INSTALL(TARGETS test_add test_sub RUNTIME DESTINATION bin)
4.2 安装普通文件
语法
INSTALL(FILES files... DESTINATION <dir>
[PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [RENAME <name>] [OPTIONAL])
使用方法和上述方法类似,举个简单的例子,就大概知道怎么用了。
一个例子
#安装头文件 INSTALL(FILES ${h_files} DESTINATION include)
4.3 安装目录和脚本
语法
INSTALL(DIRECTORY dirs... DESTINATION <dir>
[FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [USE_SOURCE_PERMISSIONS] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [[PATTERN <pattern> | REGEX <regex>] [EXCLUDE] [PERMISSIONS permissions...]] [...])
说明
dirs
:DIRECTORY 后面连接的路径是所在Source目录的相对路径; 但务必注意: abc
和 abc/
有很大的区别: 如果目录名不以/
结尾,那么这个目录将被安装为目标路径下的abc
,如果目录名以/
结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
pattern
: 使用正则表达式进行过滤.
permissions
: 用于指定pattern
过滤后的文件权限。
举例说明
INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj PATTERN "CVS" EXCLUDE PATTERN "scripts/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)
这条指令的执行结果是:将icons
目录安装到 <prefix>/share/myproj
,
将scripts/
中的内容安装到<prefix>/share/myproj
不包含目录名为CVS
的目录,对于scripts/*
文件指定权限为OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ
。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/119544.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...