Here's a summary of the provided transcript in a self-contained bullet list format, including timestamps, important details, and key takeaways:
Writing Clean CMake Code for C++ Libraries: A Guide for Library Developers
0:00:02 Introduction: The talk focuses on writing clean CMake code specifically for C++ library developers, emphasizing the difference in how libraries are consumed compared to applications.
0:00:51 Library Integration Challenges: Integrating third-party libraries often involves interacting with their build files, highlighting the importance of clean CMake code for easy integration. Poorly written CMake can cause significant problems for integrators.
0:04:01 Goal: The talk outlines five key points to make it easy for users to build and use a library, improving the overall build experience.
0:05:04 Point 1: Use CMake: Despite the existence of other build systems (Bazel, etc.), CMake remains the dominant choice for C++ libraries in 2024, according to survey data (77%). Other tools mentions were Make, MSBuild, Ninja, QMake, and Basil.
0:10:06 Point 2: Understand CMake Internally: Analogous to understanding Git's internals, understanding how CMake works (target-centric approach) is crucial for writing clean CMake files. Avoid the outdated global variable approach.
0:15:15 Modern vs Old: Avoid using outdated global settings like include_directories and link_libraries. Use a target centric approach.
0:18:51 CMake's Internal Model: CMake uses a target-centric model. Entities (executables, libraries, tests) are targets with properties that control the build process. Properties can be private or interface (propagated to dependent targets).
0:22:56 Point 3: Install Your Library Correctly: Properly installing a library involves packaging compiled libraries, header files, and usage information (where headers are, library names, additional defines) for consumers. The package should be relocatable.
0:25:16 Install Commands: Use install(TARGETS ...) and install(FILE_SET ...) to package libraries and headers. CMake generates foo-targets.cmake and foo-targets-config-version.cmake to provide usage information. A foo-config.cmake file is also needed.
0:28:53 Alias Targets: Create alias targets (e.g., add_library(foo::foo ALIAS foo)) so the library can be referenced the same way internally and externally.
0:30:21 Point 4: Handle Dependencies Properly: Avoid vendoring dependencies (including them directly in your build) for libraries. Use find_package to locate dependencies. Vendoring can lead to version conflicts.
0:34:58 Alternatives to Vendoring: Use dependency providers (CMake 3.24+) or find_dependency (for older CMake versions) to manage dependencies externally.
0:36:08 Modern Dependency Handling: Use target_link_libraries with exported targets (e.g., foo::foo) instead of outdated approaches that use variables with hardcoded paths.
0:38:18 Be Explicit with Dependencies: Don't implicitly include optional dependencies based on their presence. Use options (e.g., option(BUILD_WITH_JPEG "Build with JPEG support" ON)) and find_package(JPEG REQUIRED) to make dependencies explicit and builds deterministic.
0:40:18 Point 5: Keep CMakeLists.txt Clean: Treat CMake code like production code (DRY, meaningful names). Distinguish build settings from usage requirements. Long, cluttered CMake files are a problem.
0:41:54 Separate Build Settings: Inject build settings (compiler, flags) from the outside (command line, presets) instead of hardcoding them in CMakeLists.txt.
0:48:14 CMake Presets: Use CMake presets (CMake 3.19+) to separate build logic from configuration. Presets allow for reusable and composable build configurations.
0:49:28 Usage vs Build: Think carefully of what are usage requirements. Communicate requirements to the user but leave optional build settings to the user.
0:50:26 Conclusion: Summarizes the five points. Following these guidelines improves the user experience for those integrating the library.
0:51:33 Q&A: Handling Multiple Library Versions: The speaker recommends resolving build dependencies to avoid needing multiple versions of the same library, as this can lead to runtime issues. Conan can help.
0:52:49 Q&A: Fetch Content and Find Package: A commenter points out that fetch_content and find_package are now tightly coupled, and fetch_content can be instructed to try find_package first. Conan 2 relies heavily on the dependency provider feature (CMake 3.24+).
0:55:11 Q&A: Static Libraries and Dependencies: CMake's target_link_libraries handles transitive dependencies automatically, even for static libraries. The user only needs to link against the top-level library.
0:56:16 Q&A: Exporting Internally Built Libraries: Exporting libraries is necessary if they are to be used by others outside the main project. If the libraries are only used internally within a monorepo, exporting is not needed.
0:57:12 Q&A: Interface Library for Compiler Settings: Answering a question regarding whether to make an interface library to hold common compile settings, the speaker says if resources need the settings, that it is an OK approach.
0:58:46 Q&A: CMake presets issues: There is a combinitorial explosion issue with too many settings and presets, and requires generating presets.
01:00:25 Q&A CPack: The speaker does not use CPack in the company setup, indicating they are not a huge fan.