How to set dyld path via FindPackage(Boost)?

I encountered a problem:

I have myself-built boost libraries which FindBoost module finds perfectly, but when I look built binary with otool -L I see not full paths of boost libraries, but only their names:

(venv) ➜  target git:(fix/refactor-gitignore-and-readme) ✗ otool -L Desbordante_test 
Desbordante_test:
        libboost_graph-xgcc14-mt-a64-1_86.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_container-xgcc14-mt-a64-1_86.dylib (compatibility version 0.0.0, current version 0.0.0)
        libboost_thread-xgcc14-mt-a64-1_86.dylib (compatibility version 0.0.0, current version 0.0.0)
        /opt/homebrew/opt/gcc/lib/gcc/current/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.33.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.120.2)

At the same time when I use Apple Clang and Homebrew boost the binary looks like:

(venv) ➜  Desbordante git:(apple-clang-buildability) ✗ otool -L build/target/Desbordante_test
build/target/Desbordante_test:
	/opt/homebrew/opt/boost/lib/libboost_graph.dylib (compatibility version 0.0.0, current version 0.0.0)
	/opt/homebrew/opt/boost/lib/libboost_container.dylib (compatibility version 0.0.0, current version 0.0.0)
	/opt/homebrew/opt/boost/lib/libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1800.105.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)

Actually, In first case there is no problem with Desbordante_test, it finds boost libraries in usr/local/include fine and I don’t know why? But another binary with same otool -L output which is Python module not works:

>>> import desbordante
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/vdaleke/Documents/desbordante-core/venv/lib/python3.12/site-packages/desbordante.cpython-312-darwin.so, 0x0002): Library not loaded: libboost_container-xgcc14-mt-a64-1_86.dylib
  Referenced from: <5DE266BA-6882-3835-BB89-3E13967FF861> /Users/vdaleke/Documents/desbordante-core/venv/lib/python3.12/site-packages/desbordante.cpython-312-darwin.so
  Reason: tried: 'libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibboost_container-xgcc14-mt-a64-1_86.dylib' (no such file), 'libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file), '/usr/lib/libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file, not in dyld cache), '/Users/vdaleke/Documents/desbordante-core/libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/vdaleke/Documents/desbordante-core/libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file), '/Users/vdaleke/Documents/desbordante-core/libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file), '/usr/lib/libboost_container-xgcc14-mt-a64-1_86.dylib' (no such file, not in dyld cache)

And another binary built with brew boost and Apple Clang works fine.

So, i’m trying to understand how brew forces path into DYLD_PATH and do it too. And other question is how FindBoost module find brew boost in opt/homebrew without any hints?

Thank you.

Dear Matvey,

I wanted to write here, since by chance I was dealing with a very similar thing around BoostConfig.cmake in the last few days. Though I fear that my very specific setup/solution will not help you too much in the end. :slightly_frowning_face:

As you probably know, CMake gives no direct support for projects modifying their runtime environments. Most simple projects don’t need to do this to begin with, so this seems fair. But in our own setup we have to generate a runtime environment based on what external projects CMake used to build our code. (It’s a long story…) We do this by our CMake configuration generating setup.sh scripts that get installed along with our binaries. So that one has to source the appropriate script from the appropriate installation directory, to use that version of our software in a terminal session. (Again, longer story in the background here.)

As it happens, the recent change in CMake 3.30 with deprecating FindBoost.cmake (which itself is a quite understandable move) made things a bit difficult for us with this as well. Since while FindBoost.cmake provides a Boost_LIBRARY_DIRS variable that we could easily use in our environment setup scripts, BoostConfig.cmake coming with the Boost installations, has no such thing. :cry: So I had to write some code that would figure out the library directory from stuff that BoostConfig.cmake does provide. (In the unlikely case that you’d be interested in the details of this, I’m happy to share what I did.)

With all this being said… On macOS you should really just be thinking about setting RPATH correctly on your binaries. :thinking: Apple clearly decided a while ago that DYLD_LIBRARY_PATH is evil, and every binary should hard-code in itself with absolute path names what libraries it will want to load at runtime. (Making relocating binaries quite the pain…) So as long as you don’t absolutely need to use DYLD_LIBRARY_PATH for some reason, the following should get you started with setting up the use of RPATH in your build configuration:

https://duerrenberger.dev/blog/2021/08/04/understanding-rpath-with-cmake/

Cheers,
Attila