Setting a NEW environment variable with CMake? - cmake

I am trying to set a new environment variable with CMake. Said environment variable does not exist prior to calling cmake and I don't need it to exist after my script has run. The problem is that I can modify existing environment variables, but I cannot create a new environment variable.
Here's a test I did:
$ echo $LD_LIBRARY_PATH
No output.
In CMake script:
message(STATUS "$ENV{LD_LIBRARY_PATH}")
No output.
In shell:
$ echo $LANGUAGE
en_CA:en
In CMake script:
message(STATUS "$ENV{LANGUAGE}")
en_CA:en
Obviously I can display an existing variable without issues, the problem is when I try to add a new one. Here's the second test I did:
In CMake script:
set(ENV{'LD_LIBRARY_PATH'} "potato")
message(STATUS "$ENV{LD_LIBRARY_PATH}")
No output
In CMake script:
set(ENV{'LANGUAGE'} "$ENV{LANGUAGE}:potato")
message(STATUS "$ENV{LANGUAGE}")
Output:
en_CA:en:potato
This is problematic to me. How can I go about setting a NEW environment variable?

As #Tsyvarev pointed out, there should not be quotes around LD_LIBRARY_PATH in set(ENV{'LD_LIBRARY_PATH'} "potato")

Related

How to use CMake cached variables inside subprocess called by custom target?

My project contains a custom target which generates some output via .cmake script. It looks like this:
add_custom_target(TargetName
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/script.cmake
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/generated/output
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
VERBATIM
)
But now I want to set come cache variables inside the script. I tried doing like that:
message("MY_CACHE_VARIABLE = ${MY_CACHE_VARIABLE}")
set(MY_CACHE_VARIABLE "VALUE" CACHE INTERNAL "")
And I faced with the problem that cache variables are not saved. It always prints me empty output:
MY_CACHE_VARIABLE =
I already tried setting working directory as CMAKE_BINARY_DIR, or passing CMAKE_BINARY_DIR of the last argument of cmake command, or passing -B ${CMAKE_BINARY_DIR} or -C ${CMAKE_BINARY_DIR}/CMakeCache.txt as arguments and etc. None of these worked.
So is there any way to reuse existing cache inside CMake subprocess or I just should write my own cache inside the script?
You have to distinguish between running CMake to generate build files (for Make, Ninja, etc.) and running CMake in script mode:
Script mode simply runs the commands in the given CMake Language source file and does not generate a build system. It does not allow CMake commands that define build targets or actions.
-- cmake-language(7)
No configure or generate step is performed and the cache is not modified.
-- cmake(1)
So in script mode (-P), CMake is not aware of the cache or any variable/target/etc. defined in your regular CMakeLists.txt files. It is more similar to executing a bash/shell script than to processing a "usual" CMakeLists.txt.
But don't worry, there is still a solution to your problem. You can simply pass your arguments as -D options to your script:
add_custom_target(TargetName
COMMAND ${CMAKE_COMMAND}
-DMY_VAR="..."
-DANOTHER_VAR="..."
-P ${CMAKE_SOURCE_DIR}/cmake/script.cmake
...
)
Note however:
If variables are defined using -D, this must be done before the -P argument.
-- cmake(1)

set cmake variable from custom command before every build

How can I run a custom command before every build and pass the result to a cmake variable?
I know I can do that on the terminal for example
cmake -DMY_VARIABLE=$(echo FOOBAR)
But I'd like to integrate that in my CMakeLists.txt using
add_custom_command(TARGET ${MY_APP} PRE_BUILD ...).
Then I want to pass that variable as a compile definition.
add_cmpile_definitions(MY_DEFINITION="${MY_VARIABLE}")
I found something similar in the command execute_process which has an argument OUTPUT_VARIABLE that stores the output of the command into that variable. But I think it doesn't run before every build.

CMake cannot find environment variables within WSL

Cmake cannot find an environment variable defined in /etc/profile from within WSL.
I've tried putting the variable in other file such as /etc/environment but could not get it to echo in WSL. Finally using /etc/profile I get an echo.
/etc/environment
TEST="/some/path"
echo $TEST
>>
/etc/profile
TEST="/some/path"
echo $TEST
>>/some/path
My CMakeLists.txt has the following lines:
set(TEST $ENV{TEST})
message(STATUS "Output: ${TEST}")
When building, it outputs
>>Output:
This question had a similar issue : Here. Nonetheless I've already tried using bash.exe -i. Also tried setting the next line in my CMakeLists.txt
set(ENV{BASH_ENV}"~/.bashrc")

