Xcode preprocessor dependent on environment variable - xcode

I have a configuration that I'd like to dynamically control a preprocessor defined value through an environment variable.
Is this possible? if it is how do I set in the preprocessor define table that I want to set the value based on the environment variable?

In the "Build Settings" of a target of your project, you can add something like that to the "Preprocessor Macros" field:
DEV_USERNAME="${USER}"
Of course, the USER variable can be replaced by any environment variable available to Xcode build system. To get a list of those, you can add a run script to your target and enable the checkmark "Show environment variables in build log."
You can then use the DEV_USERNAME preprocessor macro in your code. And if you want to use it as a string, you can "stringify" it:
#define xstr(s) str(s)
#define str(s) #s
xstr(DEV_USERNAME)
This will give you the username surrounded by double quotes.

Related

CMake: how to embed build configuration (Debug, Release, MinSizeRel,...) into binary?

I'm using Cmake's configure_file() function to generate a header that I include into my project.
This way, I can for example store into the resulting binary the git commit hash of the code beeing compiled.
Now I'm trying to make my program aware of the compilation configuration which has been used: Debug, Release, MinSizeRel or RelWithDebInfo.
The toolchain used is VisualStudio, therefore all configurations are generated by CMake at the same time. So for example, CMAKE_BUILD_TYPE is alays set to Release.
What is the common way to make the program built aware of the the build mode used ?
You may create a file, containing build type-specific values, using file(GENERATE) command. This command expands generator expressions.
For example, the call
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/build_$<CONFIG>
CONTENT "Build type: $<CONFIG>")
at the end of configuration will create build_Debug file with content Build type: Debug, build_Release file with content Build type: Release and so on.
Resulted files could be used in custom commands:
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/some_file_$<CONFIG>
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/build_$<CONFIG>
COMMAND do-something-with build_$<CONFIG>
)
Note, that file(GENERATE) doesn't expand variables. So if you want to combine in the resulted file both variables values and generator expressions, then you need to "pipe" configure_file with file(GENERATE).
my_file.in:
var: #MY_VAR#
build type: $<CONFIG>
CMakeLists.txt:
# Creates intermediate file with expanded variables.
configure_file(my_file.in my_file_intermediate #ONLY)
# Expands generator expressions in the intermediate file and creates "final" files
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/my_file_$<CONFIG>
INPUT ${CMAKE_CURRENT_BINARY_DIR}/my_file_intermediate)
You can use CMake generator expressions with the add_compile_definitions command (or any other command which accepts generator expressions).
Like this: add_compile_definitions(CONFIG_TYPE="$<CONFIG>"). Then use the CONFIG_TYPE macro in your C++ code.

Is there a way to print all variables defined/visible within a makefile?

let's assume the following Makefile:
FOO=1
BAR?=test
BLAH:=$(BAR)
target:
#echo "helloworld"
Is there a way it can show me variables like this (\n or \s) ?
FOO
BAR
BLAH
bonus question:
if it is possible, is there a way to also get external variables?
make target BLABLAH=toto or export BLABLAH=toto; make target
FOO
BAR
BLAH
BLABLAH
You don't say so specifically but because of the syntax I'll assume you're using GNU make. In that case you can use the .VARIABLES special variable:
$(info Variables: $(.VARIABLES))
Note, that make target BLABLBAH=toto does not create an "external variable" (that term is not well-defined so I'm just guessing that by this you mean variables that are inherited from the environment and not set in the makefile). Setting a variable on the command line creates a real make variable and it will be shown in the list above.
Variables obtained from the environment are imported into make as makefile variables and will also appear in the above list.

How to save make argument in a variable

I am working on a (GNU) Makefile and need to save arguments in a variable.
Like if I give the command make projectX, then I need to assign projectX to some variable.
I tried to assign projectX like this, assuming that argument 1 would be projectX.
PRODUCT := "$1"
But this does not work.
What is the best way to assign make arguments in a variable?
From the GNU make manual:
Make will set the special variable MAKECMDGOALS to the list of goals you specified on the command line. If no goals were given on the command line, this variable is empty. Note that this variable should be used only in special circumstances.
And note that usually you would/should/must use $# to refer to the target of a rule.
You can also assign variables in make command line:
make PRODUCT=bla
Which is often used for debug/release builds:
make # builds debug version
make MODE=release # builds release version

How do I change the PATH variable for automatic CMake tests?

I use the Cmake Testing feature with add_test but the executable does not find all dll's. Is there a way in CMake to set environment variables for theses tests?
I want to set something like:
PATH=%PATH%;C:\additional\lib\folder
I found the solution:
You can set the ENVIRONMENT property for every test. E.g. you can add after each add_test(...)
set_property(TEST testName PROPERTY ENVIRONMENT
"PATH=%PATH%\;C:\\additional\\lib\\folder")
Take care that you escape \; and \

Command-line variables - in makefile - expand to weird values

From the docs:
Target-specific variables have the same priority as any other
makefile variable. Variables provided on the command line (and in the
environment if the '-e' option is in force) will take precedence.
Specifying the 'override' directive will allow the target-specific
variable value to be preferred.
So, a simple makefile, like:
# A pattern-specific variable assignment.
% : foo += file
all : x ;
# Target is a double-colon w/o dependencies, so Make will ALWAYS run its commands.
x ::
#echo '$(foo)'
Running, we get:
# Override makefile-level variables, with a command-line assignment.
$ make foo=cmd
cmd cmd cmd
# Set the value in the environment, And tell Make to prefer it over any makefile-level definitions.
$ foo=env make --environment-overrides
env file file
Returning now, to the quote above, from the documentation:
Variables provided on the command line (and in the environment if the '-e' option is in force) will take precedence.
It seems, that using either:
Command-line assignment.
Environment-set variables, AND using -e (--environment-overrides).
Have both the same effect, i.e. overrides the file-level (makefile) variable.
But, the results differ greatly. Remember that the value given in the command-line was: cmd, and the value given in the environment was: env.
Now, compare the values, given for a command-line override vs. an environment override:
cmd cmd cmd (for command-line override).
env file file (for environment override).
So, whereas for command-line, Make repeats the same value, i.e. cmd, 3 times, for environment-override, the situation is different. That is, Make will "repeat" the environment-level value: env only 1 time, and then repeats - none other - than the overridden file-level value: file.
Now, not only is the situation completely different for an "override" from command-line vs. an "override" from the environment, which is strange by itself, the problem here is much bigger.
Since, Make rules to give "priority" for a command-line (or environment) value, why does it insist to append "other" values (as in the case of environment-override, where Make appends "file file"), or in the case of a command-line override (where Make repeats the same value ***3* times). Seriously?
How does it make sense at all? And what is the justification for these inconsistent and strange results?
I believe the answer here is related to the answer to this other question of yours. (And possibly a bug in the env override version.)
The global variables and the target-specific variables are distinct variables.
The cmd cmd cmd result is because when you write %: foo += file make stores that as an addition to the current value of variable foo of the target-specific value of the variable foo which is file.
However, when you set foo on the command line make overrides the value of the target-specific variable foo to be cmd instead of file. So when make concats the variable each time it gets cmd cmd cmd.
That explanation should, I think, get you env env env then and I'm not sure why it doesn't. This could be a bug or it could be some other detail about how env override variables and target-specific variable values work. I'm not sure.
(Check the output of make -p for both these cases to see what I mean about the target-specific variable's value.)

Resources