Evaluate command only when running tests - cmake

I need to check if the mpirun command is present and exit with an error message if not present, but only when the user tries to run the tests. When just building the main library or executable, this command need not exist.
More generally, how to execute a cmake script when a specific target is invoked? I.e., only when I type build some_target, cmake should start searching for certain environment variables, commands, etc.
EDIT
Workaround. In my case, the custom target is dependent on an executable, and for the executable I can use add_custom_command with the PRE_LINK flag. The custom command then displays an error message and calls exit 1 if necessary and only when the custom target is invoked. However, the PRE_LINK option only works on real targets such as executables and libraries, and not for a custom target in general, so I'm still curious how to solve this for the general case.

Related

How to run a post build script in CMAKE, regardless if any object fails?

I'm trying to generate a compiler error and warning report post-build. This is all in a CMake Environment.
So I created a script, and tied to executable post-build.
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND python.exe genReport.py"
)
however this won't execute if not all STATIC Librarys are generated, because then the executable can't link them.
So I thought now I needed to create call same custom command post-build per library.
However, we also create objects before Libraries, and objects can't have a post build command.
All I'm trying to do is always run a script at the end of a make all. Whether executable is built, or any library fails, or any object fails to compile.
Is there a way to always run a post build script?

How to incorporate unittest in cmake project structure

I'm working on an embedded project. As a part of this project, I have unit-tests that use gcc and Gtest. The question what is the best to approach to incorporate these unit-tests. My current implementation is that I have a different build type called unittest. I have a clause of CMAKE_BUILD_TYPE and decide which sources to use which targets to create. I see this is not a good design and this screws up multiconfiguration gnerators. What could be the elegant solution for this?
Thanks in advance for answering.
Create separate executables for testing and use ctest:
add_test to add the combination of executable+command line parameters as a test ctest runs and enable_testing() in the toplevel CMakeLists.txt.
This allows you to simply run ctest in the build dir and you can pass a configuration to test using -C command line option.
add_executable(MyTest test.cpp test_helper.cpp test_helper.h)
target_include_directories(MyTest PRIVATE .)
target_link_libraries(MyTest PRIVATE theLibToTest)
add_test(NAME NameOfTest COMMAND MyTest --gtest_repeat=1000)
enable_testing()
Running ctest from the build directory runs a test named NameOfTest. For multi configuration generators you simply specify the configuration to test with the -C command line option
ctest -C Release
Of course you can use add_test multiple times to add different test executables or the same test executable with different command line options.
Furthermore I recommend figuring out a way of storing results in a file, since this makes via the test parameters, since ctest's output probably won't do the trick. I'm not familiar enough with gtest to give advice on this.
Btw: ctest treats exit code 0 as success and any other exit code as failure, but I guess gtest produces executables that satisfy this property.
If you don't necessarily want to build the tests at the same time as the rest, you could exclude them from all, possibly adding a custom target that depends on all of the unit tests and is also excluded from all to allow building all of them at once.
You could also use a cache variable to toggle testing on and off:
# enabled via -D TEST_MY_PROJECT:BOOL=1 parameter for cmake
set(TEST_MY_PROJECT 0 CACHE BOOL "enable tests for my project")
if (TEST_MY_PROJECT)
# testing setup goes here
endif()

Waiting for targets in a CMake build

