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 \
Related
I am playing around with yocto for a personal project. I have a layer called meta-nightcore which has several files writen in different languages: bash, Python, C, C++ and several recipes.
Is it possible to exclude the meta-nightcore when calling bitbake <image_name> when a user defined variable NIGHTCORE_ENABLED? This variable is set via shell command before calling source oe-init-build-env.
If you have different ideas, can you also share?
Thanks anh Best Regards,
Duy Tran
Yes, you can pass your environment variable into the build environment and then use it to conditionally add the extra layer(s).
You'll need to modify your bblayers.conf to store a default value for NIGHTCORE_ENABLED and to add the extra layer(s) to BBLAYERS if it is set to 1:
NIGHTCORE_ENABLED ?= "0" # overridden by env if specified in BB_ENV_EXTRAWHITE
NIGHTCORE_LAYERS ?= "/path/to/poky/meta-nightcore"
BBLAYERS ?= " \
/path/to/poky/meta \
/path/to/poky/meta-poky \
/path/to/poky/meta-yocto-bsp \
${#bb.utils.contains('NIGHTCORE_ENABLED', '1', '${NIGHTCORE_LAYERS}', '', d)} \
"
Then, you need to tell Bitbake to allow your environment variable to be captured into the Bitbake datastore by adding it to BB_ENV_EXTRAWHITE:
export NIGHTCORE_ENABLED=1
export BB_ENV_EXTRAWHITE="${BB_ENV_EXTRAWHITE} NIGHTCORE_ENABLED"
You can then run bitbake <image_name>.
Because bblayers.conf is usually generated when source oe-init-build-env is run for the first time, you may wish to use TEMPLATECONF to create a bblayers.conf.sample file that already includes this extra logic.
There's some related answers here too:
Is it possible to pass in command line variables to a bitbake build?
I am dealing with autotools and here is the situation:
By default libdir is set to '${exec_prefix}/lib' with exec_prefix set to '${prefix}' and prefix set to '/usr/local'.
Key here recursion and at first level libdir variable contain another variable and a following path.
So how to convert ${libdir} into a variable containing '/usr/local/lib' ?
Info : all 3 (libdir, exec_prefix, prefix) can change according configuration.
Consider the following files:
configure.ac
AC_PREREQ([2.59])
AC_INIT([test], [0.0.0] )
AM_INIT_AUTOMAKE()
AC_CONFIG_SRCDIR([test.cpp])
AC_LANG([C++])
AC_PROG_CXXCPP
AC_PROG_CXX
AC_CONFIG_FILES([Makefile path.conf])
AC_MSG_NOTICE([">>> Before ac_output prefix=${prefix}"])
AC_OUTPUT
AC_MSG_NOTICE([">>> after ac_output prefix=${prefix}"])
Makefile.am
bin_PROGRAMS = test
test_SOURCES = test.cpp
test.cpp
int main()
{}
path.conf.in
#libdir#
Then after invoking :
aclocal && autoconf && automake -a --foreign && ./configure
configure log show:
configure: ">>> Before ac_output prefix=NONE"
...
...
...
configure: ">>> after ac_output prefix=/usr/local"
And generated file path.conf contains
${exec_prefix}/lib
The goal is to have a variable containing the expanded version of the path to be used in a path.conf.in so autotools generate path.conf with that expanded path.
Edit: Bash only solution
Digging related topics and helped by #Aserre answer, I manage to do the following with a regex.
while expr match "${libdir}" '^.*\$.*$' 1>/dev/null;
do
echo ">${libdir}"
libdir="$(eval echo ${libdir})"
done
Which means : While $libdir contain one $ expand with eval.
But does not work in configure.ac script before AC_OUTPUT
The goal is to have a variable containing the expanded version of the path to be used in a path.conf.in so autotools generate path.conf with that expanded path.
The Autotools provide special handling for default values of the installation-directory variables, in order to enable the user to specify or override the installation prefix at make install time:
make install prefix=/my/special/prefix
What you propose to do will break that. If a user specifies a different installation prefix at the installation stage than they tell configure (or that they let configure choose by default) then you will end up with a broken installation.
The best way to do address problems like this is to build the configuration file under make's control, at make install time, instead of doing it at configuration time. If the project uses Automake, then that might mean something like this:
install-data-local:
$(SED) -e 's,[#]libdir[#],$(libdir),' path.conf.in > $(sysconfdir)/path.conf
chmod 0644 $(sysconfdir)/path.conf
chown root:root $(sysconfdir)/path.conf
uninstall-local:
rm $(sysconfdir)/path.conf
You can of course substitute more output variables than that if you like. It's pretty close to what configure does itself.
And of course, if you do it this way then you do not need to worry about performing extra expansions.
If you are 100% sure of the content of the ${exec_prefix} variable, you could use the following line to achieve what you want :
libdir="$(eval echo ${exec_prefix})"
Note that in a lot of cases, the use of eval is discouraged. Here, if the user has overriden the content of the variable exec_prefix, for instance with exec_prefix='a; rm -rf /', all the code written will be executed.
If you are in total control of your environment (i.e. you are certain of the value of the variables when you launch the script), there should be no problem, otherwise be wary of the potential side effects
I've currently run in such a problem, in fact caused by the package maintainer(s), who simply did not consider that a certain preprocessor definition was not available until version X of a certain toolkit package required in the dependencies (which is currently in testing stage). It was fixable by simply adding an additional #define to a header file in the base system, making the project compile fine again.
However, what if I had no root access to the system? Could I also add a #define new_macro "i am from the future" at compile time, e. g. to configure?
When reading myself through the matter, I thought that it might maybe work with the DEFS environment variable, but apparently this is not meant to be used for C preprocessor directives.
So can this be accomplished at all?
Thanks, but unfortunately a huge problem is the strings in quotes
Create a file, for example at ~/somedir/mycompiler with content:
#!/bin/sh
gcc -Dnew_macro="i am from the future" "$#"
add executable permissions chmod +x ~/somedir/mycompiler and then pass that as parameter to configure:
./configure CC="$HOME"/somedir/mycompiler ...
Configure script in turn will use that script to compile everything, passing -D everywhere, and quotes will be properly parsed by sh.
The project I'm compiling uses CMake, which loves absolute pathnames.
When I compile with debugging information enabled, gcc puts those long names into .debug_str sections, which is bad for debugging. I'd like to have short relative-to-project-root pathnames there instead.
Is there some option to tell gcc to strip some part of pathname before emitting debug data? Or, maybe, there is some tool that could do that on compiled binaries?
I've tried using SET(CMAKE_USE_RELATIVE_PATHS ON) (which seems to be frowned upon by devs) option, but as I'm using out-of-source builds, pathnames are still not in the form I'd want them to be. I.e. they're ./../src/mod_foo/foo.c instead of mod_foo/foo.c.
You can use the -fdebug-prefix-map flag to remap the debugging information paths. For example, to make the paths relative to the build location use: -fdebug-prefix-map=/full/build/path=.
You can set the RULE_LAUNCH_COMPILE property of a CMake target to have CMake invoke a shell script which transforms the source file path to a project relative path before invoking gcc. Use the CMake function configure_file to generate a shell script which knows about the PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR of your project.
In your outermost CMakeLists.txt add the following code:
configure_file(
"${PROJECT_SOURCE_DIR}/gcc_debug_fix.sh.in"
"${PROJECT_BINARY_DIR}/gcc_debug_fix.sh"
#ONLY)
add_executable (MyExecutable ...)
set_target_properties(MyExecutable PROPERTIES
RULE_LAUNCH_COMPILE "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh")
The following template shell script gcc_debug_fix.sh.in needs to go to the root directory of the CMake project:
#!/bin/sh
PROJECT_BINARY_DIR="#PROJECT_BINARY_DIR#"
PROJECT_SOURCE_DIR="#PROJECT_SOURCE_DIR#"
# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -o OBJECT_FILE -c SOURCE_FILE
# extract parameters
SOURCE_FILE="${#: -1:1}"
OBJECT_FILE="${#: -3:1}"
COMPILER_AND_FLAGS=${#:1:$#-4}
# make source file path relative to project source dir
SOURCE_FILE_RELATIVE="${SOURCE_FILE:${#PROJECT_SOURCE_DIR} + 1}"
# make object file path absolute
OBJECT_FILE_ABSOLUTE="$PROJECT_BINARY_DIR/$OBJECT_FILE"
cd "$PROJECT_SOURCE_DIR"
# invoke compiler
exec $COMPILER_AND_FLAGS -c "${SOURCE_FILE_RELATIVE}" -o "${OBJECT_FILE_ABSOLUTE}"
The shell script uses the information from the variables PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR to transform the path of the source file to a path relative to the project root and the object file's path to an absolute path. Because gcc gets passed a project relative path now, .debug_str should use that path, too.
The following caveats apply:
Be sure to set the executable bit of gcc_debug_fix.sh.in.
For the script to work CMAKE_USE_RELATIVE_PATHS has to set to OFF again.
The script makes assumptions about the location of the file paths on the command line. This may not work if CMake uses a different rule to invoke the compiler. A more robust solution would be to scan the script arguments for the -o and -c flags.
If I really couldn't fix the make file/tool to do this properly, I would write a wrapper script for gcc that recognises absolute pathnames and converts then to relative ones.
It might look something like this in bash:
#!/bin/bash
out=()
for arg; do
out=("${out[#]}" $(echo "$arg" | sed 's:/my/absolute/directory/:../:'))
done
exec gcc "${out[#]}"
If your source directory has subdirectories then you'll need to handle those carefully, but the above should work for a flat source directory. I've not tested it though, and I wouldn't be surprised if I've got the quoting wrong, but that'll only be a problem if you have pathnames with spaces in. It also doesn't handle parameters like -I/whatever/include, but you can fix that.
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.