【问题标题】:Call cmake from make to create Makefiles?从 make 调用 cmake 来创建 Makefile?
【发布时间】:2010-09-29 04:37:08
【问题描述】:

我正在使用cmake 来构建我的项目。对于 UNIX,我想从项目的根目录中键入 make,并调用 cmake 以创建正确的 Makefile(如果它们尚不存在),然后构建我的项目。我希望隐藏 cmake“内部”文件(目标文件、cmake 内部 Makefile 等)(例如放入 .build 目录),这样它就不会弄乱我的项目目录。

我的项目有几个子项目(特别是一个库、一个用户可执行文件和一个单元测试可执行文件)。我希望每个子项目的 Makefiles(即我键入 make 并且发生这种情况)执行 cmake(如上所述)并仅构建该子项目(具有依赖项,因此该库将从可执行文件构建Makefiles,如果需要)。生成的二进制文件(.so 库或可执行文件)应位于子项目的目录中。

我制作了一个 Makefile,它在主项目上做得有点好,虽然感觉有点 hackish。我无法使用它构建特定目标,因为我的 Makefile 只是在 cmake 的构建目录中调用 make

请注意,由于该库是唯一的依赖项(可能不需要手动构建,而且因为我很懒),所以我在 Makefile 中省略了它。

BUILD_DIR   :=  .build

.PHONY: all clean project-gui ${BUILD_DIR}/Makefile

all:    project-gui project-test

clean:
    @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean && rm -r ${BUILD_DIR}) || echo Nothing to clean

project-gui:  ${BUILD_DIR}/Makefile
    @make -C ${BUILD_DIR} project-gui
    @cp ${BUILD_DIR}/project-gui/project-gui $@

project-test:  ${BUILD_DIR}/Makefile
    @make -C ${BUILD_DIR} project-test
    @cp ${BUILD_DIR}/project-test/project-test $@

${BUILD_DIR}/Makefile:
    @[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
    @[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${CMAKE_OPTS} ..)

如果有帮助,这是我的项目结构(如果这是“错误的”,请告诉我——我还在学习cmake):

project/
project/CMakeLists.txt
project/common.cmake
project/Makefile -- see Makefile above for this; should be replaced with something better, building libproject, project-gui, and project-test

project/libproject/
project/libproject/CMakeLists.txt
project/libproject/libproject.so -- after build
project/libproject/Makefile -- doesn't exist yet; should build libproject only
project/libproject/source/
project/libproject/include/

project/project-gui/
project/project-gui/CMakeLists.txt
project/project-gui/Makefile -- doesn't exist yet; should build libproject then project-gui
project/project-gui/source/
project/project-gui/include/

project/project-test/
project/project-test/CMakeLists.txt
project/project-test/Makefile -- doesn't exist yet; should build libproject then project-test
project/project-test/source/
project/project-test/include/

如果您还没有理解,我基本上是在寻找一种方法来构建项目和子项目,就好像cmake 不存在一样:就好像我的项目只包含 Makefile。这可以做到吗?解决方案是优雅的还是混乱的?我应该尝试做其他事情吗?

谢谢!

【问题讨论】:

    标签: build-process build-automation makefile cmake


    【解决方案1】:

    如果cmake正在生成makefile,您可以简单地将生成的makefile包含在主makefile中,例如

    # makefile
    all:                # Default
    include $GENERATED
    $GENERATED:$CMAKEFILE
       #  Generate the makefile here`
    

    生成包含的文件,然后使用新的包含文件重新启动 make。包含的文件应详细说明目标等。

    您应该能够使用 vpath 指令更改已使用文件的位置,参见例如Gnu make manual,

    vpath %.o project/.build
    

    否则繁琐的方法是重写规则并记下必要的目录。

    编辑: 也许我们不应该使用平面 makefile。

    尝试类似:

    # makefile
    all: gui test
    clean:
        $(MAKE) -f $(GUI-MAKE) clean
        $(MAKE) -f $(TEST-MAKE) clean
    
    gui:$(GUI-MAKE)
        $(MAKE) -f $(GUI-MAKE) all
    $(GUI-MAKE):$(GUI-CMAKE)
        # Generate
    
    # Same for test
    

    如果 $(MAKE) -f $(GUI-MAKE) all 命令在命令行上工作,这应该可以工作,并且我们在生成目标中隐藏了 cmake。您还必须将任何其他目标复制到主 makefile,并注意并行运行 make。

    传播目标文件应该涉及类似

    %.o:$(GUI-MAKE)
        $(MAKE) -f $(GUI-MAKE) $@
    

    虽然你可能会在尝试制作测试对象时遇到错误

    【讨论】:

    • 哇!我什至没有想到!但是有一个问题:包含的 Makefile ($GENERATED) 需要与项目目录不同的 pwd/$CUR_DIR(它认为它在 project/.build 中)。有什么办法解决这个问题?
    • 我不认为您可以更改规则之间的工作目录,但是我在 vpath 上添加了一条注释,它应该允许您在正确的位置找到您的目标文件等。
    • 我收到以下错误,没有 vpath: make[1]: CMakeFiles/Makefile2: No such file or directory。这是由 cmake 生成的 Makefile 调用引起的:$(MAKE) -f CMakeFiles/Makefile2 all。 CMakeFiles 是我构建目录中的一个子目录。 [继续...]
    • [...] 我尝试通过以下方式使用 vpath:我的 Makefile 顶部的 VPATH=${BUILD_DIR},以及导出 VPATH=${BUILD_DIR}。两者都不起作用(同样的错误)。然后我尝试了:vpath CMakeFiles/% ${BUILD_DIR}。再次,没有变化。我是否不正确地使用该指令?我要粘贴 cmake 的 Makefile 吗?
    • 当然。我假设 cmake 的 makefile 在它自己的目录中工作正常,并且从主 makefile 的目录运行 make -f CMakeFiles/Makefile2 会产生相同的错误?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    相关资源
    最近更新 更多