target_compile_defintion with $<INSTALL_INTERFACE:>

I have a config file that i want in by project folder in build mode and in /usr/local/etc in install mode.
I try to use generator expression for that but it didn’t work, the build mode path is always evaluated, even if i use
cmake --build . --target install

I use the following command :
target_compile_definitions(${PROJECT_NAME} PRIVATE $<BUILD_INTERFACE:CONF_DIR="${PROJECT_SOURCE_DIR}"> $<INSTALL_INTERFACE:CONF_DIR="${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME}.d"> )

Usage requirements only change the interface exposed by the target depending on where it is consumed. It cannot be used to modify code that has been compiled at install time. You’ll need to add logic to detect the build or install tree to the code that uses CONF_DIR and select which one to use based on that. I recommend using the same relative tree layout for your build and install trees so that you just need to compute it relative to some stable location (such as where your executable or non-static library is on the filesystem).

Thank you for your help! What kind of logic do you think about? I thought of checking if the rpath of my library exist in my code, but there is certainly a more trivial way to do this

Unfortunately, all of the ways to get “where am I?” are platform-specific. There’s dladdr for ELF and macOS and GetModuleFileName on Windows. This is why shared libraries and executables are fine, but static libraries are not (since you don’t know where you’ll be linked into, so there’s no reliable way to figure out a relative path).

Thank you, that’s a very interesting solution, that’s should work for me.
I think of another one. I set 2 variables with target_compile_definition, one for the project directory and one for the installation directory. If there is a file in the project directory it uses it, otherwise it uses the installation directory.
In development phase, the project directory will be used and in production, where just the lib are pushed, the installation lib should be used because we don’t have built in place.
Doesn’t work for static libraries though.
Please could you give me your opinion on that.

That can work, but there are a few issues with it (that you might not care about for your situation):

  • the build tree path is now hard-coded into your deployment; if this directory shows up for whatever reason, it would be used
  • the install is not relocatable (you have to install it to the built-in CMAKE_INSTALL_PREFIX and cannot move the install prefix around after installation