4

I am using Linux, CMake, and Conda, which is a package manager that edits $PATH as a way to switch between "environments." This means when I run a special command in Conda, $PATH points to a different compiler. $CONDA_PREFIX is also changed.

By default, CMake is not sensitive to these changes. I would like it to be. Specifically, I want CMake to automatically regenerate all Makefiles when a different GCC is found in $PATH, or alternatively when $CONDA_PREFIX has changed since the last explicit cmake invocation. This regeneration would be similar to what CMake does when you edit the top-level CMakeLists.txt file - the next time you run make it regenerates everything.

How can I do this in a simple way using CMake?

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Natural approach seems to create new build tree for every additional "environment". – Tsyvarev Sep 22 '16 at 07:24
  • @Tsyvarev: I understand what you mean but that doesn't solve the problem--if a user accidentally is in the wrong (mismatched) Conda environment vs CMake build tree, the build may be defective. I am trying to make sure builds are never mismatched. – John Zwinck Sep 22 '16 at 08:07
  • 2
    You may add target (via `add_custom_target`), which will check that build tree corresponds to current environment. For mismatched builds target could simply fails with appropriate message. Forcing CMake to rerun (see, e.g., [that mail](http://public.kitware.com/pipermail/cmake/2010-November/040777.html)) could be useful if you need *partial* reconfiguration. But as compiler is changed, you probably need to discard all compiler-related caches, which is actually a clean configuration (`cmake` call on clean build directory). – Tsyvarev Sep 22 '16 at 08:31
  • Looks like a CMake's misfeature. It's supposed to be a high-level build tool, but leaves it to you to deal with such a trivial changes as compiler commands explicitly depending on environment, or the compiler itself. – Victor Sergienko Apr 24 '19 at 17:09

2 Answers2

2

I ended up not needing a workaround code today, but here's an idea. It's not general - it requires you to explicitly specify the variables your build depends on.

  • Create a CMake wrapper script that receives the names of environment variables that affect my specific build.
  • echo them all in VARIABLE=value format into a ${CMAKE_CURRENT_BINARY_DIR}/buildvars.environment file. Only do it if the file doesn't exist or if its content is different.
  • When calling cmake, add cmake -DCMAKE_CONFIGURE_DEPENDS=<build_direcotry>/buildvars.environment to trigger reconfiguration if the file is newer than build configuration.

References:

Related question: How to trigger a CMake reconfigure when the output of a command changes

Victor Sergienko
  • 13,115
  • 3
  • 57
  • 91
0

In short, the generated build directory should no more depend on environment.

if a user accidentally is in the wrong (mismatched) Conda environment vs CMake build tree, the build may be defective.

If you've used find_program() command to determine paths to all tools you are using then this would never happen. Using full path for every tool and having a build dir for each environment setup is the preffered way to handle this problem.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • CMake totally leaves the build environment management to the user, but dictates how we should do it ("thou shan't depend on environment variables"). Probably that downvote could be an upvote if you prepend the answer with "CMake's (bad) idea of environment management is..." – Victor Sergienko Apr 24 '19 at 17:14