How can I use environment variable in conditional compilation?

If i exported an environment variable FEATURE1=1, is it possible to create a define macro using the environment variable value?

#define FEATURE1 getenv("FEATURE1")

For example in other code places I can just use below:

1
2
3
#if FEATURE1 == 1
...
#endif 
Last edited on
Macros are evaluated at compile-time, but environment variable are evaluated at runtime!

You will have to call getenv() in your program, at runtime, to get the value of an environment variable:
https://www.cplusplus.com/reference/cstdlib/getenv/

This will not work within a pre-processor #if for obvious reasons 😧
(the #if must be decided at compile-time, but the result of getenv() will only be known at runtime)

Thus, if you want to add a pre-processor definition at compile time, then you can do something like this:

gcc -DFEATURE1=1 -c foobar.c -o foobar.o


If you call the compiler from a shell script, you can use shell (environment) variable here:
1
2
YOUR_VARIABLE=1
gcc -DFEATURE1=${YOUR_VARIABLE} -c foobar.c -o foobar.o

Or, in a Makefile:
1
2
3
4
YOUR_VARIABLE := 1

foobar.o: foobar.c
    gcc -DFEATURE1=$(YOUR_VARIABLE) -c foobar.c -o foobar.o


See also:
https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options
Last edited on
Think about what you're asking. Let's suppose that in your compiler #define FEATURE1 getenv("FEATURE1") does what you hope it will do. Then if you have a source like
1
2
3
4
5
6
7
8
9
10
#define FEATURE1 getenv("FEATURE1") 
#define FEATURE2 getenv("FEATURE2") 

#if defined FEATURE1
use_feature1();
#elif defined FEATURE2
use_feature2();
#else
throw std::runtime_error("can't do it");
#endif 
after you compile it the executable will be in one of three possible states:
 
use_feature1();

 
use_feature2();

 
throw std::runtime_error("can't do it");

No check will be made at run time, so the program will not care about the environment variables. The environment was read at build time and the results were baked into the executable. If that's what you want, why use environment variables instead of simply defining the macros you want from the command line?

If you want the environment checked at run time, just use getenv() as normal.
Thanks a lot, I think @kigar64551 answered my question, the way to add a flag in Makefile will work for my needs.
Topic archived. No new replies allowed.