【问题标题】:CMake - compile natively and crosscompile the same codeCMake - 本地编译和交叉编译相同的代码
【发布时间】:2016-09-21 12:11:36
【问题描述】:

我们正在为嵌入式 ARM/Linux 设备编写应用程序。使用交叉编译器、Eclipse 和 Ninja 在 Windows PC 上进行开发。 CMake 目前可以创建适合预期目的的构建脚本。

一旦项目(通过 Git)推送到服务器,我们就会在连接到网络的嵌入式设备上运行单元测试。

在我们在设备上尝试之前,我们正在尝试实现可以​​在 PC 上运行的单元测试。这意味着使用 MinGW GCC 本地构建 - 当然我们不能在 PC 上启动 ARM Linux 可执行文件。

即使我们切换工具链,启动 CMake 为 Ninja 重建规则集,或者创建两个构建目录,一个用于 PC,一个用于 ARM,问题仍然是 CMake 将尝试运行测试可执行文件,然后在构建期间,将在 ARM 版本上尝试单元测试。

我们如何配置构建(通过 CMake)来创建两者 - 而不是尝试在 PC 上运行交叉编译的构建?

【问题讨论】:

  • 您能否添加一个 CMake 代码示例,说明您如何执行“运行测试可执行文件”?您是否将其添加为add_custom_command(TARGET ... POST_BUILD ...) 和/或add_test()?我认为在这两种情况下,只需在此特定命令周围加上 if (NOT CMAKE_CROSSCOMPILING)|endif() 就可以了。
  • @Florian:在顶级 CMakeLists.txt 中只有 ADD_SUBDIRECTORY(UnitTests)。然后在目录中有ExternalProject_Add(GMockDownload GIT_REPOSITORY "https://github.com/google/googletest.git" ...,它完成了剩下的工作。是的,if (NOT CMAKE_CROSSCOMPILING) 在这里有帮助。似乎两个单独的构建目录和两次启动 cmake 是一种方式。不是最优的,因为我得到了两个 Eclipse 项目,而不仅仅是两个构建配置。

标签: build cmake cross-compiling ninja


【解决方案1】:

我的项目中有类似的设置(从相同的源构建模拟器、单元测试和目标二进制文件),您可以检查 CMAKE_CROSSCOMPILING 以区分您的两个用例。只是放

if (NOT CMAKE_CROSSCOMPILING)
    ....
endif()

围绕特定的命令应该可以解决问题。

而且你需要有两个二进制输出目录。 CMake 不允许在一个目录中混合工具链。

但您不需要有两个 IDE 项目。在我的项目中:

  • 我已添加所有来源 - 包括。 “仅交叉编译”文件 - 进入库/可执行目标
    • 对于仅限 PC 的变体,我将它们标记为“从构建中排除”
    • 因此所有源都将显示在一个 IDE 项目中(例如,用于搜索代码)
  • 我已将交叉编译调用添加为自定义目标
    • 我已将其从默认构建中删除,但您可以从 IDE 显式启动它
    • 在我的例子中,它是一个外部脚本,但您也可以直接在 COMMAND 参数中传递必要的调用
    • 您甚至可以使用另一个 ExternalProject_Add() 来包含您自己的项目以进行交叉编译

以下是这种方法的一些代码 sn-ps:

if (NOT CMAKE_CROSSCOMPILING)
    set(PC "ON" CACHE INTERNAL "hw-platform PC")
    unset(MCU CACHE)
else()
    set(MCU "ON" CACHE INTERNAL "hw-platform MCU")
    unset(PC CACHE)
endif()

...

if (PC)
    # Exclude files that only compile/work on MCU
    set_source_files_properties(... PROPERTIES HEADER_FILE_ONLY 1)
endif()

...

if (PC)
    add_test(...)
endif()

...

if (PC AND EXISTS "${CMAKE_SOURCE_DIR}/buildMcu.cmd")
    add_custom_target(
        BUILD_MCU
        COMMAND buildMcu.cmd
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    )
    set_target_properties(BUILD_MCU PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
endif()

参考文献

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    相关资源
    最近更新 更多