Deep CMake for Library Authors - Craig Scott - CppCon 2019
Why Stack Overflow recommends it
Stack Overflow users link it when answering CMake questions about shared library symbol visibility, RPATH and $ORIGIN at install time, and avoiding target name clashes.
Recommended by 5 people across 5 different months, 2020 to 2024.
What it is
A CppCon 2019 talk by Craig Scott, a CMake maintainer, giving C++ library authors a road map for cross-platform builds. It covers symbol visibility, library versioning, install directory layout, RPATH/RUNPATH handling, and naming conventions for targets and packages.
What people said
Recommends kdmarrett · 2020-04 · Stack Overflow · on “CMAKE RPATH not working - could not find shared object file”
I had a similar issue as the original post. I created executables which linked to external shared libraries. This approach compiled and executed fine from the build directory. However, the executable that was installed to a separate directory could not find a shared library at runtime: error while loading shared libraries: libxxxx.so.1: cannot open shared object file: No such file or directory To solve, I 1) upgraded to CMake 3.17 2) used Craig Scott's recommended: set(CMAKE_INSTALL_RPATH $ORIGIN) as explained in his talk [this video] 3) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) as directly mentioned to solve this error in the second common question in Kitware's documention [LINK] 4) Put all th
Recommends Kevin · 2020-07 · Stack Overflow · on “What is the use of .cmake files in install function of CMakeLists.txt?”
You may find the introductory description here [LINK] helpful. The <Package>Config.cmake files are package configuration [LINK] files. They are useful for providing a minimal set of information about an installed package, so the consumer of the package can easily use it in their CMake project. As a package maintainer of a CMake-based project, you are highly encouraged (and frankly, expected) to provide such a file, as this is the most efficient way for others to integrate your library into their project. The consumer of your package will typically use find_package [LINK] to find the installed package: find_package(SomePackage REQUIRED) The search procedure for find_package Config Mode [LINK]
Recommends Dudly01 · 2021-10 · Stack Overflow · on “How to configure CMakeLists.txt to install public headers of a shared library?”
The Cmake install documentation [LINK] has almost the same proposal as ComicSansMS. The following example shows how to follow this advice ( mentioned earlier in the documentation ) while installing headers to a project-specific subdirectory: include(GNUInstallDirs) install(FILES mylib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproj ) In this solution, the destination is not hard coded, but uses variable defined by the GNUInstallDirs Cmake module (and adds the subdirectory after a slash). Using variables make things more flexible for package maintainers and the default value of the variable may be system specific. (May not specific for CMAKE_INSTALL_INCLUDEDIR but definitely system specific
Recommends Alex Reinking · 2022-07 · Stack Overflow · on “How can I avoid clashes with targets "imported" with FetchContent_MakeAvailable?”
In the current CMake (<=3.24) world, there are no features for adjusting the names of the targets in other black-box projects, whether included via find_package , add_subdirectory , or FetchContent . Thus, for now, it is incumbent on you to avoid name-clashes in targets, install components, test names, and anywhere else this could be a problem. Craig Scott says as much in his (very good) talk at CppCon 2019, see here: [this video] The convention he proposes is to use names that are prefixed with SomeProj_ . He doesn't suggest to literally use ${PROJECT_NAME}_ , and I wouldn't either, because doing so makes the code harder to read and grep (which is extremely useful for understanding a 3rd-party b
Recommends Jorge Bellon · 2023-04 · Stack Overflow · on “Boost dependency crashing ableton on mac OS”
Even if you link statically there can be symbol clash. Make sure you only export the symbols you need. If you build your plugin using CMake, you can create an exports header with GenerateExportHeader [LINK] , then define the visibility of all symbols to be hidden and finally mark your types as exported `class MyPlugin PLUGIN_API { ... };` Check out Craig Scott's presentation [this video] where it explains what the CMake function is doing and why this is useful. (Basically you want to hide boost symbols)
Cites Oshio · 2020-05 · Stack Overflow · on “CMake install dependencies”
Craig, can you take a look at my related question [LINK] ? Before asking I read this post and watched one of your talks [this video] at CppCon 2019.
Cites user12322620 · 2020-11 · Stack Overflow · on “Unable to generate a shared library using cmake”
Looks like a symbol visibility issue. By default on clang/gcc symbols are hidden. There is a cppcon talk that talks about this: [this video] Basically either this library doesn't support being built as a shared library. Or you need to enable that functionality somehow. Or just force symbol visibility on.
Cites icebp · 2021-05 · Stack Overflow · on “What is the one-step process to clone a repo and run a CMake+vcpkg project, not assuming vcpkg exists?”
There's nothing wrong in assuming that the user has certain tools installed. Let's say you are developing libfoo which depends on libbar and you want to make it as easy as possible for your users to install libfoo . With a package manager If libfoo and libbar are available via the same package manager all your users have to do is: vcpkg install libbar libfoo You don't have to do anything special in libfoo for this, just instruct the user to install all dependencies in your readme. It doesn't really matter what package manager is used. Without a package manager You will still want to make it easy for people to build and install your project directly. It may seem that invoking a package manage
Cites Alex Reinking · 2021-08 · Stack Overflow · on “add extern cmake directory without building it”
If you want to build them entirely separately, you will need to go through the find_package infrastructure. Here's a complete example: Project A lib.h #ifndef LIB_H #define LIB_H int lib(); #endif lib.c #include "lib.h" int lib() { return 42; } CMakeLists.txt cmake_minimum_required(VERSION 3.21) project(projA) add_library(lib lib.c) target_include_directories(lib PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>") # Export the target named lib for use in other projects # from the build tree of this project. export(TARGETS lib FILE projA-config.cmake) Project B main.c #include <stdio.h> #include <lib.h> int main () { printf("%d\n", lib()); } CMakeLists.txt cmake_minimum_required(VERSION
Cites starball · 2023-10 · Stack Overflow · on “What is the $ORIGIN token in CMake?”
It doesn't really have anything in particular to do with CMake- more with library loaders. Some platforms treat the token " $ORIGIN " with a special meaning. For example, quoting from the man page for ld.so 's section named "Dynamic string tokens": $ORIGIN (or equivalently ${ORIGIN} ) This expands to the directory containing the program or shared object. Thus, an application located in somedir/app could be compiled with gcc -Wl,-rpath,'$ORIGIN/../lib' so that it finds an associated shared object in somedir/lib no matter where somedir is located in the directory hierarchy. This facilitates the creation of "turn-key" applications that do not need to be installed into special directories, but c