Installed module library can't find imported headers [Ubuntu 22.04 LTS, CMake 3.28.1, Ninja 1.11.1 and Clang 17.0.6]

The export-* tests here might have a simple case to look at. If something more complicated confuses things, let’s figure out where it breaks down.

I attached a small producer + consumer pair of projects to the following issue recently. It may serve to show you how to do things.

https://gitlab.kitware.com/cmake/cmake/-/issues/25594

I looked at the links you pointed out and ended up making some adjustments to my rules because of this, but they didn’t solve the problem I reported.

However, I noticed that when I added the path of the third party libraries to this IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES variable in the auto-generated CMake file, the compilation worked normally.

Trying to figure out how to make it work, I realized that I had to add:

foreach (DEP ${DEPENDENCIES})
  get_target_property(dep_include_dirs ${DEP} INTERFACE_INCLUDE_DIRECTORIES)
  target_include_directories(${LIBRARY_NAME} PRIVATE ${dep_include_dirs})
endforeach ()

Which I didn’t need before for my headers library :thinking:.

Now it seems to work normally.

Do you link to targets for your dependencies? Can you try to boil this down to a minimal example that I can investigate (assuming it is not covered by Craig’s 25594 example)?

@josecruz Any update on a minimal reproducer?

FWIW, this test shows that includes work, but it is its own provided headers. I’ll try to see about adding a test that transitive dependencies get propagated properly.

I’ve made a reproducer case; tracking it down.

Fix is here: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9265

Sorry for the delay, Ben!

Here’s a minimal example within what I interacted with the problem: GitHub - joseviccruz/cmake-module-error

In this test I use the GoogleTest library, installed in the /opt directory.

The three root scripts execute the installation of a simple library with a header or module in /usr/local and then try to execute that library in another project.

Thanks for the test cases. I tested it with 3.29.0-rc2 and things worked (after making changes to install to $PWD/install and use m gcc build instead).

I have tested it with clang-17 on OSX too, but the error occurs:

bash-5.2$ gmake -n 
cd module-lib && cmake --workflow --preset default --fresh && cmake --build --preset default --target install
cd module-exe && cmake --workflow --preset default --fresh && cmake --build --preset default --target test
cd header-lib && cmake --workflow --preset default --fresh && cmake --build --preset default --target install
cd header-exe && cmake --workflow --preset default --fresh && cmake --build --preset default --target test
TEST_FORCING_MODULE_ERROR=ON gmake working
gmake[1]: Entering directory '/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error'
cd module-lib && cmake --workflow --preset default --fresh && cmake --build --preset default --target install
cd module-exe && cmake --workflow --preset default --fresh && cmake --build --preset default --target test
gmake[1]: Leaving directory '/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error'
bash-5.2$ 
bash-5.2$ make clean
rm -rf build stagedir
bash-5.2$ gmake failing
TEST_FORCING_MODULE_ERROR=ON gmake working
gmake[1]: Entering directory '/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error'
cd module-lib && cmake --workflow --preset default --fresh && cmake --build --preset default --target install
Executing workflow step 1 of 2: configure preset "default"

Preset CMake variables:

  BUILD_SHARED_LIBS="NO"
  CMAKE_BUILD_TYPE="Release"
  CMAKE_CXX_SCAN_FOR_MODULES:BOOL="TRUE"
  CMAKE_CXX_STANDARD="23"
  CMAKE_INSTALL_PREFIX:PATH="/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir"
  CMAKE_PREFIX_PATH:STRING="/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir"
  TEST_FORCING_MODULE_ERROR="ON"

