从make调用cmake创建Makefiles?

18
我正在使用`cmake`构建我的项目。对于UNIX系统,我希望可以在项目的根目录中键入`make`命令,然后调用`cmake`创建相应的Makefile(如果尚不存在)并构建我的项目。我希望将`cmake`的“内部”文件(目标文件、`cmake`内部Makefile等)隐藏起来(例如放在一个`.build`目录中),以免混乱我的项目目录。
我的项目有几个子项目(特别是库、用户可执行文件和单元测试可执行文件)。我希望每个子项目都有自己的Makefile(即键入`make`命令时会发生这种情况),可以执行`cmake`(如上所述),并仅构建该子项目(包括依赖项,因此如果需要从可执行文件的Makefile构建库,则会进行构建)。生成的二进制文件(.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不存在一样:就像我的项目只包含Makefiles一样。这可以做到吗?解决方案是否优雅或混乱?我应该尝试做其他事情吗?
谢谢!
1个回答

8
如果使用CMake生成makefile,则可以简单地在主makefile中包含生成的makefile,例如:
# makefile
all:                # Default
include $GENERATED
$GENERATED:$CMAKEFILE
   #  Generate the makefile here`

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

您可以使用vpath指令更改所使用文件的位置,例如请参阅Gnu make手册

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) $@

虽然您可能会在尝试创建测试对象时遇到错误


我没有vpath时会收到以下错误消息: make[1]: CMakeFiles/Makefile2: No such file or directory. 这是由cmake生成的Makefile调用 $(MAKE) -f CMakeFiles/Makefile2 all 所致。 CMakeFiles是我的构建目录中的子目录。 [继续...] - strager
我尝试了以下几种方式使用vpath:在我的Makefile顶部设置VPATH=${BUILD_DIR},以及导出VPATH=${BUILD_DIR}。两者都没有起作用(相同的错误)。然后我尝试了:vpath CMakeFiles/% ${BUILD_DIR}。仍然没有变化。我是否不正确地使用了指令?我应该粘贴cmake的Makefile吗? - strager
@cramsin,没错。从pwd=${BUILD_DIR}运行是可以的,正如预期的那样。这就是我的旧Makefile所做的。 - strager
你的更新基本上就是我现在所拥有的。如果可能的话,我想能够构建特定的目标,例如特定的.o文件。包含的解决方案似乎很接近。如果只有一种方法可以临时更改当前工作目录... - strager
在 makefile 中,每个“命令”都在单独的 shell 中运行,因此您只需要给出一个更改目录并运行某些内容的命令即可。 目标: 依赖项 (cd $DIR; $(MAKE) target)您还可以查看 Make 的 -C 标志。 - Phil Miller
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接