2012-03-12 64 views
11

我刚开始玩CMake。在需要的时候用于多个库和可执行文件的CMakeLists.txt文件

  • 打造每lib和EXE独立:我有类似:

    /DEV 
    |-- lib1 
         | CMakeLists.txt 
    
    |-- lib2 
         | CMakeLists.txt 
    
    |-- exe1 
         | CMakeLists.txt 
    
    /BUILD 
    |-- lib1 
    |-- lib2 
    |-- exe1 
    
    /INSTALL 
    |-- include 
    |-- lib 
    |-- bin 
    

    我想。 (所以我想我必须为每个lib和exe添加一个CMakeLists.txt文件);

  • 建立时,include和lib目录应该引用INSTALL目录; (这是一个好主意吗?)
  • 在构建时,向其他库中添加依赖关系,并重建它们(如果不是最新的)。

我没有任何线索从哪里开始。必要时请独立帮忙...

+0

除了arrowdodgers优秀的答案:建立一个单独的库,exe独立也可以通过cd'进入该lib的生成构建目录并调用make/msbuild来完成。例如。用visual studio,cmake会为每个lib/exe生成一个解决方案文件,如果lib/exe有自己的CMakeLists.txt和project()命令 – 2012-03-13 07:00:19

回答

11

您不需要单独的CMakeLists.txt来独立构建目标。假设你有一个顶级的CMakeLists.txt有:

ADD_LIBRARY(lib1 ${all_lib1_files}) 
ADD_LIBRARY(lib2 ${all_lib2_files}) 
ADD_EXECUTABLE(exe1 ${all_exe1_files}) 
TARGET_LINK_LIBRARIES(lib2 lib1) # lib2 now depends on lib1 
TARGET_LINK_LIBRARIES(exe1 lib2) # exe1 now depends on lib2 and lib1 

然后你就可以通过运行make lib1msbuild lib1.vcxproj等只构建LIB1您可以通过在每个目标个体的CMakeLists.txt文件达到同样的 - 它是由你如果认为这是值得的。

如果你的项目中使用FIND_LIBRARYFIND_PACKAGE,那么他们不会重建,如果他们不是最新的进口这些目标。最终,如果您想自动重建过时的依赖关系,您需要让CMake知道从属目标的来源和规则,即CMakeLists.txt文件需要使用ADD_LIBRARYADD_EXECUTABLE添加目标。

你不应该再引用INSTALL目录(我想象的INSTALL命令除外),因为CMake会在链接目标时隐式使用libs/exes构建位置而不是安装位置。

+0

似乎是一个更好的解决方案,我必须把CMakeLists.txt文件放在顶层,还是可以将这样的文件放在每个可执行文件夹中?或者是否有一些“递归魔术”应该考虑在内?谢谢! – Korchkidu 2012-03-13 09:39:06

+2

在你的项目的根目录下有主CMakeLists.txt是正常的,如果你愿意,你可以在每个exe文件夹中添加CMakeLists.txt文件,然后只是'INCLUDE'每个'INCLUDE'内联运行命令,所以不需要这些从属CMakeLists.txt文件完全独立(即它们不需要'PROJECT'命令等),它们只是实现不同的分离的一种方式项目的一部分并保持顶层文件更清洁。每个可能只有'SET(all_exe1_files ...)','ADD_EXECUTABLE(exe1 $ {all_exe1_files})'和'SET_TARGET_PROPERTIES(exe1 ...)'。 – Fraser 2012-03-13 10:04:36

+0

非常好!非常感谢! – Korchkidu 2012-03-13 12:43:47

3

打造每lib和exe文件。

只是添加EXCLUDE_FROM_ALL关键字到add_executable()add_library()调用。

建设时,包括和lib目录应参考INSTALL 目录

如果referencing你的意思是将它添加到include_directories()link_directories()那么它是不是很好。最好不要在用户系统上声明所需文件的位置。正确的方法是使用find_package(),find_library()find_file()找到所需的包含和库。如果你想使用第一个功能,你需要编写FindYourLib.cmake并沿库本身安装。

建设时,添加依赖于其他lib和重建他们,如果不 最新

这是由CMake的自动完成。可以使用add_dependencies()函数添加依赖项,或者使用target_link_libraries()来隐式添加依赖项。

+0

“那么现在很好”。这是一个错字或什么?另外,INSTALL目录中的libs是我们自己的,仅供开发人员使用。我们不会分发它们。它们静态链接到可重新编译的可执行文件。所以,我们不希望将系统中的库“安装”到系统中,而是将它们分开。它更有意义吗?感谢您的回答! – Korchkidu 2012-03-13 07:41:56

+1

导入的依赖项不会被重建。来自CMake的文档:“添加到IMPORTED目标的依赖关系在传递之后被自动跟随,因为目标本身不会构建。”另外,'EXCLUDE_FROM_ALL'与独立构建目标无关,它只是阻止目标被构建为'ALL_BUILD' CMake目标的一部分。最后,在你的程序中包含另一个CMake项目的正确方法是在依赖项中使用'INSTALL(EXPORT ...'命令,然后在你的''INCLUDE''中导出' .cmake'文件,运行'cmake - -help-command INSTALL' – Fraser 2012-03-13 09:17:50