Bug 258946 - devel/libfmt: Installs a broken CMake config file
Summary: devel/libfmt: Installs a broken CMake config file
Status: Open
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Po-Chuan Hsieh
Keywords: needs-patch, needs-qa
Depends on:
Reported: 2021-10-05 12:52 UTC by David Chisnall
Modified: 2021-12-04 15:55 UTC (History)
2 users (show)

See Also:
koobs: merge-quarterly?


Note You need to log in before you can comment on or make changes to this bug.
Description David Chisnall freebsd_committer 2021-10-05 12:52:47 UTC
The file /usr/local/lib/cmake/fmt/fmt-config-version.cmake is installed by libfmt, on the default search path for CMake.  

Because the FreeBSD compilers and linkers do not search the OS default install locations for headers or libraries, this file needs to add them.  It does not, and so CMake happily reports that fmt is found, but fails to link it.  

The correct fix for this is to add /usr/local/include and /usr/local/lib to the search paths for FreeBSD versions of clang and gcc but until then ports need to work around this.
Comment 1 Po-Chuan Hsieh freebsd_committer 2021-10-25 16:14:18 UTC
What kind of build failure do you encounter? Patch is welcomed.
Comment 2 Adriaan de Groot freebsd_committer 2021-11-11 21:30:08 UTC
I can't reproduce this problem on 13- with CMake 3.21.3 (which I think is current ports version). Here's a very very simple CMakeLists.txt:

cmake_minimum_required(VERSION 3.20 FATAL_ERROR)

find_package(fmt REQUIRED)

if(NOT EXISTS "main.cc")
    file(WRITE "main.cc" "#include <fmt/core.h>\nint main() { fmt::print(\"Hello World\\n\"); }\n")

add_executable(demo main.cc)
target_link_libraries(demo fmt::fmt)

I have libfmt 8.0.1 from ports installed. I run the following in a directory containing just that CMakeLists.txt (it will create a source file to compile):

cmake .
make VERBOSE=1

CMake indicates doesn't complain, finds the *fmt* package (see the resulting CMakeCache.txt for confirmation) and the build looks like

[ 50%] Building CXX object CMakeFiles/demo.dir/main.cc.o
/usr/bin/c++ -DFMT_SHARED -isystem /usr/local/include  -MD -MT CMakeFiles/demo.dir/main.cc.o -MF CMakeFiles/demo.dir/main.cc.o.d -o CMakeFiles/demo.dir/main.cc.o -c /tmp/pr-258946/main.cc

(Note FMT_SHARED comes from the `fmt-targets.cmake` file, as does the `-I` flag)

Linking, in turn, does

[100%] Linking CXX executable demo
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/demo.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/demo.dir/main.cc.o -o demo  -Wl,-rpath,/usr/local/lib /usr/local/lib/libfmt.so.8.0.1 -Wl,--as-needed 

David, can you elaborate?
Comment 3 David Chisnall freebsd_committer 2021-12-03 15:35:27 UTC
This problem went away for me on 12.x but on a newly built FreeBSD main branch (pre-14.0) from git, installed in a pristine VM (built with poudriere-image) with cmake 3.21.4_1 and libfmt-8.0.1 installed from packages, the same problem exists.

With both the CMake and Ninja generators, your test case fails for me with:

/root/tmp/main.cc:1:10: fatal error: 'fmt/core.h' file not found

The compile line is:

/usr/bin/c++ -MD -MT CMakeFiles/demo.dir/main.cc.o -MF CMakeFiles/demo.dir/main.cc.o.d -o CMakeFiles/demo.dir/main.cc.o -c /root/tmp/main.cc

In ccmake, I see `fmt_DIR` is set to `/usr/local/lib/cmake/fmt`, so it is definitely finding libfmt, but is not installing anything.  If I do `cmake --trace` then I see that it's using both fmt-targets.cmake and fmt-config.cmake, but it's not adding any of the flags from there.
Comment 4 Adriaan de Groot freebsd_committer 2021-12-04 15:55:49 UTC
On a not-quite-pristine 14- installation, with CMake 3.21.4, I still can't reproduce the problem. Could you, David, attach your /usr/local/lib/cmake/fmt/fmt-config.cmake and /usr/local/lib/cmake/fmt/fmt-targets.cmake and /usr/local/lib/cmake/fmt/fmt-targets-release.cmake? Because this is getting kinda weird.

If you take a look at the trace, eg from running

rm CMakeCache.txt ; cmake --trace . -DCMAKE_BUILD_TYPE=wibble

You **ought** to see at least this line in the trace-output:

/usr/local/lib/cmake/fmt/fmt-targets.cmake(56):  set_target_properties(fmt::fmt PROPERTIES INTERFACE_COMPILE_DEFINITIONS FMT_SHARED INTERFACE_COMPILE_FEATURES cxx_variadic_templates INTERFACE_INCLUDE_DIRECTORIES ${_IMPORT_PREFIX}/include INTERFACE_LINK_LIBRARIES -Wl,--as-needed )

You might try also to add this to your invocation of cmake:


Just in case there's a wandering package left behind somewhere.