Project-level namespaces
使用第三方庫時,與程式鍊結的庫目標名稱必須是唯一的,但不同的第三方庫可能會使用相同的庫目標名稱,這有可能會導致衝突,因此引入命名空間可以解決這個目標名稱唯一性問題。
在[Day25] 使用第三方庫--以Glog為例中,我們使用了 Glog 自定義命名空間中的函式庫,因此接下來的範例會示範如何將庫加上命名空間。
install(TARGETS <target>...
[EXPORT <export-name>]
[<artifact-kind> <artifact-option>...]...
[INCLUDES DESTINATION [<dir> ...]]
)
<target>: target名稱
<export-name>: 要匯出的<export-name>.cmake檔案名稱,通常是${PROJECT_NAME}Targets,代表將會匯出名為${PROJECT_NAME}Targets.cmake的檔案,並安裝
<artifact-kind>:檔案種類
<dir>: 包含的目錄
install(EXPORT <export-name>
DESTINATION <dir>
[NAMESPACE <namespace>]
[FILE <name>.cmake])
<export-name> :產生<export-name>.cmake的檔案名稱
FILE:上一步驟產生的${PROJECT_NAME}Targets.cmake檔案名稱
<dir>:安裝位置
<namespace>:命名空間名稱
1. 編輯 MathFunctions / CMakeLists.txt
將庫的屬性中添加命名空間,並產生以下兩種檔案,讓find_package知道此專案庫的屬性。
install(
TARGETS mysqrt
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# 將mysqrt匯出成${PROJECT_NAME}Targets,並安裝
# 動態庫文件(LIBRARY)到 /usr/local/bin
# 靜態庫文件(ARCHIVE)到 /usr/local/lib
# 可執行文件(RUNTIME)到 /usr/local/lib
# 頭文件(INCLUDES)到 /usr/local/include
install(
EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION lib/cmake/${PROJECT_NAME}
)
# 匯出成的${PROJECT_NAME}Targets
# 生成 ${PROJECT_NAME}Targets.cmake 文件
# 設定 ${PROJECT_NAME}Targets.cmake 文件中的命名空間為 ${PROJECT_NAME}::
# 將 ${PROJECT_NAME}Targets.cmake 安裝到 /usr/local/lib/cmake/${PROJECT_NAME}
2. 編譯並安裝
$ cd build
$ make
$ make install
kai@esoc:~/2023_iT_CMake/Day26/MathFunctions/build$ sudo make install
Consolidate compiler generated dependencies of target mysqrt
[100%] Built target mysqrt
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/include/mysqrt.h
-- Installing: /usr/local/lib/libmysqrt.so.1.5.0
-- Installing: /usr/local/lib/libmysqrt.so.1
-- Installing: /usr/local/lib/libmysqrt.so
-- Installing: /usr/local/lib/cmake/MathFunctions/MathFunctionsTargets.cmake
-- Installing: /usr/local/lib/cmake/MathFunctions/MathFunctionsTargets-noconfig.cmake <----⭐
-- Installing: /usr/local/lib/cmake/MathFunctions/MathFunctionsConfig.cmake <----剛剛生成的${PROJECT_NAME}Targets.cmake⭐
-- Installing: /usr/local/lib/cmake/MathFunctions/MathFunctionsConfigVersion.cmake
3. 編輯 Main / CMakeLists.txt
將在MathFunctions這個命名空間中的庫鍊結到執行檔main
add_executable(main src/main.cpp)
# 將main.cpp編譯成可執行文件main
target_link_directories(main PUBLIC ${MathFunctions_LIBRARY_DIRS})
# 將MathFunctions_LIBRARY_DIRS加入main的連結路徑
target_link_libraries(main PUBLIC MathFunctions::${MathFunctions_LIBS})
# 將在MathFunctions這個命名空間中的庫鍊結到執行檔main
4. 進入 Main / build 編譯主程式並執行
$ cd Main/build
$ cmake ..
$ make
$ ./main 10