5

We're writing an application for an embedded ARM/Linux device. Development is performed on a Windows PC, using a crosscompiler, Eclipse and Ninja. CMake currently can create the build scripts that work well for the intended purpose.

We have unit tests that run on the embedded device attached to the net, once the project is pushed (over Git) to the server.

We're trying to implement unit tests, that would run on the PC, before we try them on the device. That means building natively, using MinGW GCC - of course we can't launch the ARM Linux executables on the PC.

Even if we switch the toolchain, launching CMake to rebuild the ruleset for Ninja, or create two build directories, one for PC, one for ARM, the problem remains that CMake will try to run a test executable, and later during build, unit tests will be attempted on the ARM build.

How can we configure the builds (through CMake) to create both - and not attempt to run the crosscompiled ones on the PC?

3
  • You could check for CMAKE_CROSSCOMPILING. See e.g. How to instruct CMake to use the build architecture compiler?. Commented May 24, 2016 at 11:27
  • Could you please add a CMake code example of how you are doing the "run a test executable"? Did you add it as add_custom_command(TARGET ... POST_BUILD ...) and/or with add_test()? I think in both case just putting a if (NOT CMAKE_CROSSCOMPILING)|endif() around this particular command should do the trick. Commented May 25, 2016 at 7:53
  • @Florian: In the top-level CMakeLists.txt there's just ADD_SUBDIRECTORY(UnitTests). Then in the directory there's ExternalProject_Add(GMockDownload GIT_REPOSITORY "https://github.com/google/googletest.git" ... which does the rest of the work. Yes, if (NOT CMAKE_CROSSCOMPILING) helps here. It seems two separate build dirs and launching cmake twice is the way. Not optimal, because I'm getting two Eclipse projects instead of merely two Build Configurations. Commented May 25, 2016 at 8:05

1 Answer 1

3

I have a similar setup in my projects (building from the same sources a simulator, unit tests, and the target binary), and you can check for CMAKE_CROSSCOMPILING to differentiate your two use cases. Just putting

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

around the particular commands should do the trick.

And you need to have two binary output directories. CMake does not allow to mix toolchains in one directory.

But you don't need to have two IDE projects. In my projects:

  • I've added all sources - incl. the "cross-compile only" files - into the library/executable targets
    • I'm marking them as "excluded from build" for the PC only variants
    • So all sources will show-up in one IDE project (e.g. for searching through the code)
  • I've added the cross-compiling call as a custom target
    • I've removed it from the default build, but you can explicitly start it from your IDE
    • In my case it's an external script, but you can also pass the necessary calls directly in COMMAND parameters
    • You could even use another ExternalProject_Add() to include your own project for cross-compiling

Here are some code snippets for this kind of approach:

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() 

References

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.