假设有以下目录结构:
projects
|
+--lib1
| |
| +-CMakeFiles.txt
|
+--lib2
| |
| +-CMakeFiles.txt
|
+--test
|
+-CMakeFiles.txt
Run Code Online (Sandbox Code Playgroud)
LIB1/CMakeFiles.txt:
cmake_minimum_required(VERSION 2.0)
add_library(lib1 STATIC lib1.cpp)
Run Code Online (Sandbox Code Playgroud)
LIB2/CMakeFiles.txt:
cmake_minimum_required(VERSION 2.0)
add_subdirectory(../lib1 ${CMAKE_CURRENT_BINARY_DIR}/lib1)
add_library(lib2 STATIC lib2.cpp)
target_link_libraries(lib2 lib1)
Run Code Online (Sandbox Code Playgroud)
测试/ CMakeFiles.txt:
cmake_minimum_required(VERSION 2.0)
project(test)
add_subdirectory(../lib1 ${CMAKE_CURRENT_BINARY_DIR}/lib1)
add_subdirectory(../lib2 ${CMAKE_CURRENT_BINARY_DIR}/lib2)
add_executable(test main.cpp)
target_link_libraries(test lib1 lib2)
Run Code Online (Sandbox Code Playgroud)
即lib2
依赖于lib1
并test
依赖于它们.(我知道技术上静态的库不会"链接",但这只是一个例子).
问题是,使用当前设置,lib1编译两次 - 第一次在"test"构建目录中,第二次在"test/build_directory/lib2/build_directory"中.我想避免这种情况.
我希望能够将lib1,lib2或它们两者(使用add_subdirectory)的依赖性添加到位于其他位置的任何项目.所以移动CMakeFiles不是一个选择.我也想避免多次编译任何库.
我怎样才能做到这一点?
cmake-2.8.4 winxp sp3
--EDIT--顶级cmakelists不是一个选项,因为我想保持干净的顶级目录,并能够将库包含在可以位于其他地方的其他项目中.因为它是windows,我无法"在系统范围内安装软件包" - 我不想失去动态切换编译器的能力.使用不同编译器构建的实用程序库将使用不同的C运行时库/ ABI,因此将不兼容.
use*_*450 13
另一种解决方案是在子目录CMakeLists.txt的顶部添加一个防护:
if(TARGET targetname)
return()
endif(TARGET targetname)
Run Code Online (Sandbox Code Playgroud)
这将导致cmake在第二次添加子目录时不执行任何操作(当然,如果在该文件中定义了targetname).
这将导致lib beeing构建在构建/树中的任意位置(取决于首先添加它的模块),但它将只构建一次并在任何地方链接.
在您的示例中,您将添加
if(TARGET lib1)
return()
endif(TARGET lib1)
Run Code Online (Sandbox Code Playgroud)
在lib1/CMakeFiles.txt的顶部
使用CMake,库依赖关系是可传递的,因此您不应调用add_subdirectory
两次test/CMakeFiles.txt
(也不必将其lib1
列为依赖项,test
因为它已经是的依赖项lib2
)。
因此,您可以将test
CMakeFiles.txt 修改为:
cmake_minimum_required(VERSION 2.8.7) # Prefer the most current version possible
project(test)
add_subdirectory(../lib2 ${CMAKE_CURRENT_BINARY_DIR}/lib2)
add_executable(test main.cpp)
target_link_libraries(test lib2)
Run Code Online (Sandbox Code Playgroud)
另外,您可能应该cmake_minimum_required
从非项目CMakeFiles.txt文件(lib文件)中删除调用。有关更多信息,请运行:
cmake --help-policy CMP0000
Run Code Online (Sandbox Code Playgroud)
如果添加依赖于lib1
和的类似test2子目录和项目,此设置仍将导致所有库重新编译lib2
。如果您确实不想在中拥有顶级CMakeFiles.txt projects/
,那么您就束手无策了,或者可以使用export
or install
命令。
export
会创建一个文件,该文件可以include
由其他项目进行打包,并将目标导入到调用该项目的项目中include
。
install
可以将库安装到的另一个公共子目录中projects/
。根据您的源目录结构,这样做的好处是仅使预期的库API标头可用于相关项目。
但是,这两个选项都需要在修改后重建(并安装)依赖库项目,而您当前的设置包括项目中的所有依赖目标,因此对依赖库中源文件的任何更改都将导致您test
目标要过时。
有关进一步的细节export
和install
运行:
cmake --help-command export
cmake --help-command install
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4540 次 |
最近记录: |