从 make 调用 cmake 来创建 Makefile?
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果cmake正在生成makefile,您可以简单地将生成的makefile包含在主makefile中,例如
生成包含的文件,然后使用新的包含的文件重新启动make。 包含的文件应详细说明目标等。
您应该能够使用 vpath 指令更改使用的文件的位置,请参见 Gnu make 手册,
否则繁琐的方法是重写规则,记下必要的目录。
埃德:
也许我们不应该使用平面 makefile。
尝试如下操作:
如果 $(MAKE) -f $(GUI-MAKE) all 命令在命令行上运行,并且我们已在生成目标中隐藏了 cmake,则这应该可以工作。 您还必须将任何其他目标复制到主 makefile,并小心并行运行 make。
传播对象文件应该涉及类似的内容,
尽管您可能会在尝试创建测试对象时遇到错误
If cmake is generating the makefiles, you can simply include the generated makefile in the master makefile, eg
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,
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:
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
although you'll probably get errors trying to make test objects