jeremy-rifkin / cpptrace

Simple, portable, and self-contained stacktrace library for C++11 and newer
MIT License
621 stars 64 forks source link

How do I propagate export of `cpptrace` and its dependencies through CMake's `FetchContent`? #149

Closed vittorioromeo closed 1 month ago

vittorioromeo commented 1 month ago

I have started using cpptrace in my fork of SFML, which has been immensely helpful for assertions and error logging -- great work!

The way I use it is as follows:

# SFML/CMakeLists.txt

# ...
include(FetchContent)
FetchContent_Declare(
    cpptrace
    GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git
    GIT_TAG        v0.6.2 
)

FetchContent_MakeAvailable(cpptrace)
# ...
# SFML/src/SFML/System/CMakeLists.txt

# ...
target_link_libraries(sfml-system PUBLIC cpptrace::cpptrace)
# ...

This works fine when building SFML and its test suite in isolation. However, I have another project, imgui-sfml, which depends on my fork of SFML:

# imgui-sfml/CMakeLists.txt

# ...
find_package(SFML 3 REQUIRED COMPONENTS Graphics)
# ...

After building SFML locally and installing it with ninja install, I direct imgui-sfml to its installation folder:

cd imgui-sfml && mkdir build && cd build
cmake .. -DSFML_DIR="C:/OHWorkspace/SFML/build/installed"

This fails with the following error message:

Make Error at C:/msys64/ucrt64/share/cmake/Modules/CMakeFindDependencyMacro.cmake:76 (find_package):
  By not providing "Findcpptrace-lib.cmake" in CMAKE_MODULE_PATH this project
  has asked CMake to find a package configuration file provided by
  "cpptrace-lib", but CMake did not find one.

  Could not find a package configuration file provided by "cpptrace-lib" with
  any of the following names:

    cpptrace-libConfig.cmake
    cpptrace-lib-config.cmake

  Add the installation prefix of "cpptrace-lib" to CMAKE_PREFIX_PATH or set
  "cpptrace-lib_DIR" to a directory containing one of the above files.  If
  "cpptrace-lib" provides a separate development package or SDK, be sure it
  has been installed.
Call Stack (most recent call first):
  C:/OHWorkspace/SFML/build/installed/lib/cmake/SFML/SFMLConfigDependencies.cmake:32 (find_dependency)
  C:/OHWorkspace/SFML/build/installed/lib/cmake/SFML/SFMLConfig.cmake:125 (include)
  CMakeLists.txt:28 (find_package)

CMake Error at CMakeLists.txt:28 (find_package):
  Found package configuration file:

    C:/OHWorkspace/SFML/build/installed/lib/cmake/SFML/SFMLConfig.cmake

  but it set SFML_FOUND to FALSE so package "SFML" is considered to be NOT
  FOUND.  Reason given by package:

  The following imported targets are referenced, but are missing:
  cpptrace::cpptrace

I attempted to fix this by exporting cpptrace-lib from SFML/CMakeLists.txt:

# SFML/CMakeLists.txt

# ...
include(FetchContent)
FetchContent_Declare(
    cpptrace
    GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git
    GIT_TAG        v0.6.2 
)

FetchContent_MakeAvailable(cpptrace)

install(TARGETS cpptrace-lib EXPORT SFMLConfigExport) # <--
# ...

But then I get the same error message when trying to build imgui-sfml, but for libdwarf:

[...]

The following imported targets are referenced, but are missing:
  libdwarf::dwarf

What is the proper way of exporting cpptrace and propagating its dependencies?

jeremy-rifkin commented 1 month ago

Hi, I'm glad you're finding the library useful!

Unfortunately I'm not an expert in cmake but I have some guesses about what might be going on here. I would expect your SFML fork to have installed cpptrace to C:/OHWorkspace/SFML/build/installed along with SFML (and any dependencies cpptrace brings in, like libdwarf and zstd on linux or windows with mingw). -DSFML_DIR tells cmake where to find the SFML install but it probably doesn't know where to look for cpptrace or additional dependencies. It may just work if you use -DCMAKE_PREFIX_PATH=C:/OHWorkspace/SFML/build/installed, otherwise -DCPPTRACE_DIR=C:/OHWorkspace/SFML/build/installed -DDWARF_DIR=C:/OHWorkspace/SFML/build/installed -DZSTD_DIR=C:/OHWorkspace/SFML/build/installed may be needed. This path propagation could be done automatically in SFMLConfig.cmake.in as well:

set(CPPTRACE_DIR ${SFML_DIR})
...

I hope this helps, if it doesn't I'd be happy to look more!

jeremy-rifkin commented 1 month ago

Hi, I haven't heard back so I'll close this for now but please let me know if you have any other questions!