2

Suppose one wants to use the environment variable MY_VAR in CMake. This may be accomplished simply by using set(myVar $ENV{MY_VAR}).

But what if MY_VAR contains escape characters, say MY_VAR="/path/with/escaped\ chars"? CMake treats \ followed by a white-space as two individual characters, instead of a single character (white-space). In other words,

# CMakeLists.txt

set(myVar $ENV{MY_VAR})
message(${myVar})

prints /path/with/escaped\ chars, not /path/with/escaped chars. How does one get CMake to recognize escape characters in environment variables? Are there any best practices regarding this problem? I'm running CMake on macOS, but hope that there is a platform independent solution...

Context: Cmake is used to configure a C++ framework before installation. The MY_VAR contains a path provided by the user that is used (a) in a Makefile to set the CMAKE_PREFIX_PATH and (b) by Cmake to configure_file a configuration file for a python script that is required by the framework.

mkl
  • 392
  • 2
  • 13
  • After trying it, it doesn't appear that CMake applies the escape character processing for `$ENV{}` variables, but it does when just using `set(myVar /path/with/escaped\ chars)`. Can you provide some more context for what you're using the path in `MY_VAR` for? For example, if you are trying to use a path containing spaces, you could wrap the path in quotes `"` after it is read in through the environment variable... – squareskittles Sep 30 '19 at 17:59
  • Thanks for commenting! I've added context to the question. I would rather not ask the user not to use escape characters and always use double quotes. – mkl Sep 30 '19 at 21:24
  • I should add that the question "should" have an answer regardless of the context. There must be a way to control how Cmake deals with escape characters in environment variables, right? – mkl Sep 30 '19 at 21:30
  • It is my understanding that CMake copies the backslashes (\\) from environment variables verbatim, as they are commonly used as path separators (e.g. on Windows). – squareskittles Sep 30 '19 at 22:08
  • `MY_VAR="/path/with/escaped\ chars"` set's MY_VAR with two distinct characters slash and space, it's the same as `MY_VAR="/path/with/escaped\\ chars"` but it really depends on your shell. What environment are you on? Windows? Linux? I think you want `MY_VAR="/path/with/escaped chars"`. The slash is there in the variable value, so it get's printed out properly. – KamilCuk Sep 30 '19 at 23:41
  • I'm using macOS, but looking for a platform independent solution. The problem with `MY_VAR="/path/with/escaped chars"` is that `MY_VAR` can then no longer be used properly in the shell. I guess the Cmake behaviour is as expected. Apparently it's simply a bad idea to use the same environment variable in shell and Cmake context. – mkl Oct 01 '19 at 11:53
  • You could add a check for this: `if(UNIX) string(REGEX REPLACE "\\\\" "" myVar ${myVar}) endif()`, assuming there will be no back-slashes in paths in MacOS/Linux environments. – squareskittles Oct 01 '19 at 12:25
  • Yeah, thanks a lot for the help! I get it now: Without the assumption that there be no backslashes in the path, this problem is unsolvable: `export MY_VAR="\\"` and `export MY_VAR="\\\\"` both yield the same `myVar` in Cmake. Therefore, Cmake cannot tell if `myVar` is supposed to be one escaped backslash, or two backslashes. – mkl Oct 01 '19 at 14:56

0 Answers0