【问题标题】:Can CMake generate build scripts which do *not* use cmake?CMake 可以生成不 * 使用 cmake 的构建脚本吗?
【发布时间】:2011-03-14 02:46:16
【问题描述】:

问题:CMake 能否生成不使用 CMake 的构建脚本?如果不是,那么将 CMake 生成的 automake 脚本消化为不对 CMake 进行任何检查有多难?

我是 CMake 的忠实粉丝,以至于我支持在我目前的工作环境中过渡到 CMake 的想法。如果我能证明 CMake 可以生成不需要 cmake 本身的 automake 文件,那么可以简化从我们当前的构建系统到 CMake 的过渡的一件事。

显然,我永远不想在日常使用中这样做,但是能够轻松创建可以从源代码构建而无需 cmake 的代码分支,这将大大有助于我提出自己的观点.

【问题讨论】:

  • 我觉得奇怪的是这里的答案是“否”。我刚刚开始使用 cmake 来了解如何使用它(而不是试图强迫它做一些不是为它设计的事情),例如使用源外构建等。但我确实知道 cmake 与 cpack 捆绑在一起,它可以在 Linux 和类似设备上生成 tarball。如果一个 tarball 需要 cmake 来构建,我根本不相信它是一个 tarball。
  • 我会仔细看看 CPack ;)
  • CPack 生成的压缩包通常不是用于构建的源压缩包,而是用于运行系统的二进制压缩包。
  • 讽刺的是,您会引用“CMake 生成的自动制作脚本”。 Automake 是 CMake 取代的工具之一,但“automake”这个词显然已经在文化中根深蒂固。

标签: c++ build-process cmake


【解决方案1】:

执行此操作的能力取决于您的操作系统,我假设是 Unix/Makefile 或 Windows/MSVC。如果您使用的是 MSVC,则应通过在 cmake 脚本开头声明 CMAKE_SUPPRESS_REGENERATION 选项来消除 cmake 依赖项。

SET(CMAKE_SUPPRESS_REGENERATION TRUE)

然而,在基于 Unix 的系统上,Makefile 明确地指向 cmake 构建文件(CMakeFiles 等)的 tied。我怀疑这种依赖关系可能会被 Makefile 指令的战略注释绕过,但我不能说它们可能是什么。

【讨论】:

  • CMAKE_SUPPRESS_REGENERATIONCMake 3.12 开始支持 Ninja 和 Makefile 生成器。
【解决方案2】:

不,CMake 不能这样做。这也没有任何意义,因为在构建时没有任何 CMake 支持,当 CMakeLists.txt 文件发生更改时,将无法检查或更新 makefile/项目文件本身。

如果您要从 Visual Studio 迁移到 CMake,您可能需要查看 vcproj2cmake

【讨论】:

  • 这实际上是一个“想要的”结果——我有兴趣生成一个自动工具“准备分发”类型的构建,其中 make 可用于构建项目而无需任何类型的 cmake 依赖项——到那时,如果更改没有反映在 CMake 中也没关系。
  • 这是一个 CMake 没有解决的用例。
【解决方案3】:

CMake 生成的文件依赖于 cmake 的各种命令,例如创建 / 删除 / 等...不仅仅是在更改时重新生成 makefile,因此删除 cmake 不起作用。

【讨论】:

  • +1 CMake 也可以用作脚本语言(请参阅 CMake 手册页中的选项“-P”),许多项目使用 CMake 作为 shell 脚本的替代品,例如复制文件或调用帮助程序。这些项目在构建时需要 CMake,而不仅仅是生成 makefile。
【解决方案4】:

作为一个已经使用了一个大型复杂软件并最近撤出其现有构建系统并在其位置安装新构建系统的人。我可以告诉你这并不容易,但我绝对不希望 shell 脚本作为我构建过程的一部分,如果它们可以避免的话。无论如何,随着越来越多的大牌软件包(如 LLVM 和 KDE)开始使用 CMake,越来越多的系统会发现自己使用 CMake——这是一个真正加速大型项目的领域。

CMake 的一大优点是构建速度更快。不得不 fork shell 实例来解释脚本确实会减慢构建过程。

【讨论】:

    【解决方案5】:

    “原子解决方案”呢?

    EX- 从 CMakeLists.txt 自动生成一个“QT moc”文件,然后构建依赖于正在生成的 .cpp 文件的项目

    # inside project level CMakeLists.txt 
    # run shell script to create the "moc_GUICreator.cpp" auto-generated source file
    if(UNIX)
    execute_process(COMMAND "sh" ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_moc.sh  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts )
    endif(UNIX)
    

    .sh 文件包含的位置:

    # generate_moc.sh
    echo "generating moc file:  moc ../include/GUICreator.h  -o  ../src/moc_GUICreator.cpp "
    moc ../include/GUICreator.h -o ../src/moc_GUICreator.cpp
    

    等效的windows批处理文件,“moc_creator_win.bat”:

    moc "GUICreator.h" -o "moc_GUICreator.cpp"
    

    还没有在 Windows 中尝试过最后一点,但它或非常接近的东西应该可以工作,就在 CMakeLists.txt 中的 if(UNIX) 块之后:

    if(WIN32)
    execute_process(COMMAND "cmd" ${CMAKE_CURRENT_SOURCE_DIR}/scripts/moc_creator_win.bat  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts )
    endif(WIN32)
    

    所以,基本上,如果你很聪明,你可以从脚本中做任何你想做的事情,并使用 CMake 变量作为它的参数,我不确定你是否可以要求更多......

    关键是要避免“不可移植的构建类型”,除非您真的需要将其破解到专门的编译器中,或者不想使用 QT Designer 来放置小部件;-)

    【讨论】:

    • 您可以按预期使用 CMake,或者在频谱的另一端,只需将其包装在任意脚本周围。没有什么可以阻止您解析 cmake 变量并生成您想要的任何 makefile...
    猜你喜欢
    • 2015-09-05
    • 2014-05-24
    • 2012-02-11
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多