Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在GNU make中,哪个cmake命令与vpath匹配?_Cmake - Fatal编程技术网

在GNU make中,哪个cmake命令与vpath匹配?

在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+${

我正在从现有的GNU makefile重写一个cmake构建脚本。这是我试着写的第一张cmake纸条

GNU make提供vpaths命令,但我找不到相应的命令

我已经实现了一个宏来解决它,但是我发现它太难覆盖所有异常情况

你有什么解决办法吗

在许多源和目录下需要一些时间

宏vpath resultSource NumOfSource NumOfDir源列表DirList mathEXPR startDirIndex 3+${NumOfSource} mathEXPR endIndex 2+${NumOfSource}+${NumOfDir}

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-我写了一些宏。它有一些奇怪的地方。我写在下面。