NOTE: 因为 CSDN 上没有 CMake 的语法高亮,所以拿 lua 的替代了,还算看得过去。
关键词:CMake
CMake install
CMake export
废话不多说,先上成品!
给 VSCode 用的 Snippet ????
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67{ "CMake install configure": { "prefix": "cmake-install", "body": [ "# --- BEGIN CMAKE INSTALL/EXPORT ---", "include(GNUInstallDirs)", "set(PROJECT_EXPORT_TARGETS ${1:\${PROJECT_NAME\}})", "set(PROJECT_EXPORT_NAME ${2:\${PROJECT_NAME\}})", "set(PROJECT_INSTALL_CMAKEDIR ${3:\${CMAKE_INSTALL_LIBDIR\}/cmake/\${PROJECT_EXPORT_NAME\}})", "", "# create aliases for targets", "foreach(target \${PROJECT_EXPORT_TARGETS\})", "tadd_library(\${PROJECT_EXPORT_NAME\}::\${target\} ALIAS \${target\})", "endforeach()", "# install targets", "install(", "tTARGETS \${PROJECT_EXPORT_TARGETS\}", "tEXPORT \${PROJECT_EXPORT_NAME\}Targets", "tARCHIVE DESTINATION \${CMAKE_INSTALL_LIBDIR\}", "tLIBRARY DESTINATION \${CMAKE_INSTALL_LIBDIR\}", "tRUNTIME DESTINATION \${CMAKE_INSTALL_BINDIR\}", "tPUBLIC_HEADER DESTINATION \${CMAKE_INSTALL_INCLUDEDIR\}", "tINCLUDES DESTINATION \${CMAKE_INSTALL_INCLUDEDIR\}", ")", "", "# install project headers", "install(", "tDIRECTORY \${CMAKE_CURRENT_SOURCE_DIR\}/include/", "tDESTINATION \${CMAKE_INSTALL_INCLUDEDIR\}", ")", "", "# install CMake xxxTargets.cmake", "export(", "tEXPORT \${PROJECT_EXPORT_NAME\}Targets", "tNAMESPACE \${PROJECT_EXPORT_NAME\}::", "tFILE \${PROJECT_EXPORT_NAME\}Targets.cmake", ")", "install(", "tFILES \${CMAKE_CURRENT_BINARY_DIR\}/\${PROJECT_EXPORT_NAME\}Targets.cmake", "tDESTINATION \${PROJECT_INSTALL_CMAKEDIR\}", ")", "", "# install xxxConfigVersion.cmake", "include(CMakePackageConfigHelpers)", "write_basic_package_version_file(", "t\${PROJECT_EXPORT_NAME\}ConfigVersion.cmake", "tVERSION \${PROJECT_VERSION\}", "tCOMPATIBILITY AnyNewerVersion", ")", "install(", "tFILES \${CMAKE_CURRENT_BINARY_DIR\}/\${PROJECT_EXPORT_NAME\}ConfigVersion.cmake", "tDESTINATION \${PROJECT_INSTALL_CMAKEDIR\}", ")", "", "# install CMake xxxConfig.cmake", "install(", "tEXPORT \${PROJECT_EXPORT_NAME\}Targets", "tFILE \${PROJECT_EXPORT_NAME\}Config.cmake", "tNAMESPACE \${PROJECT_EXPORT_NAME\}::", "tDESTINATION \${PROJECT_INSTALL_CMAKEDIR\}", ")", "# --- END CMAKE INSTALL/EXPORT ---" ], "description": "CMake 导出目标" } }
简单讲讲
第一部分
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14#! 常用的模块了,设置 GNU 风格的 install 目录,变量命名为 CMAKE_INSTALL_xxxDIR include(GNUInstallDirs) #! 设置需要导出的目标(列表) set(PROJECT_EXPORT_TARGETS ${PROJECT_NAME}) #! 设置导出的命名,在这份 snippet 中应用于 xxxConfig.cmake/xxxTargets.cmake/ #! xxxConfigVersion.cmake 和导出的目标的命名空间 set(PROJECT_EXPORT_NAME ${PROJECT_NAME}) #! 设置生成的 cmake 文件的 install 目录,通常会放在顶层目录为 share 或 lib/lib64 的 #! 目录下,在这里选择放在 lib/lib64 目录下 set(PROJECT_INSTALL_CMAKEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_EXPORT_NAME})
第二部分
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#! 在同一个 CMake build tree 中,每个项目的 targets 对外都是可见的,比如 A 项目中有一个 #! foobar 的静态库目标,那么在 B 项目中就可以直接链接 foobar 目标。 #! 但是一般情况在 CMake 使用第三方库引入库都会有命名空间(命名冲突问题),这时链接的目标可 #! 能就是 foobar::foobar !(如果不是的话假设就是!!!) #! 出于统一性考虑,应尽可能使得同一 build tree 内外链接同名目标。 #! 然而 build tree 内即使进行了 install/export 操作,依旧不能直接使用带有命名空间的目标 #! (可能以某种参数进行的 install/export 可以做到,但是我写的时候实在是在这上面找不到办法) #! 故而曲线救国,在这里额外对导出的目标定义带命名空间的别名,完美! #! NOTE: 不会吧不会吧?不会有人连这种别名都能造成命名冲突吧? #! NOTE: 我自认为因为别名没在这里被导出,所以不会影响外部 CMake 项目的引入,或许只不过是我 #> 多虑了,其实根本就不存在这种问题呢?不过说到底我对此机理并未深究,故留个疑问在这。 foreach(target ${PROJECT_EXPORT_TARGETS}) add_library(${PROJECT_EXPORT_NAME}::${target} ALIAS ${target}) endforeach()
第三部分
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13#! 重头之一:配置待导出目标们的 install 选项,主要包括相关文件的 install 目录, #! 其中 EXPORT 参数指示了被导出目标集合的导出名,该项将在 export 中被使用以代替显 #! 式地列出目标。另 install( TARGETS ${PROJECT_EXPORT_TARGETS} EXPORT ${PROJECT_EXPORT_NAME}Targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
第四部分
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#! 导出头文件 #! 实际上该命令单纯地用于 install 目录(当路径后跟着 "/" 时表示仅导入目录下的文件与子目录) #! 但是由于我个人的习惯,即项目结构一般服从如下: #! Project #! | CMakeLists.txt #! +---include #! | ---ProjectInc #! | [Public Headers] #! ---src #! *.cpp #! [Private Headers] #! CMakeLists.txt #! 所以就方便如下这样直接导出公共头文件了!另外在这份 snippet 中还有几个地方也需要前置要求 #! 如上的目录结构,如果要直接挪用的话可能需要注意一下! install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
第五部分
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#! 重头之二:生成用于导入被导出目标的 xxxTargets.cmake 文件 #! export 支持 export(TARGETS) 命令和 export(EXPORT) 命令,在第三部分中提过,install #! 中指定了待导入目标们的导出名,在此处则直接使用导出名指代被导出的目标。这与代换后的 #! export(TARGETS) 命令是等价的。 export( EXPORT ${PROJECT_EXPORT_NAME}Targets NAMESPACE ${PROJECT_EXPORT_NAME}:: FILE ${PROJECT_EXPORT_NAME}Targets.cmake ) #! export 执行生成的 xxxTargets.cmake 存在于 ${CMAKE_CURRENT_BINARY_DIR} 目录下(也就 #! 是 CMake 构造目录下的与源代码同名子目录),故而需要额外导入该文件。 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_EXPORT_NAME}Targets.cmake DESTINATION ${PROJECT_INSTALL_CMAKEDIR} )
第六部分
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#! 生成 xxxConfig.cmake 的版本配置脚本 xxxConfigVersion.cmake #! NOTE: 不是特别重要,可以跳过~ include(CMakePackageConfigHelpers) write_basic_package_version_file( ${PROJECT_EXPORT_NAME}ConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) #! 原因同第五部分,需要手动导入! install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_EXPORT_NAME}ConfigVersion.cmake DESTINATION ${PROJECT_INSTALL_CMAKEDIR} )
第七部分
复制代码
1
2
3
4
5
6
7
8
9#! 重头之三:生成库的配置文件 xxxConfig.cmake xxxConfig-<config>.cmake #! 其中 EXPORT 是一个已经被指派的导出名,剩下的部分敢敢当当,一目了然! install( EXPORT ${PROJECT_EXPORT_NAME}Targets FILE ${PROJECT_EXPORT_NAME}Config.cmake NAMESPACE ${PROJECT_EXPORT_NAME}:: DESTINATION ${PROJECT_INSTALL_CMAKEDIR} )
最后
以上就是无奈蛋挞最近收集整理的关于CMake 使用 install 与 export 导出库废话不多说,先上成品!简单讲讲的全部内容,更多相关CMake内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复