53

I have a script that sets all variables needed for the cross-compilation. Here is just part of it :

export CONFIG_SITE=~/workspace/eldk-5.4/powerpc/site-config-powerpc-linux
export CC="powerpc-linux-gcc  -m32 -mhard-float --sysroot=~/workspace/eldk-5.4/powerpc/sysroots/powerpc-linux"
export CXX="powerpc-linux-g++  -m32 -mhard-float --sysroot=~/workspace/eldk-5.4/powerpc/sysroots/powerpc-linux"
export CPP="powerpc-linux-gcc -E  -m32 -mhard-float --sysroot=~/workspace/eldk-5.4/powerpc/sysroots/powerpc-linux"
export AS="powerpc-linux-as "
export LD="powerpc-linux-ld  --sysroot=~/workspace/eldk-5.4/powerpc/sysroots/powerpc-linux"
export GDB=powerpc-linux-gdb

If I do source environment-setup-powerpc-linux, all environment variables are imported into the current shell session, and I can compile my example.

Is it possible to import these variables in cmake? If yes, how?


A bit more details :

  1. I am using ELDK v 5.4, and it's install script generates a script which sets all environment variables
  2. I found this tutorial, which explains how to manually set for cross-compilation, but not how to use the script, which sets everything
  3. if I call the script before setting cmake, all works fine, and I can cross-compile, but I'd like that cmake calls the script
BЈовић
  • 62,405
  • 41
  • 173
  • 273

2 Answers2

99

Reading through the cmake quick start, you can specify variable on a command line:

cmake -DVARIABLE1=value1 -DVARIABLE2=value2 ...

Otherwise, set command in the cmake script is probably what you want, see the reference manual. To set the environment variable PATH, do:

set(ENV{PATH} "/home/martink")

To set normal variable, do:

set(variable "value")

Not sure which ones you have to set, probably the environment ones.

That said, setting environment variable prior to calling cmake is often the easiest solution to solve the problem. If you want a cross-platform way to do this that doesn't depend on the syntax of a specific shell to set environment variables, there is the cmake -E env command.

starball
  • 20,030
  • 7
  • 43
  • 238
Tomas
  • 57,621
  • 49
  • 238
  • 373
  • 11
    set(ENV{PATH} "/home/martink") does this work for anyone? Its not working in mine – Pritesh Acharya Mar 06 '14 at 08:56
  • 6
    @PriteshAcharya There is a typo, type set($ENV{PATH} "/home/martink") – Jean Davy Mar 14 '15 at 22:37
  • 4
    @JeanDavy I don't think that's a typo - set($ENV{PATH} "/home/martink") will put the current value of PATH where you specified $ENV{PATH} as the variable name, and so it won't set what you think you're setting. I just did this myself by accident! A more usual setting of path would be set(ENV{PATH} "/home/martink:$ENV{PATH}") and that's where the '$' would be necessary. – J.Churchill Apr 08 '15 at 19:03
  • excuse me, but in what file should I add that set(...) command? I see some *.cmake files and CMakeFiles directory and a Makefile from where I build.(the build directory) – Chan Kim Jul 15 '16 at 06:46
  • 1
    @PriteshAcharya yes, for me it works (CMake v3.7). (I am confirming just in case that anyone cares, as it's already 3 years since the first comment) – lef Jun 02 '17 at 11:16
  • I updated to cmake v3.7, and this did not work for me. In fact, I also tried https://stackoverflow.com/questions/35029277/how-to-modify-environment-variables-passed-to-custom-cmake-target I tested it by doing cmake -E env ENV{PATH}=${PATH}:~/source/new/path/to/add export PATH=${PATH}:~/source/new/path/to/add which returned "No such file or directory" – txs Mar 19 '18 at 22:08
  • It seems that what some of you wanted is `cmake -E env`, which makes set variable available to child process: https://stackoverflow.com/a/64823115/714907. – Pugsley Nov 13 '20 at 15:00
  • Took me a long time to see you need to put a D before the variable name. Then' the name is without the D. – Chen Peleg Jul 01 '22 at 09:26
6

The only way to set a compiler and flags to do cross-compilation reliably with CMake is with a toolchain-file as done in the tutorial you have found.

When we faced the same issue you have (a toolkit which produces a script so set the compile-environment) we changed the toolkit in a way that it produces a toolchain-file along with the script.

In reality a cmake-toolchain-file does not change that often. The basic flags used for the target are fixed quite early in a project - normally. And with CMake's CMAKE_BUILD_TYPE you can switch between Debug and Release compilations without changing the toolchain-file.

If you have different targets to support, create different toolchain and use the out-of-source-build with CMake.

EDIT: One thing you could do is to invoke cmake with the -D-argument setting the variables you want to and having sourced your script before:

source environment-setup-powerpc-linux
cmake -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX etc

The result will be identical as to having used a toolchain-file.

Patrick B.
  • 11,773
  • 8
  • 58
  • 101
  • so, does it mean there are no ways to do what I wanted? Although it doesn't change often, it does change. Then someone has to not forget to convert that script into cmake rules. – BЈовић Jan 12 '14 at 18:05
  • 1
    In the current way cmake is doing things you cannot simply tell cmake to import a script like you have it. Of course you can create a wrapper-script which transforms you script into a toolchain-file, but this is still work you have to do. – Patrick B. Jan 18 '14 at 11:22