我开发了一些库,主要是一些第三方包的接口。在我的库中,有一些核心例程需要编译,还有一组可选的例程,如果在代码中使用它,需要编译。
让我举一些例子说明。
@RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST, headers = ("content-type=multipart/*"), produces = "application/json", consumes = "image/*")
这是我项目的一棵树。我的图书馆只是一个标题。我需要编写Library
|---interfaces
| |---first
| | |---CMakeLists.txt
| | |---...
| |---second
| |---CMakeLists.txt
| |---...
|---core_routines
| |---CMakeLists.txt
| |---...
|---dependencies.cmake
函数,可以使用它来有效地在项目中添加所需的子模块。
目前我使用自己非常难看的解决方案。也就是说,您可以在下面看到我的cmake
文件的样子
dependencies.cmake
现在,当我在某些代码中使用我的库时,相应的#first interface dependencies
if(first)
link_directories(...)
include_directories(...)
add_subdirectory(${SOME_PATH}/interfaces/first
"${CMAKE_CURRENT_BINARY_DIR}/first")
endif()
#second interface dependencies
if(second)
...
endif()
#core routines
add_subdirectory(${SOME_PATH}/core_routines/
"${CMAKE_CURRENT_BINARY_DIR}/core_routines")
#function for adding required libs to new target
function(add_new_target new_target)
target_link_libraries(
${new_target} core_lib
)
if(first)
target_link_libraries(
${new_target} first_lib
)
endif()
if(second)
target_link_libraries(
...
)
endif()
endfunction(add_new_target)
文件看起来像
CMakeLists.txt
我使用这种方式编译示例,因为据我所知,在添加新的可执行文件之前需要指定set(first ON)
set(second ON)
include(dependencies.cmake)
add_executable(main.exe main.cpp)
add_new_target(main.exe)
和link_directories
,然后在include_directories
之后指定所需的库它。如果我错了,请纠正我。
我的问题是,在这种情况下是否有可能写出更好的东西?我需要保持我的代码的模块化结构,因为,首先,一些接口需要使用不能安装在用户PC上的库,其次,我的库的主要用途是在包含cmake文件的项目中。不同的目标,所以我需要一些功能,可以根据用户的要求指定所需的库和接口。
答案 0 :(得分:0)
i
和link_directories()
不是现代方式。它们太宽泛了。默认情况下,现代CMake中的几乎所有内容都基于include_directories()
。
每个子目录目标应该已经使用target_*
和target_include_directories()
使用" PUBLIC"或者" INTERFACE"传递依赖性,即携带成功包含和链接它们所需的东西。
如果这些图书馆是第三方并且尚未捆绑其传递依赖关系,那么您可以使用target_link_libraries()
使用" INTERFACE_INCLUDE_DIRECTORIES" AND" INTERFACE_LINK_LIBRARIES"属性。
答案 1 :(得分:0)
提供客户端程序需要链接的所有库的列表。这就像内置的FindBoost模块一样,它接收组件列表,然后为每个组件准备变量,加上BOOST_LIBRARIES,它是所有组件的列表。
set(my_component_libraries core_lib)
if(first)
list(APPEND my_component_libraries first_lib)
endif()
# etc.
set(my_component_libraries ${my_component_libraries} PARENT_SCOPE)
这样您就可以将实际链接留给用户了。
如果您将CMake接口编写为find_package
兼容,您实际上可以将COMPONENTS接口用于find_package
,就像Boost一样。