【问题标题】:Can cmake compile directly from source files to binary?cmake 可以直接从源文件编译成二进制文件吗?
【发布时间】:2015-09-08 08:12:49
【问题描述】:

cmake 先将 .c 文件编译成 .o 文件,然后将它们链接在一起:

gcc a.c -o a.c.o
gcc b.c -o b.c.o
gcc c.c -o c.c.o
gcc a.c.o b.c.o c.c.o -o a.out

而不是直接从源文件编译成二进制:

gcc a.c b.c c.c -o a.out

通常我会使用链接时间优化 (-flto) 来允许编译器进行跨二进制优化,但不幸的是,我必须使用不支持链接时间优化的旧编译器。

也就是说,如果我使用 cmake,我的二进制文件比我直接从源文件编译成二进制文件大 3 倍,因为缺乏跨二进制优化

你知道让 cmake 直接从源文件编译成二进制文件的方法吗,或者你知道解决这个问题的另一种方法吗?

【问题讨论】:

    标签: gcc cmake


    【解决方案1】:

    使用 a custom commandtarget 并使用 COMMAND 参数来构建您的源文件。

    【讨论】:

      【解决方案2】:

      根据我的经验,如果您在使用 CMake 时遇到二进制文件大 3 倍等问题,您需要查看完整的构建过程。

      首先检查编译器/链接器选项是否真的相同:Using CMake with GNU Make: How can I see the exact commands?

      如果它们都匹配,您可以 - 找出哪些部分实际上更大 - 比较 CMake 和非 CMake 情况下输出的映射文件。在 CMake 中,您需要将 -Wl,-Map=<TARGET_NAME>.map 添加到链接器标志中。如何添加链接器标志见:CMake: How to set the LDFLAGS in CMakeLists.txt?

      或者在您的a.out 上使用nmsizeTool to analyze size of ELF sections and symbol

      最后您尝试激活链接器的其他优化选项(即使是较旧的编译器也应该支持通用 -O 选项)。另见:Remove useless files, includes, global variables and functions in C++

      .c vs .o 和 Windows 上的 GNU

      将源文件或目标文件提供给gcc 应该没有区别。但是,如果您在 Windows 上使用 GNU 工具链,您可能会偶然发现Windows-GNU.cmake 中的解决方法:

      # The gcc/collect2/ld toolchain does not use response files
      # internally so we cannot pass long object lists.  Instead pass
      # the object file list in a response file to the archiver to put
      # them in a temporary archive.  Hand the archive to the linker.
      

      此解决方法确实会导致:

      gcc a.c -o a.c.o
      gcc b.c -o b.c.o
      gcc c.c -o c.c.o
      rm objects.a
      ar cr a.c.o b.c.o c.c.o -o objects.a
      gcc objects.a -o a.out
      

      问题在于中间的ar 调用。如果 CMake 会直接获取 .o 文件,那你就可以了。

      您可以通过在您的project() 命令之后将CMAKE_C_LINK_EXECUTABLE 设置回其默认值来覆盖此解决方法:

      set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
      

      其他参考:CMake: use a custom linker

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-24
        • 2015-10-29
        • 1970-01-01
        相关资源
        最近更新 更多