如何将$ {CMAKE_CURRENT_SOURCE_DIR}添加到变量中的所有文件?

时间:2012-10-27 18:36:46

标签: cmake

我有子目录的项目,我想保持每个目录的源列表分开。

我有:

SET( SUBDIR_SOURCES
  ${CMAKE_CURRENT_SOURCE_DIR}/a.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/b.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/c.cpp
  PARENT_SCOPE
)

我想:

SET( SUBDIR_SOURCES
  a.cpp
  b.cpp
  c.cpp
  PARENT_SCOPE
)
some_magic_fuction( SUBDIR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR} )

3 个答案:

答案 0 :(得分:2)

我经常为每个子目录写一个小CMakeLists.txt,它将该目录中的所有文件编译成一个库。

在父目录的CMakeLists.txt中,我添加了add_subdirectory( blah )的每个子目录。

如果必须具有指定的变量,则以下内容应该有效(请注意,我实际上没有测试过它):

MACRO( prepend_path _srcs _path )
    unset( _tmp )
    foreach( src ${_srcs} )
        list( append _tmp ${_path}/${src} )
    endforeach( src ${_srcs} )
    set( _srcs ${_tmp} )
ENDMACRO( prepend_path _srcs )

这样称呼它:

prepend_path( SUBDIR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR} )

答案 1 :(得分:2)

要让some_magic_function传递源列表,首先您需要避免在PARENT_SCOPE中设置它们,因为它们在子目录的CMakeList范围内不可用。

您也不需要将${CMAKE_CURRENT_SOURCE_DIR}传递给函数,因为它将在函数内部可用,无论函数本身在何处定义。

所以你可以这样做:

SET( SUBDIR_SOURCES a.cpp b.cpp c.cpp )
some_magic_function( SUBDIR_SOURCES )
SET( SUBDIR_SOURCES ${SUBDIR_SOURCES} PARENT_SCOPE )

,功能可以是:

FUNCTION( some_magic_function SOURCE_FILES )
  FOREACH( SOURCE_FILE ${${SOURCE_FILES}} )
    SET( MODIFIED ${MODIFIED} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE} )
  ENDFOREACH()
  SET( ${SOURCE_FILES} ${MODIFIED} PARENT_SCOPE )
ENDFUNCTION()

在函数内部,${SOURCE_FILES}SUBDIR_SOURCES,因此我们需要使用${${SOURCE_FILES}}来获取实际的文件列表。

函数有自己的范围,因为我们要在函数外部的范围内替换SUBDIR_SOURCES的值,我们需要在调用PARENT_SCOPE时使用SET( ${SOURCE_FILES}...

有关这些命令的更多信息,请运行:

cmake --help-command set
cmake --help-command function

答案 2 :(得分:0)

我通常也更喜欢具有自己的局部变量范围的函数,但在你的情况下,我建议你编写自己的宏命令。

因此,采用Fraser的代码,如下所示:

macro( set_subdir_sources )
    foreach( SOURCE_FILE ${ARGN} )
        set( SUBDIR_SOURCES ${SUBDIR_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE} )
    endforeach()
    set( SUBDIR_SOURCES ${SUBDIR_SOURCES} PARENT_SCOPE )
endmacro()

或者使用相对路径:

macro( set_subdir_sources )
    get_directory_property( _PARENTDIR PARENT_DIRECTORY )
    file( RELATIVE_PATH _SUBDIR ${_PARENTDIR} ${CMAKE_CURRENT_SOURCE_DIR} )
    foreach( SOURCE_FILE ${ARGN} )
        set( SUBDIR_SOURCES ${SUBDIR_SOURCES} ${_SUBDIR}/${SOURCE_FILE} )
    endforeach()
    set( SUBDIR_SOURCES ${SUBDIR_SOURCES} PARENT_SCOPE )
endmacro()

然后致电:

set_subdir_sources( a.cpp b.cpp c.cpp )

您的父CMakeLists.txt无论如何都必须知道SUBDIR_SOURCES变量。这也有一个好处,你可以在子目录的CMakeLists.txt中多次调用它。

但是你真的需要在一个没有首先定义自己的目标的子目录中的CMakeLists.txt吗?我只是将源添加到父目录CMakeLists.txt

set( 
  SUBDIR_SOURCES
  SubDir/a.cpp
  SubDir/b.cpp
  SubDir/c.cpp
)

另见CMakeLists.txt files for multiple libraries and executables