Help with packaging a test suite + main project together

I have a project where I would like to generate 2 ZIP archives using CPack.
The first is straightforward packaging of an executable and supporting files which is already working. The second package I am trying to build would include everything from the first plus a test suite. The test suite is using ctest, and is basically a series of python scripts which run the main executable on different input files and parameters.

I have added the tests as a component like so:

cpack_add_component(Tests DEPENDS ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})

along with various install(... COMPONENT Tests) commands, and I am able to build a test archive.
But my problem is that this test archive does not include the main executable files like I wanted.

Is there some way to get CPack to do what I want in this case, or any kind of workaround if CPack is not really designed to work this way?

Part II:
This is less crucial, but I’m also wondering if there are any specific commands or special variables that facilitate installing/packaging ctests in any way. This is specifically for a cross compiled target, where the build environment can be a lot of work to set up, so the whole test suite bundling is meant to be a convenience for users on that target platform who may want to try the tests. I realize it is probably a rare usage case so I’m not too surprised if the answer is simply “no”. The implementation I’ve worked out, as it sits now, just feels a bit messy with a lot of file(GLOB_RECURSE) feeding into the install commands.

No, not really. CTest generates code that is “tied” to the build tree. The way I would suggest to do this is to have the test suite support finding an existing install and then configuring and adding tests that use the existing install. Of course, this assumes the target machine supports running CMake, but that’s probably easier than getting it to compile anything for itself at least.

There was a thread on here recently seeking something similar. But I think that if the above suggestion works, you might not need this?

I have changed my goal to something which I thought would be more flexible/easily done.
What I would like to do is have an NSIS installer which does not include the “Tests” cpack component.
And a single ZIP file which does include Tests + default component.

I have been pouring over documentation for over a week, only to become more and more lost about what anything means. This is actually driving me insane. I’ve somehow ended up with the packaging configuration more broken than before.

Hardly any of the dozens of seemingly redundant cpack settings seem to make a single difference.

  • CPACK_NSIS_COMPONENT_INSTALL ON or OFF does nothing.
    The generated installer always shows the user a component selection screen with the choice to check or uncheck the “Tests” component.
  • set(CPACK_COMPONENT_Tests_HIDDEN TRUE) does nothing
  • NSIS ignores CPACK_COMPONENT_<compName>_DISPLAY_NAME and CPACK_COMPONENT_<compName>_DESCRIPTION, and only goes by <compName>
  • If I set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "Foo"), then why does “Unspecified” still exist as an empty component?:
Pack: Create package using NSIS
CPack: Install projects
CPack: - Install project: MyProject []
CPack: -   Install component: Foo
CPack: -   Install component: Tests
CPack: -   Install component: Unspecified
  • It seems that every CPACK_* variable needs to be set before include(CPack), or it won’t pick up any of those settings. So you should put the include at the end of your CMakeLists.txt right?
    Nope! It can’t go before any cpack_add_component commands because that function hasn’t been defined yet. So you can only add a component after you’ve been referring to it all your installcommands? Is that right? The required order of definitions is confounding.
  • How many other settings are secretly very sensitive to the order in which they are placed in your CMakeListst.txt, in relation to other very specific commands?

By the way, what happens when you add_subdirectory(tests), and you want to call cpack_add_component from that tests/CMakeLists.txt file?
I guess you have to:

  1. Have your top level CMakeListst.txt call all add_subdirectory commands BEFORE calling include(CPack).
  2. Have your subdir’s tests/CMakeLists.txt setup all of its component’s CPACK_* variables, etc. before calling include(CPack). Then it can add its component cpack_add_component immediately after?
    What does it even mean to have included CPack twice now (with regards to variables being set in time, etc.)?

Another huge mystery to me is what is intended scope of the file CMAKE_PROJECT_CONFIG_FILE.
Are you only allowed to read/write variables that start with CPACK_? Wouldn’t it be evaluated after include(CPack) processes all those CPACK_ variables?
I tried to conditionally set CPACK_INSTALL_CMAKE_PROJECTS based on which CPACK_GENERATOR was set in this file:

if(CPACK_GENERATOR MATCHES "NSIS")
  set(CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME};/")
 ...

But all CMAKE_* variables are empty from this file. Is it even possible to pass any information from config time to this file?

Finally: Is it good or bad practice (or completely inconsequential) for with tests\CMakeListst.txt to have its own project command, when it is added from the top evel project, as add_subdirectory(tests)?

Yes, the project already uses some support scripts which do something similar. However, it is just replacing various paths in a pre-packaged CTestTestfile.cmake after finding the local binary paths etc. I suppose the test config/build could be done entirely on the target machine as you say, but I’d rather not completely rewrite those scripts which are already working.

Anyways, I was able to get a working solution using the CMAKE_PROJECT_CONFIG_FILE. I realized from reading another thread here that I guess the preferred/recommended way to pass config data to files like that is to use configure_file.

Sorry if my last post was overly negative / ranting, but I really was at my wits end and just feeling completely lost and frustrated.
And although I now have a solution to my main issue, I am still genuinely very confused about every other point I mentioned there (aside from the CMAKE_PROJECT_CONFIG_FILE “scope” issue).
So I would greatly appreciate any explanations that can be given to help me understand what was going on there.

For example, is it just that NSIS generator does not make use of many of those variables I mentioned?

I’m not sure myself. CPack is one of those things I poke at until it works and then leave it alone. There was another thread here recently asking about CPack and components (ZIP or DPKG-based IIRC) that might have some relevant info.