Preset environment variables:

  CPM_USE_LOCAL_PACKAGES="NO"
  PATH="/Users/clausklein/.local/bin:/usr/local/opt/llvm/bin://Users/clausklein/perl5/bin:/usr/local/opt/net-snmp/bin:/usr/local/opt/coreutils/libexec/gnubin:/usr/local/libexec/bin:/usr/local/opt/curl/bin:/usr/local/opt/libxml2/bin:/usr/local/opt/libxslt/bin:/usr/local/opt/expat/bin:/usr/local/opt/net-snmp/bin:/Users/clausklein/Library/Python/3.9/bin:/usr/local/opt/python/libexec/bin:/usr/local/opt/sqlite/bin:/usr/local/bin:/usr/local/sbin:/Users/clausklein/scripts:/Users/clausklein/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/X11/bin:/Library/Apple/usr/bin:/usr/local/MacGPG2/bin:/usr/texbin"

-- The CXX compiler identification is Clang 17.0.6
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/opt/llvm/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Using GTest: 1.14.0
CMake Warning at /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/helpers.cmake:108 (message):
  TEST_FORCING_MODULE_ERROR
Call Stack (most recent call first):
  test-library/CMakeLists.txt:1 (robocin_cpp_library)


-- Configuring done (1.9s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/build/module-lib

Executing workflow step 2 of 2: build preset "default"

[4/4] Linking CXX static library test-library/libtest_class.a
[0/1] Install the project...
-- Install configuration: "Release"
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/include/test-library/test_class.ixx
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/libtest_class.a
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/modules/test_class.ixx
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/modules/test.pcm
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/cmake/module_lib/module_libConfig.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/cmake/module_lib/module_libConfig-release.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/cmake/module_lib/cxx_modules/cxx-modules-module_libTargets.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/cmake/module_lib/cxx_modules/cxx-modules-module_libTargets-Release.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/cmake/module_lib/cxx_modules/target-test_class-Release.cmake
cd module-exe && cmake --workflow --preset default --fresh && cmake --build --preset default --target test
Executing workflow step 1 of 2: configure preset "default"

Preset CMake variables:

  BUILD_SHARED_LIBS="NO"
  CMAKE_BUILD_TYPE="Release"
  CMAKE_CXX_SCAN_FOR_MODULES:BOOL="TRUE"
  CMAKE_CXX_STANDARD="23"
  CMAKE_INSTALL_PREFIX:PATH="/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir"
  CMAKE_PREFIX_PATH:STRING="/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir"
  TEST_FORCING_MODULE_ERROR="ON"

Preset environment variables:

  CPM_USE_LOCAL_PACKAGES="NO"
  PATH="/Users/clausklein/.local/bin:/usr/local/opt/llvm/bin://Users/clausklein/perl5/bin:/usr/local/opt/net-snmp/bin:/usr/local/opt/coreutils/libexec/gnubin:/usr/local/libexec/bin:/usr/local/opt/curl/bin:/usr/local/opt/libxml2/bin:/usr/local/opt/libxslt/bin:/usr/local/opt/expat/bin:/usr/local/opt/net-snmp/bin:/Users/clausklein/Library/Python/3.9/bin:/usr/local/opt/python/libexec/bin:/usr/local/opt/sqlite/bin:/usr/local/bin:/usr/local/sbin:/Users/clausklein/scripts:/Users/clausklein/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/X11/bin:/Library/Apple/usr/bin:/usr/local/MacGPG2/bin:/usr/texbin"

-- The CXX compiler identification is Clang 17.0.6
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/opt/llvm/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Using GTest: 1.14.0
-- Using module_lib: '/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/lib/cmake/module_lib'
-- Configuring done (2.0s)
-- Generating done (0.0s)
CMake Warning:
  Manually-specified variables were not used by the project:

    TEST_FORCING_MODULE_ERROR


-- Build files have been written to: /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/build/module-exe

Executing workflow step 2 of 2: build preset "default"

[1/6] Scanning /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/modules/test_class.ixx for CXX dependencies
FAILED: CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi.ddi 
"/usr/local/Cellar/llvm/17.0.6_1/bin/clang-scan-deps" -format=p1689 -- /usr/local/opt/llvm/bin/clang++ -DPROJECT_PATH=\"/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/module-lib\" -I/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/module-lib -I/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/build/module-lib -O3 -DNDEBUG -std=gnu++23 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk --precompile -x c++ /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/modules/test_class.ixx -c -o CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi -MT CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi.ddi -MD -MF CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi.ddi.d > CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi.ddi.tmp && mv CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi.ddi.tmp CMakeFiles/module_lib__test_class@synth_800cc612d0fe.dir/9ece086e9bac.bmi.ddi
Error while scanning dependencies for /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/modules/test_class.ixx:
/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/stagedir/modules/test_class.ixx:3:10: fatal error: 'gtest/gtest.h' file not found
ninja: build stopped: subcommand failed.
gmake[1]: *** [GNUmakefile:5: working] Error 1
gmake[1]: Leaving directory '/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error'
gmake: *** [GNUmakefile:8: failing] Error 2
bash-5.2$ 

I have tested it on CI with ubuntu 22.04 and it works?
see Use setup-cpp to speeup docker build · ClausKlein/cmake-module-error@5d74595 · GitHub

But on my OSX, I get an error.

snipped of module_libConfig.cmake

# Create imported target module_lib::test_class
add_library(module_lib::test_class STATIC IMPORTED)

set_target_properties(module_lib::test_class PROPERTIES
  IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS "PROJECT_PATH=\"/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/module-lib\""
  IMPORTED_CXX_MODULES_COMPILE_FEATURES "cxx_std_23"
  IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES "/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/module-lib;/Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/build/module-lib"
  IMPORTED_CXX_MODULES_LINK_LIBRARIES "\$<COMPILE_ONLY:GTest::gtest>"
  INTERFACE_COMPILE_FEATURES "cxx_std_23"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "GTest::gtest"
)

IMHO: find_dependency(Gtest) is missing too!

see Use setup-cpp to speeup docker build by ClausKlein · Pull Request #1 · ClausKlein/cmake-module-error · GitHub

The error occurs, if GTest is installed to /opt or /usr/local which are not in default include path!

CMake doesn’t generate anything like that today; you’ll need to provide that call.

But I added it, only it does not help:

include(CMakeFindDependencyMacro)
find_dependency(GTest 1.14 CONFIG REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")

@ben.boeckel It does still not work on OSX. What is different on Apple?

bash-5.2$ find stagedir/include -name gtest.h
stagedir/include/gtest/internal/custom/gtest.h
stagedir/include/gtest/gtest.h

bash-5.2$ ll stagedir/lib/cmake/GTest/*.cmake
-rw-r--r-- 1 clausklein 5.3K Feb 24 22:21 stagedir/lib/cmake/GTest/GTestTargets.cmake
-rw-r--r-- 1 clausklein 2.3K Feb 24 22:21 stagedir/lib/cmake/GTest/GTestTargets-release.cmake
-rw-r--r-- 1 clausklein 1.9K Feb 24 22:21 stagedir/lib/cmake/GTest/GTestConfigVersion.cmake
-rw-r--r-- 1 clausklein 1.1K Feb 24 22:21 stagedir/lib/cmake/GTest/GTestConfig.cmake

bash-5.2$ cmake --version
cmake version 3.28.3
CMake suite maintained and supported by Kitware (kitware.com/cmake).

bash-5.2$ clang --version
Homebrew clang version 17.0.6
Target: x86_64-apple-darwin23.3.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin

bash-5.2$ 

I’ve aso tested it with 3.29.0-rc2 and it worked, thanks!

On OSX too:

bash-5.2$ /Applications/CMake.app/Contents/bin/cmake --version
cmake version 3.29.0-rc2

CMake suite maintained and supported by Kitware (kitware.com/cmake).

bash-5.2$ time ninja
[7/7] Linking CXX executable /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/module-exe/bin/test_main

real	0m2.869s
user	0m2.543s
sys	0m0.309s
bash-5.2$ bash-5.2$ ctest
Test project /Users/clausklein/Workspace/cpp/cxx20/cmake-module-error/build/module-exe
    Start 1: test_main
1/1 Test #1: test_main ........................   Passed    0.10 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.11 sec
bash-5.2$ 

3.28.4 will include the fix.

1 Like