On 30/11/2015 02:10, Dmitry Marakasov wrote:
Hi!

This question bugs me for a long time so I though maybe someone has
a solution. I have a project which includes an application and some
data for it. An application needs to know path to its data files, so
I pass it via compiler definition: ADD_DEFINITIONS(-DDATADIR="...")

The problem is that this path is different based on whether I want to
run the application from build directory:

ADD_DEFINITIONS(-DDATADIR="${PROJECT_SOURCE_DIR}/data")

or want to install it systemwide:

ADD_DEFINITIONS(-DDATADIR="${CMAKE_INSTALL_PREFIX}/share/myapp")

I want my project to both run from build directory and to be
installable systemwide, without the need to rebuild or specify extra
options.

Any ideas?

I don't claim this is a universal solution, but it works for me. It's also likely to be further improved--this is the first functional implementation.


https://github.com/openmicroscopy/bioformats/blob/dev_5_1/cpp/lib/ome/common/module.cpp

While you can configure and use hardcoded install paths, it will also optionally introspect itself at runtime and compute the install paths dynamically. This means you can have a relocatable installation and it will discover this on the fly. Lastly, you can overrride each path component with an environment variable. This is used to run inside the install tree where the path layout doesn't match the installed layout. It's also useful for testing or overriding things after installation, if needed, or overriding the autodetection on platforms where autodetection doesn't work.

This approach requires this source file to be in a shared library (Linux/FreeBSD/MacOS X - using dlopen(3)/dladdr(3)) or in a DLL (Windows - uses GetModuleHandleExW()/GetModuleFileNameW()). It would also work in an executable compiled with -rdynamic with suitable adjustment for the install path computation. Other platforms could be added, but this covers all my needs at the present. Basically we get the path to the .so/.dylib/.dll, then remove the library runtime path to get the installation root, then add on any relative path we need, e.g. the datadir or anything else. This works for system installations or relocatable installs anywhere.

This uses the CMake GNUInstallDirs module variables via a generated header to store all the paths.


Regards,
Roger
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to