在GNU make中,哪个cmake命令与vpath匹配?
我正在从现有的GNU makefile重写一个cmake构建脚本。这是我试着写的第一张cmake纸条 GNU make提供vpaths命令,但我找不到相应的命令 我已经实现了一个宏来解决它,但是我发现它太难覆盖所有异常情况 你有什么解决办法吗 在许多源和目录下需要一些时间 宏vpath resultSource NumOfSource NumOfDir源列表DirList mathEXPR startDirIndex 3+${NumOfSource} mathEXPR endIndex 2+${NumOfSource}+${NumOfDir}在GNU make中,哪个cmake命令与vpath匹配?,cmake,Cmake,我正在从现有的GNU makefile重写一个cmake构建脚本。这是我试着写的第一张cmake纸条 GNU make提供vpaths命令,但我找不到相应的命令 我已经实现了一个宏来解决它,但是我发现它太难覆盖所有异常情况 你有什么解决办法吗 在许多源和目录下需要一些时间 宏vpath resultSource NumOfSource NumOfDir源列表DirList mathEXPR startDirIndex 3+${NumOfSource} mathEXPR endIndex 2+${
message(STATUS "startDirIndex: ${startDirIndex}")
message(STATUS "endIndex: ${endIndex}")
set( __SRC_LIST__ )
set( __SRC_DIR__ )
set( pos 0 )
foreach(item ${ARGV})
if( ${pos} EQUAL ${startDirIndex}
OR ${pos} GREATER ${startDirIndex} )
list( APPEND __SRC_DIR__ ${item} )
#message(STATUS "DIR:${item}")
elseif( ${pos} GREATER 2 )
list( APPEND __SRC_LIST__ ${item} )
#message(STATUS "SRC:${item}")
endif( ${pos} EQUAL ${startDirIndex}
OR ${pos} GREATER ${startDirIndex} )
math(EXPR pos "${pos}+1")
endforeach(item ${ARGV})
#message(STATUS "__SRC_LIST__: ${__SRC_LIST__}")
#message(STATUS "__SRC_DIR__: ${__SRC_DIR__}")
#set( SOURCE_EXTENTION cpp c C CPP)
set( SOURCE_EXTENTION cpp )
#list( APPEND SOURCE_EXTENTION ${CMAKE_CXX_SOURCE_FILE_EXTENSIONS} ${CMAKE_C_SOURCE_FILE_EXTENSIONS} )
#message(STATUS "SOURCE_EXTENTION: ${SOURCE_EXTENTION}")
set( temp_list "" )
foreach( dir ${__SRC_DIR__} )
foreach( src ${__SRC_LIST__} )
set( cand_src )
foreach( postfix ${SOURCE_EXTENTION})
set( cand_src "${dir}/${src}.${postfix}" )
file(GLOB result ${cand_src} )
if( NOT ${result} STREQUAL "" )
list( APPEND temp_list ${result} )
endif( NOT ${result} STREQUAL "" )
endforeach( postfix ${SOURCE_EXTENTION})
endforeach( src ${__SRC_LIST__} )
endforeach( dir ${__SRC_DIR__} )
set( ${resultSource} ${temp_list} )
#message(STATUS "temp_list: ${temp_list}")
endmacro vpath resultSource NumOfSource NumOfDir sourceList DirList这就是我的想法。完整免责声明:我不是真正的cmake大师,这个答案完全基于我在阅读问题后的研究。我没有一个项目来测试它,而且我从来没有在我编写的Makefile中使用过vpath 此外,这个问题没有发布示例Makefile,也没有发布OP使用的宏,这让我在给出这个答案时犹豫不决,但这里是 第一:为什么我们在Makefile中使用vpath? 因为我不知道vpath是什么,所以我查了一下。从第4.5节: make的目录搜索功能通过自动搜索多个目录来查找先决条件,从而简化了这一过程。。。 与VPATH变量类似,但更具选择性的是VPATH指令note小写,它允许您为特定类别的文件名指定搜索路径:与特定模式匹配的文件名。因此,您可以为一类文件名和其他目录提供某些搜索目录,或为其他文件名提供任何搜索目录 因此,您使用vpath查找分布在多个目录中的文件。我进一步推测,这些文件要么是源文件,要么是在构建过程中创建的中间文件 我找到了几个vpath示例,它们似乎表明了vpath的用法,最后是第2.3节 这就是为什么要使用vpath。因此,继续: 其次,如何使用cmake实现同样的目标。这就是OP的进一步投入会有所帮助的地方 如果您有多个目标是从如下目录结构生成的:
|- library1/
|-- {C++ Source}
|- Tool/
|-- {C++ Source}
|- Project/
|-- src/
|---- {C++ Source}
|-Project/
|--src/
|----maths/
|------ { SOURCE FILES }
|----sound/
|------ { SOURCE FILES }
|----imagegeneration/
|------ { SOURCE FILES }
您应该使用多个CMakeLists.txt,每个子目录中一个。在library1中,您将构建库ADD_library libNAME src1.cxx src2.cxx src3.cxx,在工具中,您将添加可执行文件ADD_可执行文件工具src1.cxx src2.cxx。最后,在Project/src/中,您将使用ADD_可执行文件构建您的项目可执行文件,并将其链接到您在library1中构建的libNAME
在这种情况下,您永远不需要搜索,因为您的源代码显式地放在CMakeLists.txt中
如果您没有执行上述操作,并且您的源代码仅分布在许多目录中,则如下所示:
|- library1/
|-- {C++ Source}
|- Tool/
|-- {C++ Source}
|- Project/
|-- src/
|---- {C++ Source}
|-Project/
|--src/
|----maths/
|------ { SOURCE FILES }
|----sound/
|------ { SOURCE FILES }
|----imagegeneration/
|------ { SOURCE FILES }
在这种情况下,您只构建了一个东西,您只是为了方便使用而扩展了源代码。在这种情况下,有几个选项供您选择
您可以使用发布的答案自动将某一类型的所有文件添加到目标。这是不应该做的!从cmake-help命令文件emphasis-mine:GLOB将生成与globbing表达式匹配的所有文件的列表,并将其存储到变量中。。。我们不建议使用GLOB从源代码树中收集源文件列表。[原因见下文]
可以使用add_subdirectory指令添加多个子目录,每个源子目录对应一个子目录。这也不理想。一些支持文档:以这种方式讨论add_子目录的使用的
您可以使用aux_source_目录从指定目录收集源文件并存储在变量中。如果您感兴趣,请阅读cmake-help命令aux\u source\u目录。但是,也不建议这样做
那么为什么不使用1、2或3呢?
cmake不是make或Makefiles的替代品。相反,cmake生成一个构建系统,然后您可以使用它来构建项目。这是一个值得注意的区别。虽然您可以轻松地将多个源自动添加到CMakeLists.txt中,但这将导致cmake的不确定性:cmake将无法创建一个了解源文件的生成系统来确定发生了哪些更改
这是上述三种方法的问题。从cmake-help命令辅助源目录:
虽然这似乎有效,
CMake无法生成知道
已添加新的源文件。通常生成的构建系统
知道何时需要重新运行CMake,因为CMakeLists.txt文件
已修改以添加新源。当源刚刚添加到
如果不修改此文件,将有
e)手动执行
重新运行CMake以生成包含新文件的生成系统
总结:如何将源文件添加到cmake
在使用cmake时,应该将源文件显式添加到每个CMakeLists.txt。如果使用多个目录来分隔逻辑代码段,则应在CMakeLists.txt中显式设置,如下所示:
set ( MyApplication_SRC_FILES
maths/a.cpp
maths/b.cpp
sound/c.cpp
sound/d.cpp
imagegeneration/e.cpp
imagegeneration/f.cpp
)
ADD_EXECUTABLE ( MyApplication ${MyApplication_SRC_FILES} )
然后,这允许cmake生成一个构建系统,该系统可以构建您的代码。有适当的方法将目录中的许多文件添加到构建系统中,如上文1、2和3所述;但是应该谨慎对待它们,而不是仅仅因为我使用Makefile就是这样做的就使用它们。您不需要编写构建系统本身;这是Makefile的一个倒退,因此应该稍微区别对待 我就是这么想的。完整免责声明:我不是真正的cmake大师,这个答案完全基于我在阅读问题后的研究。我没有一个项目来测试它,而且我从来没有在我编写的Makefile中使用过vpath 此外,这个问题没有发布示例Makefile,也没有发布OP使用的宏,这让我在给出这个答案时犹豫不决,但这里是 第一:为什么我们在Makefile中使用vpath? 因为我不知道vpath是什么,所以我查了一下。从第4.5节: make的目录搜索功能通过自动搜索多个目录来查找先决条件,从而简化了这一过程。。。 与VPATH变量类似,但更具选择性的是VPATH指令note小写,它允许您为特定类别的文件名指定搜索路径:与特定模式匹配的文件名。因此,您可以为一类文件名和其他目录提供某些搜索目录,或为其他文件名提供任何搜索目录 因此,您使用vpath查找分布在多个目录中的文件。我进一步推测,这些文件要么是源文件,要么是在构建过程中创建的中间文件 我找到了几个vpath示例,它们似乎表明了vpath的用法,最后是第2.3节 这就是为什么要使用vpath。因此,继续: 其次,如何使用cmake实现同样的目标。这就是OP的进一步投入会有所帮助的地方 如果您有多个目标是从如下目录结构生成的:
|- library1/
|-- {C++ Source}
|- Tool/
|-- {C++ Source}
|- Project/
|-- src/
|---- {C++ Source}
|-Project/
|--src/
|----maths/
|------ { SOURCE FILES }
|----sound/
|------ { SOURCE FILES }
|----imagegeneration/
|------ { SOURCE FILES }
您应该使用多个CMakeLists.txt,每个子目录中一个。在library1中,您将构建库ADD_library libNAME src1.cxx src2.cxx src3.cxx,在工具中,您将添加可执行文件ADD_可执行文件工具src1.cxx src2.cxx。最后,在Project/src/中,您将使用ADD_可执行文件构建您的项目可执行文件,并将其链接到您在library1中构建的libNAME
在这种情况下,您永远不需要搜索,因为您的源代码显式地放在CMakeLists.txt中
如果您没有执行上述操作,并且您的源代码仅分布在许多目录中,则如下所示:
|- library1/
|-- {C++ Source}
|- Tool/
|-- {C++ Source}
|- Project/
|-- src/
|---- {C++ Source}
|-Project/
|--src/
|----maths/
|------ { SOURCE FILES }
|----sound/
|------ { SOURCE FILES }
|----imagegeneration/
|------ { SOURCE FILES }
在这种情况下,您只构建了一个东西,您只是为了方便使用而扩展了源代码。在这种情况下,有几个选项供您选择
您可以使用发布的答案自动将某一类型的所有文件添加到目标。这是不应该做的!从cmake-help命令文件emphasis-mine:GLOB将生成与globbing表达式匹配的所有文件的列表,并将其存储到变量中。。。我们不建议使用GLOB从源代码树中收集源文件列表。[原因见下文]
可以使用add_subdirectory指令添加多个子目录,每个源子目录对应一个子目录。这也不理想。一些支持文档:以这种方式讨论add_子目录的使用的
您可以使用aux_source_目录从指定目录收集源文件并存储在变量中。如果您感兴趣,请阅读cmake-help命令aux\u source\u目录。但是,也不建议这样做
那么为什么不使用1、2或3呢?
cmake不是make或Makefiles的替代品。相反,cmake生成一个构建系统,然后您可以使用它来构建项目。这是一个值得注意的区别。虽然您可以轻松地将多个源自动添加到CMakeLists.txt中,但这将导致cmake的不确定性:cmake将无法创建一个了解源文件的生成系统来确定发生了哪些更改
这是上述三种方法的问题。从cmake-help命令辅助源目录:
虽然这似乎有效,
CMake无法生成知道
已添加新的源文件。通常生成的构建系统
知道何时需要重新运行CMake,因为CMakeLists.tx
t文件是
已修改以添加新源。当源刚刚添加到
目录,而不修改此文件,则必须手动
重新运行CMake以生成包含新文件的生成系统
总结:如何将源文件添加到cmake
在使用cmake时,应该将源文件显式添加到每个CMakeLists.txt。如果使用多个目录来分隔逻辑代码段,则应在CMakeLists.txt中显式设置,如下所示:
set ( MyApplication_SRC_FILES
maths/a.cpp
maths/b.cpp
sound/c.cpp
sound/d.cpp
imagegeneration/e.cpp
imagegeneration/f.cpp
)
ADD_EXECUTABLE ( MyApplication ${MyApplication_SRC_FILES} )
然后,这允许cmake生成一个构建系统,该系统可以构建您的代码。有适当的方法将目录中的许多文件添加到构建系统中,如上文1、2和3所述;但是应该谨慎对待它们,而不是仅仅因为我使用Makefile就是这样做的就使用它们。您不需要编写构建系统本身;这是Makefile的一个倒退,因此应该稍微区别对待 嗯,你为什么需要它?你能展示一下这个宏的代码吗?嗯,你为什么需要它?你能显示这个宏的代码吗?谢谢。遗留makefile有太多的源代码,所以我不能重写你的建议选项-1,2,3-我写了一些宏。它有一些奇怪的地方。我写在下面,谢谢。遗留makefile有太多的源代码,所以我不能重写你的建议选项-1,2,3-我写了一些宏。它有一些奇怪的地方。我写在下面。