# Bug with setting rpath in incremental builds

**URL:** https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489
**Category:** Development
**Tags:** os:linux, gen:makefiles
**Created:** [August 20, 2024, 1:34pm UTC](https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489 "2024-08-20T13:34:04Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![fnicholson](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/258eb7/32.png) [@fnicholson](https://discourse.cmake.org/u/fnicholson)
#### Post date: [August 20, 2024, 1:34pm UTC](https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489/1 "2024-08-20T13:34:04Z")

</div>

Hi all,

It looks like I found a bug in CMake. It sets the rpath (e.g. set(BUILD\_RPATH “lib/dir/here”) when I delete the build folder and build everything fresh. However, if I do an incremental build, the RPATH is not set properly (set to a directory in the build directory itself). I’ve confirmed this using  
objdump -x binary\_name | grep ‘R.\*PATH’

Any thoughts on where to go from here?

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [August 20, 2024, 9:41pm UTC](https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489/2 "2024-08-20T21:41:46Z")

</div>

I’d recommend coming up with a complete, minimal project that can be used to reproduce the problem. Make sure you clearly explain what you expect to happen versus what does happen (the more specific the better).

---

<div class="post-metadata">

### Author: ![ferdnyc](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ferdnyc/32/267_2.png) [@ferdnyc](https://discourse.cmake.org/u/ferdnyc)
#### Post date: [August 22, 2024, 4:10am UTC](https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489/3 "2024-08-22T04:10:05Z")

</div>

> [@fnicholson](#):
>
> It looks like I found a bug in CMake. It sets the rpath (e.g. set(BUILD\_RPATH “lib/dir/here”) when I delete the build folder and build everything fresh. However, if I do an incremental build, the RPATH is not set properly (set to a directory in the build directory itself). I’ve confirmed this using  
> objdump -x binary\_name | grep ‘R.\*PATH’

```cmake
set(BUILD_RPATH "/some/path")

```

…If we take your code literally, that command does nothing. It sets a local variable named `BUILD_RPATH` in your `CMakeLists.txt` code, but that variable has no meaning unless it’s used somewhere.

CMake **does** support a variable `CMAKE_BUILD_RPATH` that can be set to initialize the value of the `BUILD_RPATH` target property. But the _property_ `BUILD_RPATH` (which is a completely separate thing from a variable named `BUILD_RPATH`) can only be set on a build target using `set_property()` or `set_target_properties()`.

You normally don’t _need_ to mess with the `BUILD_RPATH` property, though, because by default CMake will **automatically** set RUNPATHs on all of the output binaries in your build directory so that they can load any linked build artifacts. Those `RUNPATH` entries are then removed when the binaries are re-linked during installation.

So, for example, if you have a `CMakeLists.txt` like this:

```cmake
project(myproj VERSION 0.1 LANGUAGES CXX)

add_executable(binary_name ${sourcefiles})
add_library(somelib SHARED ${libsources})
set_target_properties(somelib PROPERTIES
  VERSION 0.1
  SOVERSION 0
)
target_link_libraries(binary_name PRIVATE somelib)

```

…Then CMake will automatically set a `RUNPATH` on the `<builddir>/binary_name` file that points to `/full/path/to/<builddir>`, so that `binary_name` can find the `libsomelib.so.0` file in that directory.

If you need additional `RUNPATH`s set on your output binaries, you can add them using the **property** `BUILD_RPATH`:

```auto
set_target_properties(binary_name PROPERTIES
 BUILD_RPATH "/path/to/some/library"
)

```

…But `set(BUILD_RPATH ...)` isn’t doing _anything_ in your CMake code, and any `RUNPATH`s you see on your output binaries in the build directory are probably the ones being set by CMake itself.

Regardless whether they’re set by CMake automatically or manually using `BUILD_RPATH`, by default all of the binaries will be re-linked during install so that the _installed_ binary files have no `RUNPATH` entries. If you need `RUNPATH`s set on your installed binaries, you can point the `INSTALL_RPATH` target property to the location of any installed targets, or ask CMake to automatically include the location of any _externally_-linked libraries:

```cmake
set_target_properties(binary_name PROPERTIES
  # manually
  INSTALL_RPATH "/path/to/some/libdir"
  # automatically for any external (to the project) directories
  # that are found in the linker path of project binaries
  INSTALL_RPATH_USE_LINK_PATH TRUE

```

In a scenario like this:

```cmake
add_executable(foo ...)
add_library(bar ...)
set_target_properties(bar PROPERTIES
  SOVERSION 0
)
set_target_properties(foo PROPERTIES
  INSTALL_RPATH_USE_LINK_PATH TRUE
)
target_link_libraries(foo PRIVATE bar /opt/dep/lib/libbaz.so)
install(TARGETS foo bar
  RUNTIME DESTINATION bin
  LIBRARY DESTINATION lib/foo
)

```

Building that project and installing it to `/usr` will cause CMake to install `/usr/bin/foo` with a `RUNPATH` of `/opt/dep/lib`, so that it can find the linked `libbaz.so.1`. But if you also want `/usr/lib/foo` on the `RUNPATH` to find `libbar.so.0`, you have to do that yourself:

```cmake
set_target_properties(foo PROPERTIES
   INSTALL_RPATH "${ORIGIN}/../lib/foo"
)

```

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [August 22, 2024, 7:57am UTC](https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489/4 "2024-08-22T07:57:34Z")

</div>

> [@ferdnyc](#):
>
> Regardless whether they’re set by CMake automatically or manually using `BUILD_RPATH`, by default all of the binaries will be re-linked during install so that the _installed_ binary files have no `RUNPATH` entries.

Excellent response overall, but to correct a small thing in the above, CMake doesn’t relink during install on most platforms now. It has its own code to directly modify the binaries and rewrite the RUNPATH details without needing to re-link. You can force it to do it via re-linking if you really want to, I think there are still some less common platforms where that is still necessary, but for most folks, re-linking is no longer a thing.

---

<div class="post-metadata">

### Author: ![ferdnyc](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ferdnyc/32/267_2.png) [@ferdnyc](https://discourse.cmake.org/u/ferdnyc)
#### Post date: [August 22, 2024, 10:45am UTC](https://discourse.cmake.org/t/bug-with-setting-rpath-in-incremental-builds/11489/5 "2024-08-22T10:45:08Z")

</div>

> [@craig.scott](#):
>
> CMake doesn’t relink during install on most platforms now. It has its own code to directly modify the binaries and rewrite the RUNPATH details without needing to re-link.

D’oh, that’s right, I forgot CMake had acquired `chrpath` technology. 😆
