从 make 调用 cmake 来创建 Makefile?

发布于 2024-07-10 16:52:58 字数 2440 浏览 6 评论 0原文

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

我的项目有几个子项目(特别是一个库、一个用户可执行文件和一个单元测试可执行文件)。 我希望每个子项目的 Makefiles(即我输入 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 不存在一样:就好像我的项目仅由 Makefile 组成。 这可以做到吗? 解决方案是优雅的还是混乱的? 我应该尝试做点别的事情吗?

谢谢!

I am using cmake to build my project. For UNIX, I would like to type make from my project's root directory, and have cmake invoked to create the proper Makefiles (if they don't exist yet) and then build my project. I would like the cmake "internal" files (object files, cmake internal Makefiles, etc.) to be hidden (e.g. put in a .build directory) so it doesn't clutter my project directory.

My project has several sub-projects (in particular, a library, a user executable, and a unit test executable). I would like Makefiles (i.e. I type make and this happens) for each sub-project to execute cmake (as above) and build only that sub-project (with dependencies, so the library would be built from the executables' Makefiles, if needed). The resulting binary (.so library or executable) should be in the sub-project's directory.

I made a Makefile which does the main project bit somewhat well, though it feels somewhat hackish. I can't build specific targets using it, because my Makefile simply calls make in cmake's build directory.

Note that because the library is a sole dependency (and probably doesn't need to be build manually, and because I'm lazy) I omitted it in my 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} ..)

If it helps, here's my project structure (if this is "wrong" please tell me -- I'm still learning 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/

If you haven't caught on yet, I'm basically looking for a way to build the project and sub-projects as if cmake wasn't there: as if my project consisted of only Makefiles. Can this be done? Is the solution elegant, or messy? Should I be trying to do something else instead?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美的太阳 2024-07-17 16:52:58

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

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

If cmake is generating the makefiles, you can simply include the generated makefile in the master makefile, eg

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

The included files are generated then make is restarted with the new included files. The included files should detail the targets, etc.

You should be able to change the location of used files using the vpath directive, see e.g. the Gnu make manual,

vpath %.o project/.build

else the tedious way is to rewrite the rules making note of the necessary directory.

Ed:
Perhaps we shouldn't use a flat makefile.

Try something like:

# 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

This should work if the $(MAKE) -f $(GUI-MAKE) all command works on the command line, and we've hidden cmake in the generating target. You would have to copy any other targets to the master makefile as well, and take care running make in parallel.

Propagating object files through should involve something like

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

although you'll probably get errors trying to make test objects

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文