CMake/CTest DEPENDS on add_executable or custom_target

195 Views Asked by At

How can I force an add_test() to build an add_executable() or add_custom_target() target before it runs?

I have a very complicated cmake flow because some of my binaries (created with add_executable() on the host GENERATE source code that I use in later add_executable() declarations for a number of cross-compile platforms.

The gist of my question supposes I have a subdirectory of my cmake project containing this...

set(CMAKE_C_COMPILER /path/to/cross-compiler/bin/gcc)
add_executable(foo.elf)
...
add_test(test_foo COMMAND foo_script.sh foo.elf)
set_tests_properties(test_foo PROPERTIES
  DEPENDS(foo.elf) ...)  # Build "foo.elf" before running "test_foo"

I understand about chains of add_test() dependencies possible with FIXTURES_REQUIRED, that allows me to say that one test must run after another test. I don't see any way to express that a test requires that a "target" must be built before running the test.

The code above does not have any errors/warnings with my cmake command, but with ninja it simply acts as if the DEPENDS is not present.

How can I force an add_test() to build an add_executable() or add_custom_target() target before it runs?

To clarify a bit for @user, I cannot have a single "build phase". I need a "first build phase" who's "first generate phase" will create a C file. Then I need a "second build phase" (with a cross-compiler) to create an executable. Then another add_test() to run that executable on a platform.

EDIT:

Okay, I got this working.

For @Tsyvarev, I built a toolchain file for each of my platforms, and I called my "elf" target "elf" with filename "elf". I understand the SUFFIX property could choose a filename suffix, and I used $<TARGET_FILE:elf> everywhere to refer to that file.

I used @KamilCuk's approach. My project used configure_file() to create a totally new cmake project within the build tree of the main project. That project is only responsible for compiling the generated C file into the platform-specific elf file.

The add_test() command is a script that asks the main project to generate the C file, then create the subproject for it, then generate the elf, then the main project runs the test on the platform.

Thanks for your help! As you can tell, I had trouble even asking the right question at the start of this...

1

There are 1 best solutions below

4
KamilCuk On

How can I force an add_test() to build an add_executable() or add_custom_target() target before it runs?

Do exactly that, verbatim. Run the build, then execute your command. You need a script, or executable, that will wrap that in one command. You can for example use bash.

add_test(test_foo COMMAND
   bash
   -c
   "\"$1\" --build \"$2\" --target foo.elf && foo_script.sh \"$3\""
   --
   ${CMAKE_COMMAND}
   ${CMAKE_BINARY_DIR}
   $<TARGET_FILE:foo.elf>
)