Permanently storing an environment variable when using CMake install - c++

I'm trying to store a path environment variable to the location of some configuration files my program needs at runtime, but I do not know the location of until the compiled program is installed.
My idea was to use the following:
install(CODE "set(ENV{MY_CONFIG_PATH} \"${CMAKE_INSTALL_PREFIX}/MyConfig\"")
However, I quickly found out that this does not permanently set that environment variable so as soon as I run the program and check the contents of MY_CONFIG_PATH with std::getenv(), I get a null pointer.
I thought about maybe setting a preprocessor define at compile time, but that won't work either because it seems CMAKE_INSTALL_PREFIX is only populated when the installation process is executing.
Can anyone suggest a neat workaround that works for both Windows and Unix?

Since CMAKE_INSTALL_PREFIX is known at configure-time you can use the configure_file command to configure a file and insert the value of CMAKE_INSTALL_PREFIX into the specified location.

Related

Set a predefined working directory when building a program in MacOSX

Recently I encountered this documentation about Apple and the loading of dynamic libraries.
Citing:
When the library name is a filename (that is, when it doesn’t include directory names), the dynamic loader searches for the library in several locations until it finds it, in the following order:
$LD_LIBRARY_PATH
$DYLD_LIBRARY_PATH
The process’s working directory
$DYLD_FALLBACK_LIBRARY_PATH
And my concern is about the third step "The process’s working directory".
Since I load libraries (and libraries that I load will load others), I would like to force the working directory to be some predefined path.
At the beginning of the main is already too late for me.
Do you know if there is some build option that I can set in pkgbuild, or in some .plist file?
Do you know a workaround for that?
EDIT:
I found these keys that could be set, in particular see LSEnvironment.
I was thinking maybe some 'hack' like
$DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$DYLD_FALLBACK_LIBRARY_PATH
(yes, I know that it is ugly...). But it would not work anyway, because citing the previous link:
These environment variables are set only for apps launched through Launch Services. If you run your executable directly from the command line, these environment variables are not set.
So, what can I do if someone calls my executable directly?
Are the .plist files considered at all in case the executable is called directly?

Eclipse ignore LD_LIBRARY_PATH in Environment

I'm trying to lunch an application from Eclipse CDT and as I read everywhere, I set LD_LIBRARY_PATH to the directory containing the shared library:
However, when I try to run this configuration:
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/make/CloudCache: error while loading shared libraries: libvl.so: cannot open shared object file: No such file or directory
Just to clarify: I'm 100% sure that libvl.so is in that path, in fact when I try to run the application from command line it works perfectly.
Why this happens?
I wonder if it is being reset somewhere else. You can also set environment variable in the Launch Configuration if you are using that. There are two places in there, one where you have an 'Environment' tab, and another where you choose your 'Build Configuration' which could itself point somewhere else.
I've just been trying to get this to work for the first time in eclipse (Linux 64), and did exactly what you showed and it worked.
A bit late, but still can be useful. You have the option "Append environment to native environment" checked on your screenshot. Very probably you have this variable redefined there. It was my case.

Netbeans/C++ add environment variable at make

I need to set a variable that is checked in the makefile(i.e. at compile time), but I can't find it in the project properties.
I right-click on the project, but can't find a place to set environment vars, except in the Run but even there it seems I can't add a variable (nothing happens when I click on Add after expanding the ...).
What am I missing?
As a side: Netbeans probably will run a shell before issuing the commands like make, what kind of shell is it? how can I configure it?
Judging by your screenshot that you are on OSX, you should be able to set an environment variable by replacing "${OUTPUT_PATH}" under Run Directory with FOO=BAR;"${OUTPUT_PATH}". This is normal POSIX syntax for running a program with a specific environment variable or set of variables set, and can be used at the terminal as well.
Edit: In Netbeans, to set an environment variable for a specific action, right click on project, go to Properties->Actions->{Action}->Set Properties: Add Env.FOO=BAR.

Where does cmake look to find packages?

In Ubuntu 14.04, I am compiling a C++ program, which depends on the following packages: CUDA and OpenNI. In the CMakeListst.txt file for this program, there is the following:
find_package(CUDA)
find_package(OpenNI)
And the output to cmake is:
Found CUDA: /usr/local/cuda (found version "6.5")
-- Could NOT find OpenNI (missing: OpenNI_LIBRARY OpenNI_INCLUDE_DIR)
So, it seems that CUDA was found, but OpenNI was not. Now, I have definitely installed OpenNI, but perhaps not in the standard location. Whereas the CUDA files are in usr/local/cuda as stated, my OpenNI files are in ~/Libraries/OpenNI.
My question is: How do I tell cmake where to look for to define the OpenNI_LIBRARY and OpenNI_INCLUDE_DIR variables? Is there a file somewhere which cmake has paths defined for all these variables, which I might need to manually edit?
It looks in CMAKE_MODULE_PATH.
Append to this path using expressions like this
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
There is no unified way that tells you where a find script will attempt to look for a library.
This is a bit unfortunate, but the only way to know for sure is to check the source of the find script itself. Most find scripts rely on find_library and similar commands to locate their files, which will by default search in a number of locations that are obvious candidates (like /usr/local/ on Unixes).
Unfortunately, this alone does not get you very far. If you are stuck on a platform like Windows where there is no reasonable default location, or you want to avoid polluting the directory tree, you need another way. Most find scripts therefore allow injecting the location of the library in some way.
In my experience, the cleanest way to do this is through environment variables. They are flexible to configure and convenient to use. In particular, you can make them persistent by adding them to your user's environment, so you don't have to type them out each time you run CMake.
If you check for example the find script for CUDA that ships with CMake, you will notice that it uses the environment variables CUDA_PATH, CUDA_LIB_PATH, CUDA_INC_PATH and CUDA_BIN_PATH (along with a few others) for this purpose.
An alternative is to directly set the result variables of the find script in the cache from the command line via CMake's -D parameter.
In any case you will have to check the find script source to find out what is the best course of action.
A word of advice: Do not attempt to hardcode locations in your own CMakeLists. While this might seem like a quick solution, it's also a very dirty one that essentially makes your build system non-relocatable. Always reach for solutions that allow the user to configure the build system from the outside without having to change CMake code.
Even if this is a quite old question: If you call cmake with --debug-find it will tell you where it looks for a package that you requested through a find_package() call in your CMake script.
My personal preference, especially for packages residing in their very own dedicated location, is to define an environment variable <package_name>_DIR, which points to the package's configuration file (assuming that the lib provides one). See the find_package() documentation about the search procedure for more details.

What is the Best Way to get Installation Prefix in Windows

I am compiling my stuff both for Linux and Windows. On Linux, normally, the installation prefix is determined at compile time so everything can be hard-coded in the executables. On Windows, I use the standard MSVC install shield program and it allows the user to change the installation location. My question is what is the "correct/proper" way for the Windows port of a program to determine this installation prefix. Do I find the location of the executable and then subtract the installation prefix? Or, is there something in the registry during installation which tells me where I can find my data files/etc.?
While you COULD use the registry (provided your installation sets an appropiate key, either automatically or because you told it to), I prefer just asking the program itself. Call the GetModuleFileName() function with a NULL parameter to get the path for the executable.