使用 CMake 创建 C++ 库
Creating C++ library with CMake
我正在尝试创建一个合理的库结构和 CMake 文件,以允许其他 CMake 项目轻松包含此库。我发现了很多类似的问题,但是,其中 none 似乎解决了我的确切问题。
我当前的结构如下:
/*MyLibrary/
├── CMakeLists.txt (including lib subdirectories)
├── external/
│ └── googletest/
├── lib/
│ ├── common/
│ │ ├── CMakeList.txt (creates static lib common)
│ │ ├── include/common/*.h
│ │ └── src/*.cpp
│ ├── cipher/
│ │ ├── CMakeList.txt (creates static lib cipher)
│ │ ├── include/cipher/*.h
│ │ └── src/*.cpp
└── test/
├── main.cpp (code for executing google test)
├── CMakeLists.txt (creates unittest executable)
├── common/*Test.cpp
└── cipher/*Test.cpp
*/
现在我想创建一个具有类似目录结构的项目,但是当我想在该项目中创建一个与 MyLibrary
中的静态库同名的静态库时出现问题(common
例如)。
我曾考虑在项目 CMakeLists 中使用 add_subdirectory(external/MyLibrary)
将库包含到项目中,但由于静态库的名称冲突而失败了。
即使我通过重命名库解决了这个问题(事实上我不认为这是一个优雅的解决方案),我最终还是遇到了 googletest 冲突,因为库和我的项目都依赖于 googletest。
有什么方法可以轻松解决这个问题吗?我在想两种可能性:
在 MyLibrary
中,我将从所有名为 libMyLibrary.a
的子库中创建一个静态库,并仅包含该库(首选选项,但我没有如何在 CMake 中实现它的线索)
强制库的用户安装它并且不将库作为项目子模块包括在内(我会选择的最后一个选项)
有没有其他合理的方法来解决这个问题,使我的库与大多数 CMake 项目兼容?如果没有,我怎样才能至少实现上述选项之一?
简而言之:我如何为一个库创建一个 CMake 文件,以便该库很容易包含在其他 CMake 项目中?
如何处理 googletest 等冗余依赖项?
How can I create a CMake file for a library so the library is easy to include in other CMake projects?
为此没有通用的方法。
通过 add_subdirectory()
将您的项目包含到另一个项目中,您可以 "open" 将项目的内部结构包含到另一个项目中。除了让库的目标准备好链接的优点之外,这种方法也有缺点。目标的冲突,缓存变量的冲突会让你头疼,还有一些其他问题。
如果您希望您的项目包含在 add_subdirectory
的其他项目中,请避免为您的目标使用 "generic" 名称。例如,使用 <my_project_name>_common
而不是 common
。
有些目标你不能重命名(比如gtest
)。如果您的项目实际上不需要这些目标,请创建一个选项来禁用它们:
option(<my_project_name>_TESTING "Enable testing" ON)
if(<my_project_name>_TESTING)
add_subdirectory(external/googletest)
endif()
另请参阅 有关目标名称冲突的类似问题。
我正在尝试创建一个合理的库结构和 CMake 文件,以允许其他 CMake 项目轻松包含此库。我发现了很多类似的问题,但是,其中 none 似乎解决了我的确切问题。
我当前的结构如下:
/*MyLibrary/
├── CMakeLists.txt (including lib subdirectories)
├── external/
│ └── googletest/
├── lib/
│ ├── common/
│ │ ├── CMakeList.txt (creates static lib common)
│ │ ├── include/common/*.h
│ │ └── src/*.cpp
│ ├── cipher/
│ │ ├── CMakeList.txt (creates static lib cipher)
│ │ ├── include/cipher/*.h
│ │ └── src/*.cpp
└── test/
├── main.cpp (code for executing google test)
├── CMakeLists.txt (creates unittest executable)
├── common/*Test.cpp
└── cipher/*Test.cpp
*/
现在我想创建一个具有类似目录结构的项目,但是当我想在该项目中创建一个与 MyLibrary
中的静态库同名的静态库时出现问题(common
例如)。
我曾考虑在项目 CMakeLists 中使用 add_subdirectory(external/MyLibrary)
将库包含到项目中,但由于静态库的名称冲突而失败了。
即使我通过重命名库解决了这个问题(事实上我不认为这是一个优雅的解决方案),我最终还是遇到了 googletest 冲突,因为库和我的项目都依赖于 googletest。
有什么方法可以轻松解决这个问题吗?我在想两种可能性:
在
MyLibrary
中,我将从所有名为libMyLibrary.a
的子库中创建一个静态库,并仅包含该库(首选选项,但我没有如何在 CMake 中实现它的线索)强制库的用户安装它并且不将库作为项目子模块包括在内(我会选择的最后一个选项)
有没有其他合理的方法来解决这个问题,使我的库与大多数 CMake 项目兼容?如果没有,我怎样才能至少实现上述选项之一?
简而言之:我如何为一个库创建一个 CMake 文件,以便该库很容易包含在其他 CMake 项目中?
如何处理 googletest 等冗余依赖项?
How can I create a CMake file for a library so the library is easy to include in other CMake projects?
为此没有通用的方法。
通过 add_subdirectory()
将您的项目包含到另一个项目中,您可以 "open" 将项目的内部结构包含到另一个项目中。除了让库的目标准备好链接的优点之外,这种方法也有缺点。目标的冲突,缓存变量的冲突会让你头疼,还有一些其他问题。
如果您希望您的项目包含在 add_subdirectory
的其他项目中,请避免为您的目标使用 "generic" 名称。例如,使用 <my_project_name>_common
而不是 common
。
有些目标你不能重命名(比如gtest
)。如果您的项目实际上不需要这些目标,请创建一个选项来禁用它们:
option(<my_project_name>_TESTING "Enable testing" ON)
if(<my_project_name>_TESTING)
add_subdirectory(external/googletest)
endif()
另请参阅