New command: cmake --run which appends LINK_DIRECTORIES to PATH/LD_LIBRARY_PATH and runs executable
PROBLEM
There's a very common workflow that is currently more difficult than it should be. Build and Run
/ Build and Debug
For targets which link with non-trivial numbers of shared library dependencies, and when the dependencies are spread out in different directories, it takes significant CMake configuration to gather all the paths to those libraries into the target property LINK_DIRECTORIES
for those targets. However, once this property has all the paths, a target can be linked successfully into an executable.
The next most common thing for developers to do with such an executable is to run it or debug it. IDE's often consolidate these two steps into a single button. In order to run executables with non-trivial numbers of shared library dependencies, and when the dependencies are spread out in different directories, developers must take significant configuration to gather all the exact same library paths (not precisely correct, see edit #4 (closed)) into environment variables: PATH
/ LD_LIBRARY_PATH
. Since all these paths are known to CMake via the LINK_DIRECTORIES
property, I believe CMake could facilitate this workflow.
CONCEPT FOR IMPLEMENTATION
CMake exposes cmake --build
which is a build-system agnostic way to "build targets". This is possible because cmake knows what build system it generated and how to invoke it. This is nice for IDE's and other tools to be able to invoke the build system without knowing which build system it is.
CMake could expose cmake --run
which would become a platform-agnostic way to "run targets", which takes the LINK_DIRECTORIES
property used to link the target, converts it to a properly formatted string for the current platform, and appends that string to the appropriate environment variable for the platform (PATH
/ LD_LIBRARY_PATH
).
Additionally, there's an opportunity to add a new category of target properties for executable: "Run Properties". This would enable users to define and further manipulate things like Working directory, command-line arguments, and further customize PATH
/ LD_LIBRARY_PATH
.
EXISTING WORKAROUNDS
This is such a common workflow, I believe that many CMake users have invented and implemented a variety of mechanisms and strategies for achieving a similar effect. I am unaware of any such strategies, so I would very much like to hear from other people about what they currently do in this regard. Perhaps there are well-known patterns that solve this problem and don't require a feature, and that would of course be best. Any feedback welcome.
EDITS
-
macOS has the concept of
RPATH
which is unique and means the environment variable component of this feature applies less (or not at all tomacOS
). However, the agnostic feature of "run the binary output by the target without needing to know the name or output location of the binary" still seems relevant. As does "run configuration", with working directory, and command-line arguments. -
Another big "value add" here is that it enables defining the run configurations in CMake, which makes it platform-agnostic, build-system agnostic, and IDE agnostic way. Currently, IDE users have to define "Run Configurations" in an IDE-specific way, and in many cases, developers all have to setup their own run configurations (redundant work).
-
I should also reference the
virtualrunenv
feature of the package manager Conan which was some of the inspiration of this feature request: https://docs.conan.io/en/latest/mastering/virtualenv.html#virtualrunenv-generator This feature demonstrates that this is a common enough problem which has some demand for a solution, and provides a decent example of what would be the minimum required functionality surroundingPATH
/LD_LIBRARY_PATH
. -
It has been pointed out (correctly so) that the lib directories for build-time linking are not necessarily the "exact same" directories needed for runtime linking on Windows (and potentially other platforms). For this reason, the suggestion of a new
RUNTIME_DIRECTORIES
property was suggested and seems logical. Again, I point to the conanvirtualrunenv
generator for reference on the conditional behavior desired (see quote below). Of note, the term (bin
folder) in Conan would be equivalent to the suggestedRUNTIME_DIRECTORIES
in CMake. The term (lib
folder) is equivalent toLINK_DIRECTORIES
in CMake. Also, I would suggest a sensible default for targets which have noRUNTIME_DIRECTORIES
defined would be to useLINK_DIRECTORIES
, which will be the desired behavior a significant percentage at the time.
Append to PATH environment variable every bin folder of your requirements. Append to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment variables each lib folder of your requirements.