
在这个有趣的故事的前一部分中 ,我们讨论了将标头库组织为CMake装配系统生成器的一部分。
这次我们向其中添加了一个已编译的库,并且还彼此讨论了模块的布局。
和以前一样,那些迫不及待的人可以立即进入更新的存储库 ,用自己的双手触摸一切。
目录内容
- 分享到
- 征服
要实现我们的崇高目标,要做的第一件事就是将开发中的软件分为通用的,独立的模块,这些模块从用户的角度来看是统一的。
第一部分描述了这样的标准块-一个带有标头库的项目。 现在,将一个已编译的库添加到我们的项目中。
为此,我们在单独的.cpp
文件中取出myfunc
函数的实现:
diff --git a/include/mylib/myfeature.hpp b/include/mylib/myfeature.hpp index 43db388..ba62b4f 100644 --- a/include/mylib/myfeature.hpp +++ b/include/mylib/myfeature.hpp @@ -46,8 +46,5 @@ namespace mylib \~ \see mystruct */ - inline bool myfunc (mystruct) - { - return true; - } + bool myfunc (mystruct); } diff --git a/src/mylib/myfeature.cpp b/src/mylib/myfeature.cpp new file mode 100644 index 0000000..abb5004 --- /dev/null +++ b/src/mylib/myfeature.cpp @@ -0,0 +1,9 @@ +#include <mylib/myfeature.hpp> + +namespace mylib +{ + bool myfunc (mystruct) + { + return true; + } +}
然后,我们定义已编译的库( myfeature
),它将由上一步中获得的.cpp
文件组成。 新库显然需要现有的头文件,并且为了确保这一点,有可能和有必要将其与mylib
的现有目的结合起来。 而且,它们之间的链接是公共的,这意味着myfeature
目标将连接到的所有内容都将在负载中自动接收mylib
目标( 更多关于连接方式 )。
diff --git a/CMakeLists.txt b/CMakeLists.txt index 108045c..0de77b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,17 @@ target_compile_features(mylib INTERFACE cxx_std_17) add_library(Mylib::mylib ALIAS mylib) +################################################################################################### +## +## +## +################################################################################################### + +add_library(myfeature src/mylib/myfeature.cpp) +target_link_libraries(myfeature PUBLIC mylib) + +add_library(Mylib::myfeature ALIAS myfeature) +
接下来,我们将在系统上也安装新的库:
@@ -72,7 +83,7 @@ add_library(Mylib::mylib ALIAS mylib) install(DIRECTORY include/mylib DESTINATION include) -install(TARGETS mylib EXPORT MylibConfig) +install(TARGETS mylib myfeature EXPORT MylibConfig) install(EXPORT MylibConfig NAMESPACE Mylib:: DESTINATION share/Mylib/cmake) include(CMakePackageConfigHelpers)
应该注意的是,出于myfeature
和mylib
的目的,别名以Mylib::
为前缀。 当导出它们以将其安装到系统中时,两种目的都说明了相同的内容。 这样就可以与任何链接方案的目标统一工作。
之后,仍然需要使用新库来编织单元测试( myfunc
函数myfunc
标头中myfunc
,因此现在您需要链接):
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5620be4..bc1266c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable(mylib-unit-tests test_main.cpp) target_sources(mylib-unit-tests PRIVATE mylib/myfeature.cpp) target_link_libraries(mylib-unit-tests PRIVATE - Mylib::mylib + Mylib::myfeature doctest::doctest )
头文件( Mylib::mylib
)现在不需要单独连接,因为如上所述,它们与库( Mylib::myfeature
)自动连接在一起。
并添加一些细微差别以确保对覆盖范围的测量,并考虑到了新到的库:
@@ -15,11 +15,16 @@ if(MYLIB_COVERAGE AND GCOVR_EXECUTABLE) target_compile_options(mylib-unit-tests PRIVATE --coverage) target_link_libraries(mylib-unit-tests PRIVATE gcov) + target_compile_options(myfeature PRIVATE --coverage) + target_link_libraries(myfeature PRIVATE gcov) + add_custom_target(coverage COMMAND ${GCOVR_EXECUTABLE} - --root=${PROJECT_SOURCE_DIR}/include/ - --object-directory=${CMAKE_CURRENT_BINARY_DIR} + --root=${PROJECT_SOURCE_DIR}/ + --filter=${PROJECT_SOURCE_DIR}/include + --filter=${PROJECT_SOURCE_DIR}/src + --object-directory=${PROJECT_BINARY_DIR} DEPENDS check )
您可以添加更多的库,可执行文件等。 在项目框架中将它们如何精确地编织在一起并不重要。 唯一重要的是我们模块的接口(即伸出)的目标是什么。
现在我们有了标准的模块块,并且可以对其进行控制:从它们组成任何复杂的结构,将它们安装在系统中或在单个组装系统中互连它们。
系统安装
使用该模块的选项之一是在系统中安装我们的模块。
cmake --build /// --target install
之后,它使用find_package
连接到任何其他项目。
find_package(Mylib 1.0 REQUIRED)
连接作为子模块
另一种选择是使用add_subdirectory
将文件夹与我们的项目作为子模块连接到另一个项目。
使用方法
绑定方法不同,但结果相同。 在这两种情况下,在使用我们的模块的项目中,目标Mylib::myfeature
和Mylib::mylib
都是可用的,例如可以这样使用:
add_executable(some_executable some.cpp sources.cpp) target_link_libraries(some_executable PRIVATE Mylib::myfeature)
具体来说,在我们的示例中,当需要libmyfeature
库时,需要连接Mylib::myfeature
libmyfeature
库。 如果头足够,则应使用Mylib::mylib
库。
CMake目标可能很棘手,例如,仅设计为转发某些属性,依赖项等。 同时,以单一方式进行处理。
需要接收什么。