CMake:在 XCode 中生成和编译特定于体系结构的源文件

CMake: generate and compile architecture-specific source files in XCode

我有一个 CMake 项目,用于生成支持多个 CPU 架构(arm64 和 armv7)的 iOS 目标 XCode 项目。

我的 CMake 项目包含一些将 Lua 脚本转换为 C++ 源文件的命令(用 add_custom_command 定义)。这些生成的 C++ 文件因体系结构而异(不应为 arm64 编译 armv7 文件,反之亦然)。 该工具旨在像这样调用:

./data_tool --input <script> --output <C++ source> --architecture <armv7 or arm64>

我的(不正确的)CMake 文件目前看起来像这样:

foreach(ARCHITECTURE ${TARGET_ARCHITECTURES})
        string(
            REPLACE ".lua" ".cpp" GENERATED_CPP
            ${GENERATED_SOURCE_DIRECTORY}/${ARCHITECTURE}/${INPUT_SCRIPT}
        )

        add_custom_command(
                    OUTPUT ${GENERATED_CPP}
                    COMMAND ${DATA_TOOL} --input "${INPUT_SCRIPT}" --output "${GENERATED_CPP}" --architecture ${ARCHITECTURE}
                    MAIN_DEPENDENCY ${INPUT_SCRIPT}
        )
        list( APPEND GENERATED_SOURCE ${GENERATED_CPP} )
endforeach()

稍后,GENERATED_SOURCE 被附加到传递给 add_executable 的源文件列表中。这段代码显然是错误的,因为在为任一体系结构构建时都会编译 armv7 和 arm64 文件。

如何告诉 CMake 每个架构编译一组不同的源文件?

好吧,不要将不同架构的生成源放在同一个列表中。展开 foreach body 并为每个拱门重复这些命令。

如果您不想引入代码重复,您可以编写一个 CMake function 来创建该自定义命令和 return 生成的源列表。请参阅 this question 以了解如何 return 来自函数的值。

XCode 没有基于正在构建的体系结构排除文件的好方法。虽然这是可能的(参见 Disabling some files in XCode project from compilation),但通过 CMake 进行设置会有些困难。

相反,我建议简单地让您的生成 tool/script 为生成的文件支持的体系结构在整个文件周围放置预处理器防护。这样,当 XCode 编译它们时,它们基本上是空的,除了它们所针对的体系结构。在这个答案 (Determine if the device is ARM64) 中,它展示了如何基于 arm64 进行条件编译(并且对 armv7 使用反向编译)。