I think I do have a CMake order/parallelism problem.
In my build process, I need to build a tool which is then later used by some other target. This tool is a separate project with a CMakeLists.txt file like this:
project (package-tool LANGUAGES CXX)
set (SOURCES package_tool.cpp)
...
Later in the build, this top level target is referenced by some other target:
...
add_custom_command (OUTPUT "${DST_FILE}"
COMMAND ${PACKAGE_COMMAND} "${DST_FILE}"
COMMAND package-tool.exe -e "${DST_FILE}"
DEPENDS ${PACKAGE_DEPENDENCIES} package-tool)
...
I use ninja for building and the dependencies (ninja -t depends) are looking correctly. Also, the build commands (ninja -t commands) are making sense. But: From time to time, the build fails. The message does not make sense, it reads:
This version of package-tool.exe is not compatible with the version
of Windows you're running.
Because the build runs in parallel (32 processes) I suspect that the package-tool target is not completed when the generated exe is being used in the second target, which might lead to this confusing error message. Again, most of the time the build succeeds but every 10th or 20th run, it fails with that message.
So now my question is:
Is there a way to wait for a tool/target having been finished building in a parallel build in CMake/Ninja ?
Or how do I handle the task of building build tools in the same build process correctly ?
Thank you in advance !
Actually depend on the executable file and run the executable file, not the target. Don't concern yourself with any .exe suffix. Also better don't assume add_custom_command will be run in CMAKE_RUNTIME_OUTPUT_DIRECTORY - if you depend on specific directory explicitly set it with WORKING_DIRECTORY.
add_custom_command (
OUTPUT "${DST_FILE}"
COMMAND ${PACKAGE_COMMAND} "${DST_FILE}"
COMMAND $<TARGET_FILE:package-tool> -e "${DST_FILE}"
DEPENDS ${PACKAGE_DEPENDENCIES} $<TARGET_FILE:package-tool>
)

Cmake apparently ignoring CMAKE_BUILD_TYPE?

So I'm using CMake for a project.
It consists of a set of shared libraries linked to one executable. All are generated in the project (there are no external targets). Each sub project lives in its own directory, with its own cmakelists file.
So I make an out-of-source build, taking care to set CMAKE_BUILD_TYPE to Debug, and run cmake, and then make. I use GNU make 3.81, GCC 4.8.1, binutils 2.23.2 and CMake 3.2.3 on a Windows box using MSYS/MINGW.
The problem is that, when I load this executable in gdb (version 7.6), place a breakpoint on a function from one of the shared libraries, and then try to single step, gdb skips the whole function saying it has no line number information.
According to my understanding, line number information is a part of the debugging information, so I expected this to be generated during the compiling process (as per the CMAKE_BUILD_TYPE) which it didn't, so I would like to know how I can get CMake to generate this line number information properly (that is, without manually adding compiler-specific options in the cmake files, although I would take that if it's the only solution).
I've tried setting CMAKE_BUILD_TYPE from the command line (when invoking the cmake utility), inside the cmakelists, and even by modifying the CMakeCache.txt, and restarting the build from an empty directory with no success. I then made sure that CMAKE_BUILD_TYPE was effectively set to Debug by using the MESSAGE command to print it's value, and it was correctly set to Debug. So then I executed 'make VERBOSE=1' to see if the correct compiler option was added, and found it correctly used the "-g" option (although I would have expected -ggdb, but more on this later). The cmake documentation and Google did not bring me any answers.
My hypothesis is that the -g option only generates basic debugging information (such as the mappings between functions and their memory addresses, and how to access their arguments) whereas -ggdb would generate more in-detail debugging information in a gdb-specific format, including said line number informations), but a troubling fact is that, when running the executable in gdb, functions defined inside the executable do have line number information, only the shared libraries don't, hence my confusion.

How to add dependency in cmake targets

I have defined a custom target in cmake. I now want to ensure that this target is only build when the cmake target test was executed. How can I achieve this.
Lets say that I have a target make coverage which should depend on the target make test to be called before, or call make test before executing.
How can I define this behavior in cmake?
Here my code that did not work as expected. I want to achive that make coverage depend that make test has to be called before.
ADD_CUSTOM_TARGET(
coverage COMMAND /bin/bash ${LIBPIPE_BINARY_DIR}/cmake/scripts/coverage.sh
DEPENDS test
)
You cannot add a "DEPENDS test" clause. The pre-defined/built-in targets in CMake (all, install, package, test, clean) are not available as actual targets in a CMakeLists.txt file. So you cannot express a dependency on a built-in target.
There is an outstanding feature request in the CMake bug tracker for this feature, but it is not yet implemented. See http://public.kitware.com/Bug/view.php?id=8438
However, you could change your command for your custom target, though, such that it calls "make test" first, and then runs your coverage command.
The CMake FAQ states that the add_custom_command/add_custom_target commands, which define custom targets, have a DEPENDS parameter.
Edit
This will not work for built-in target test because of following feature request.
But you always can create custom target check or whatever as suggested in CMake FAQ