如何在 CMake 中添加非标准构建步骤

发布于 2025-01-09 16:10:28 字数 792 浏览 0 评论 0原文

对于我现有的基于 CMake 的项目,我希望启用 C 编译器提供的优化。与大多数优化不同,这需要多次运行编译器,生成或使用中间文件。具体来说,对于每个C文件,它消耗C文件并产生相应的中间文件。然后编译器运行并消耗所有中间文件(可能读取它们并将它们写回)。最后,对于每个 C 文件,编译器都会翻译 C 文件,同时也使用相应的中间文件,以生成目标文件。

编译器供应商提供了一个示例 Makefile:

SRCS=src/file1.c src/file2.c src/file3.c
INFS=objs/file1.inf objs/file2.inf objs/file3.inf
OBJS=objs/file1.o objs/file2.o objs/file3.o
CFLAGS=-object_dir=objs -Owholeprogram -Ogeneral -I.

myprog: ${OBJS}
   ${CC} -o myprog ${OBJS}

# first pass
objs/%.inf: src/%.c ${SRCS}
   ${CC} ${CFLAGS} $< -Q

# second pass
qnormalize: ${INFS}
   ${CC} ${CFLAGS} ${INFS} -Qnormalize
   touch qnormalize

# third pass
objs/%.o: src/%.c objs/%.inf qnormalize
   ${CC} ${CFLAGS} ${INFS} $< -c -Qfinal

有没有办法使用 CMake 来完成此任务?我考虑过添加自定义目标和依赖项,但我看不到实际执行此操作的方法。

For my existing CMake-based project, I want to enable an optimization available from our C compiler. Unlike most optimizations, this requires running the compiler several more times, either producing or consuming intermediate files. Specifically for each each C file, it consumes the C file and produces a corresponding intermediate file. Then the compiler is run and consumes all the intermediate files (perhaps reading them and writing them back out). Then finally for each C file the compiler translates the C file, also making use of the corresponding intermediate file, to produce an object file.

The compiler vendor provides a sample Makefile:

SRCS=src/file1.c src/file2.c src/file3.c
INFS=objs/file1.inf objs/file2.inf objs/file3.inf
OBJS=objs/file1.o objs/file2.o objs/file3.o
CFLAGS=-object_dir=objs -Owholeprogram -Ogeneral -I.

myprog: ${OBJS}
   ${CC} -o myprog ${OBJS}

# first pass
objs/%.inf: src/%.c ${SRCS}
   ${CC} ${CFLAGS} 
lt; -Q

# second pass
qnormalize: ${INFS}
   ${CC} ${CFLAGS} ${INFS} -Qnormalize
   touch qnormalize

# third pass
objs/%.o: src/%.c objs/%.inf qnormalize
   ${CC} ${CFLAGS} ${INFS} 
lt; -c -Qfinal

Is there a way to accomplish this with CMake? I looked at adding custom targets and dependencies, but I can't see a way to actually do it.

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

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

发布评论

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

