[CMake] Project initialization file path
Michael Hertling
mhertling at online.de
Thu Jun 10 15:52:26 EDT 2010
On 06/10/2010 10:51 AM, Eric Noulard wrote:
> 2010/6/9 Aby Louw <jalouw at csir.co.za>:
>> Hi,
>>
>> I have a Linux project that reads an initialization file on startup to
>> get some file names and variables.
>>
>> When doing an in-source or out of source build, I generate the
>> initialization file in the CMAKE_BINARY_DIR and then also generate the C
>> file that reads this file so that I know the correct path.
>>
>> Now when doing a "make install" I want to install the initialization
>> file on the /etc path. Therefore the initialization file path in the C
>> file needs to be updated. However I do not know how to recompile the C
>> target before installation happens.
>
> Looks odd to bury some config into a compiled C-file.
> If the C file contains some "actual installation path" It may be easier for this
> executable/function to lookup **at runtime** its actual install path...
>
> If this C file is "reading" some config file may be you can add
> some primitive search path mechanism,
>
> 1) look in "."
> 2) look in "${CMAKE_INSTALL_PREFIX}/...." --> you must be doing
> something like that now
> 3) use some environment var prefix
> getenv(HOME)/... --> using HOME env var
> getenv(MYSW_PATH)/.... --> using specific env var
>
> then during devel you may setup MYSW_PATH as you want
> and then when installed ${CMAKE_INSTALL_PREFIX}/ will be used
> provided 3) as a higher priority than 2)
>
>> I need something like a pre install or, add_dependency to install
>> target, but as far as I know this is not possible. Does anybody know of
>> a workaround to this problem?
>
> install(CODE ...
> or
> install(SCRIPT ...
>
> may help you to execute extra CMake action at install time.
> However I would rather use some "search path" mechanism.
The following CMakeLists.txt provides a somewhat weird approach:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(REINSTALL C)
FILE(WRITE f.c "void f(void){}\n")
FILE(WRITE reinstall.cmake
"IF(NOT INSTALLED)\n"
" EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E touch
${CMAKE_SOURCE_DIR}/f.c)\n"
" EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} --build
${CMAKE_BINARY_DIR})\n"
" EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -DINSTALLED=TRUE -P
cmake_install.cmake)\n"
"ENDIF()\n"
)
ADD_LIBRARY(f STATIC f.c)
INSTALL(
TARGETS f
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
INSTALL(SCRIPT reinstall.cmake)
The reinstall.cmake script is executed by INSTALL(SCRIPT ..), i.e. after
the targets are checked for being up to date and after being installed;
it touches a source file, rebuilds by "cmake --build ..." and reinstalls
by "cmake -P cmake_install.cmake", so any "make install" will result in
an install-touch-build-install cycle, and the INSTALLED flag prevents an
infinite recursion. Of course, instead of touching, you can do whatever
is necessary to set up the project for rebuild-before-installation. This
appoach works with *nix Makefiles, but I don't know if it's suitable for
other generators, too, in particular due to "cmake --build ...".
Generally, I would recommend the same as EN and MW have before, i.e. a
search path that takes into account: Environment variables, the user's
home directory and - as a hardcoded last resort - the /etc or
${CMAKE_INSTALL_PREFIX}/etc directories.
'hope that helps.
Regards,
Michael
More information about the CMake
mailing list