target_compile_definition build vs install phase

Trying to add definition to executable as shown below.

target_compile_definitions(definitionTest
    PUBLIC
        $<INSTALL_INTERFACE:EXAMPLE_ASSETS_PATH="install time path">
        $<BUILD_INTERFACE:EXAMPLE_ASSETS_PATH="build time path">
    )

Is this valid/possible ? It always gives the build time value.
Being a new user it doesn’t allow adding files. Hence the copy paste.
CMakeLists.txt

cmake_minimum_required (VERSION 3.10)
project(examples)
add_executable(definitionTest main.cpp)

target_compile_definitions(definitionTest
    PUBLIC
        $<INSTALL_INTERFACE:EXAMPLE_ASSETS_PATH="install time path">
        $<BUILD_INTERFACE:EXAMPLE_ASSETS_PATH="build time path">
    )

## install

include(GNUInstallDirs)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Setting install path to install folder in the build tree" FORCE)
endif()

install(
    TARGETS definitionTest
    EXPORT EXPORT_TEST
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/definitionTest
    )

install(
    EXPORT EXPORT_TEST 
    NAMESPACE UNKOWN::
    DESTINATION lib/cmake/EXPORT_TEST
    )

export(
    EXPORT EXPORT_TEST 
    NAMESPACE UNKNOWN::
    )

main.cpp

#include <iostream>
#include <conio.h>
int main()
{
    std::cout<<EXAMPLE_ASSETS_PATH;
    getch();
    return 0;
}

$<BUILD_INTERFACE> expands during the build to give build-specific information. $<INSTALL_INTERFACE> expands during the install for consumers to get the same information from the install. Since your main.cpp is only built during the build, that source file only sees the $<BUILD_INTERFACE> (otherwise CMake would need to rebuild your file prior to installation…but that’s not what you tested as CMake has no idea that it is “just a string” you changed).

Instead, you should do something like:

  • always have the same relative path between the executable and the assets
  • compute the executable’s location at runtime
  • use the relative path to find the assets

To do this, you need to:

  • put the binary in the same place as the install when built into the build tree (i.e., use the install destination as part of CMAKE_RUNTIME_OUTPUT_DIRECTORY)
  • copy the assets to the binary directory from the source tree
1 Like