How to set the CMAKE_PREFIX_PATH?

I have a problem with the global environmental variable CMAKE_PREFIX_PATH. I already set this and I can see it is set when I type env, but when I run cmake . to build HipHop, it tells me that the variable isn't set.
Is there a way I can hard-code this into the makefiles?
Try to run cmake -DCMAKE_PREFIX_PATH=/your/path .
CMAKE_PREFIX_PATH works as a build directive, rather than as an environment variable. Moreover, you may perform the build into a dedicated temporary directory (it's cleaner, because when done, you can remove that temporary directory and you get back a clean pristine source tree).
$ mkdir -p tmpbuild && cd tmpbuild
$ cmake -DCMAKE_PREFIX_PATH=~/deliveries/hiphop ..
$ make install
$ cd ..
On MacOS it's different. I had to use:
make -i CMAKE_PREFIX_PATH="/the/path"
This was while installing VMQT, and this error was shown:
CMake Error at CMakeLists.txt:87 (find_package): By not providing
"FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has asked CMake
to find a package configuration file provided by "OpenCV", but CMake
did not find one.
Could not find a package configuration file provided by "OpenCV"
with any of the following names:
OpenCVConfig.cmake
opencv-config.cmake
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
"OpenCV_DIR" to a directory containing one of the above files. If
"OpenCV" provides a separate development package or SDK, be sure it
has been installed.
Used this to solve it: make -i CMAKE_PREFIX_PATH="/opt/homebrew/Cellar/opencv/4.6.0_1/lib/cmake/opencv4/"

How to set PATH environment variable in CMake script?

I want to build my sources by Mingw compiler which in not placed on my system PATH.
I tried this in the beginning of my script:
set(Env{PATH} "c:/MyProject/Tools/mingw/bin/" "c:/MyProject/Tools/mingw/msys/1.0/bin/")
And this:
set(CMAKE_PROGRAM_PATH "c:/MyProject/Tools/mingw/bin/" "c:/MyProject/Tools/mingw/msys/1.0/bin/")
set(CMAKE_LIBRARY_PATH "c:/MyProject/Tools/mingw/bin/" "c:/MyProject/Tools/mingw/msys/1.0/bin/")
set(CMAKE_SYSTEM_PROGRAM_PATH "c:/MyProject/Tools/mingw/bin/" "c:/MyProject/Tools/mingw/msys/1.0/bin/")
set(CMAKE_SYSTEM_PREFIX_PATH "c:/MyProject/Tools/mingw/bin/" "c:/MyProject/Tools/mingw/msys/1.0/bin/")
The first variant doesn't work at all. A suggest that I can't overwrite the value of the environment variable in CMake script.
The second script finds my mingw compiler, but catches the error while running gcc (can't find libgmp-10.dll which needs by gcc). This is because the PATH variable is not set to my Mingw.
CMAKE_SYSTEM_PROGRAM_PATH is not meant to be modified, use
LIST(APPEND CMAKE_PROGRAM_PATH "c:/MyProject/Tools/mingw/bin/" ...)
You might approach it as if it were a cross compiling toolchain, even if you're not cross compiling from Linux to Windows as in this example:
http://www.vtk.org/Wiki/CmakeMingw
After you follow that guide you set the mingw toolchain at the command line when calling cmake:
~/src/helloworld/ $ mkdir build
~/src/helloworld/ $ cd build
~/src/helloworld/build/ $ cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-mingw32.cmake
then if you're using this a whole lot you can make an alias to limit typing in that ugly -D every time you want to regenerate makefiles:
alias mingw-cmake='cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-mingw32.cmake'
Write a script file to start CMake.
On Windows make a batch file:
#echo off
set path=c:\MyProject\Tools\mingw\bin;c:\MyProject\Tools\mingw\msys\1.0\bin
"C:\Program Files\CMake 2.8\bin\cmake-gui.exe"
On Linux make a bash script:
export PATH=$PATH:/your/path