3

I created a command-line portable script-based industrialized agnostic build system useful to quickly build several dependent projects while not having to rely on a particular IDE or a build factory. It's agnostic, because it's not based on a single build engine. I founded the first version using cmake, because my projects are mostly C++, but that'll evolve (to include gradle for example or whatever). That's to say, I'm not centered on CMake, it's merely a tool to a goal, easy portable C++ project building. I had BJam in mind formerly and would have kept it if there had been more documentation.

As a result though, I'm very dependent on CMake to perform the build and unit tests. As of today, I realized that tests are built under the 'all' target and run under the 'test' target.

With CMake 2- (and -here for example- a Unix Makefiles generator):

make all  # Build project AND tests
make test # Run tests

With CMake 3+ and any generator:

cmake --build . --target all  # Build project AND tests
cmake --build . --target test # Run tests

I'd like to know if someone would know a way to split the 'build project' phase apart from the 'build tests' phase (also because it feels more natural in my build system to join test building and running tests than the other way around).

Important precision: I don't want to bootstrap the project with one vision or another (by flipping BUILD_TESTING). The idea would be to have 3 stages like:

cmake --build . --target <project>     # 1. Build project only
cmake --build . --target <build_tests> # 2. Build tests
cmake --build . --target <run_tests>   # 3. Run tests

If I choose not to run tests, I could go straight from phase 1 above to installing, but running phase 3 would trigger the previous dependent phases.

Any clue? (If not, I suspect I'll have to ask CMake developers directly...)

Thanks in advance. Regards.

tomoyo255
  • 153
  • 1
  • 8
  • Possible duplicate of [CMake & CTest : make test doesn't build tests](https://stackoverflow.com/questions/733475/cmake-ctest-make-test-doesnt-build-tests) – usr1234567 Sep 26 '18 at 22:30
  • I read this question, which complains that tests aren't built prior to running them if I understand correctly "The problem is CMake does not "understand" that the test I'm willing to run has to be built since it is part of the project." – tomoyo255 Sep 29 '18 at 08:45
  • I've got no such issue. Tests are built and run just fine. However, I'm embarassed that tests are built under the 'all' target, rather than when running unit tests is actually wanted. Professionnally, I happen to work with other tools, like Visual Studio and building the solution never builds tests, whereas running a unit-test would build it. It's a lot more natural. When I build to debug, I don't want to wait for all tests to be built, I want to debug as quick as possible. Only in continuous integration makes it sense to perform every unit tests or when you plan to push, that sort of things. – tomoyo255 Sep 29 '18 at 08:48
  • tomoyo255: Technically, your question **can be divided** into two relatively *independent* problems: 1. How to NOT build tests on "all" target. 2. How to DO build tests before running them on "run_tests" target. From that point of view, the question is "too broad", because it contains more than a single problem. And the question, referenced by @usr1234567, is actually a duplicate for the second problem. But I find your question to be useful *in whole*, and answers "in whole" could help you and many other readers. – Tsyvarev Sep 30 '18 at 10:59

1 Answers1

3

Assuming you choose build_tests target for build test's executables and run_tests target for run them:

  1. Defining targets:

    add_custom_target(build_tests)
    # 'run_tests' triggers 'ctest'.
    add_custom_target(run_tests COMMAND ${CMAKE_CTEST_COMMAND})
    # 'run_tests' implies 'build_tests'
    add_dependencies(run_tests build_tests)
    
  2. Creating test's executables, so they won't be built by default but with build_tests target.

    # Do not build 'test1' by default
    add_executable(test1 EXCLUDE_FROM_ALL ...)
    # 'build_tests' implies (among other things) building 'test1'
    add_dependencies(build_tests test1)
    
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • I tried excluding tests from the 'all' target (EXCLUDE_FROM_ALL). But, they're still built. With the Unix Makefile generator, I can see that all target still triggers unit test building through a makefile dependency. Furthermore, the test high-level target cannot be used anymore with your proposal (I realize you mimicked the target names I used as placeholders). A custom target (distinct from a high-level target as all, install, test...) should be used instead and I assume with the loss of all what the real 'test' target offers. Thanks for the idea anyway. I'll give it some more thoughts. – tomoyo255 Sep 29 '18 at 08:33
  • "I can see that all target still triggers unit test building through a makefile dependency. " - It would be unlikely with `EXCLUDE_FROM_ALL` option in the effect. Or such dependency is caused by some other code. – Tsyvarev Sep 29 '18 at 09:37
  • This doesn't seem to solve the issue, `make test` will not depend on building the tests if they have been excluded, so no tests will be run. I'm really surprised that what the OP wants is not default behavior, currently `make install` triggers building tests, which makes no sense. – definelicht Feb 20 '19 at 13:58
  • @jlicht: 1. My answer assumes that one uses `make run_tests` (not `make test`) for build the tests and run them. This assumption is written in the first sentence. 2. In my snippets the executable `test1` will be built neither with `make` nor with `make install`. As far as I understand from the question post and the comments, the OP wants exactly such behavior, but it won't work for him for some reason. – Tsyvarev Feb 20 '19 at 14:26