# target\_compile\_definition build vs install phase

**URL:** <https://discourse.cmake.org/t/target-compile-definition-build-vs-install-phase/5618>\
**Category:** Code\
**Created:** [May 5, 2022, 12:53pm UTC](https://discourse.cmake.org/t/target-compile-definition-build-vs-install-phase/5618 "2022-05-05T12:53:30Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pacific](https://discourse.cmake.org/user_avatar/discourse.cmake.org/pacific/32/2164_2.png) [@Pacific](https://discourse.cmake.org/u/Pacific)\
**Post date:** [May 5, 2022, 12:53pm UTC](https://discourse.cmake.org/t/target-compile-definition-build-vs-install-phase/5618/1 "2022-05-05T12:53:30Z")

</div>

Trying to add definition to executable as shown below.

```auto
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**

```auto
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**

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

```

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [May 5, 2022, 1:07pm UTC](https://discourse.cmake.org/t/target-compile-definition-build-vs-install-phase/5618/2 "2022-05-05T13:07:26Z")

</div>

`$<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