评论(1

活泼老夫 2025-01-16 16:10:28

没有简单的方法 - 你似乎正在使用一些我不知道的编译器。 CMake 必须知道如何生成依赖项(GCC 编译器的 -MD -MT 标志)以及要传递哪些标志,为此,您必须为特定编译器创建整个编译器配置(例如 < code>Modules/Compiler/**-C-DetermineCompiler.cmake 和 Modules/Platform/Generic-**-C.cmake 等文件,其中 ** 是您的编译器的名称)。

这可以作为初始配置,如果 CMake 检测到编译器,这可以帮助您入门。如果 CMake 不知道编译器,您可以使用 add_custom_command 编写所有内容,并在末尾添加一个 add_custom_target

cmake_minimum_required(VERSION 3.11)
project(test C)

foreach(i IN RANGE 1 3 1)
   # objs/%.inf: src/%.c ${SRCS}
   add_custom_command(
       OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/objs/file${i}.inf
       DEPENDS
        ${CMAKE_CURRENT_SOURCE_DIR}/src/file1.c
        ${CMAKE_CURRENT_SOURCE_DIR}/src/file2.c
        ${CMAKE_CURRENT_SOURCE_DIR}/src/file3.c
      COMMAND
        ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} 
        ${CMAKE_CURRENT_BINARY_DIR}/objs/file${i}.inf
        -Q
      COMMENT "Generting file${i}.inf"
   )
endforeach()

# qnormalize: ${INFS}
add_custom_command(
      OUTPUT
          ${CMAKE_CURRENT_BINARY_DIR}/qnormalize
      DEPENDS
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
      COMMAND
          # ${CC} ${CFLAGS} ${INFS} -Qnormalize
          ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS}
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
         -Qnormalize
      COMMAND
         ${CMAKE_COMMAND} -E touch 
         ${CMAKE_CURRENT_BINARY_DIR}/qnormlize
)

add_executable(myprog 
   src/file1.c
   src/file2.c
   src/file3.c
)
add_compile_options(myprog PRIVATE
     ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
     ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
     ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
     -Qfinal
)
    
# objs/%.o: src/%.c objs/%.inf qnormalize
#   ${CC} ${CFLAGS} ${INFS} 
lt; -c -Qfinal
foreach(i IN RANGE 1 3 1)
   add_file_dependencies(src/file${i}.c
      ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
      ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
      ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
      ${CMAKE_CURRENT_BINARY_DIR}/qnormalize
   )
endforeach()

# myprog: ${OBJS} #   ${CC} -o myprog ${OBJS}
add_executable(myprog
   src/file1.c
   src/file2.c
   src/file3.c
)
target_compile_options(myprog PRIVATE -Qfinal)

There is no easy way - you seem to be using some compiler not known to me. CMake has to know how to generate dependencies (-MD -MT flags to GCC compiler) and what flags to pass, for that you would have to create the whole compiler configuration for your specific compiler (files like Modules/Compiler/**-C-DetermineCompiler.cmake and Modules/Platform/Generic-**-C.cmake and other files, where ** is the name of your compiler).

This may serve as an initial configuration, if the compiler is detected by CMake which may help you get started. If the compiler is unknown to CMake, you can just write everything with add_custom_command and single add_custom_target on the end.

cmake_minimum_required(VERSION 3.11)
project(test C)

foreach(i IN RANGE 1 3 1)
   # objs/%.inf: src/%.c ${SRCS}
   add_custom_command(
       OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/objs/file${i}.inf
       DEPENDS
        ${CMAKE_CURRENT_SOURCE_DIR}/src/file1.c
        ${CMAKE_CURRENT_SOURCE_DIR}/src/file2.c
        ${CMAKE_CURRENT_SOURCE_DIR}/src/file3.c
      COMMAND
        ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} 
        ${CMAKE_CURRENT_BINARY_DIR}/objs/file${i}.inf
        -Q
      COMMENT "Generting file${i}.inf"
   )
endforeach()

# qnormalize: ${INFS}
add_custom_command(
      OUTPUT
          ${CMAKE_CURRENT_BINARY_DIR}/qnormalize
      DEPENDS
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
      COMMAND
          # ${CC} ${CFLAGS} ${INFS} -Qnormalize
          ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS}
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
          ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
         -Qnormalize
      COMMAND
         ${CMAKE_COMMAND} -E touch 
         ${CMAKE_CURRENT_BINARY_DIR}/qnormlize
)

add_executable(myprog 
   src/file1.c
   src/file2.c
   src/file3.c
)
add_compile_options(myprog PRIVATE
     ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
     ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
     ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
     -Qfinal
)
    
# objs/%.o: src/%.c objs/%.inf qnormalize
#   ${CC} ${CFLAGS} ${INFS} 
lt; -c -Qfinal
foreach(i IN RANGE 1 3 1)
   add_file_dependencies(src/file${i}.c
      ${CMAKE_CURRENT_BINARY_DIR}/objs/file1.inf
      ${CMAKE_CURRENT_BINARY_DIR}/objs/file2.inf
      ${CMAKE_CURRENT_BINARY_DIR}/objs/file3.inf
      ${CMAKE_CURRENT_BINARY_DIR}/qnormalize
   )
endforeach()

# myprog: ${OBJS} #   ${CC} -o myprog ${OBJS}
add_executable(myprog
   src/file1.c
   src/file2.c
   src/file3.c
)
target_compile_options(myprog PRIVATE -Qfinal)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文