Module not found error on 3.28

Hello, I’m trying to integrate the new modules functionality into a project. I’m currently having issues with the module not being found when I import it.

I’ve added this to my CMakeLists:

file(GLOB_RECURSE TEST_MODULE_FILES
    src/unit_tests/*.cppm
)

# print test_module_files
message("Test module files: ${TEST_MODULE_FILES}")

add_library(tests_modules)

target_sources(tests_modules PUBLIC
FILE_SET CXX_MODULES
FILES ${TEST_MODULE_FILES}
)

add_executable(tests ${UNIT_TESTING_FILES})
target_link_libraries(tests Catch2::Catch2WithMain core tests_modules)

In test.cppm I’m doing:

export module foo;

And in another file I have the import. However on build I get:
…/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp:1:8: fatal error: module ‘foo’ not found
import foo;

I’m using conan so I have a build directory /build/Debug/, could this be causing this? I’ve run the basic example with foo.cxx in a different directory and that one works fine.

Any help would be appreciated.

You should set your minimum CMake version to 3.28. Sources that are not in a FILE_SET TYPE CXX_MODULES cannot use modules (by default) if CMP0155 is OLD. You can also use CMAKE_CXX_SCAN_FOR_MODULES

I’ve set:
cmake_minimum_required(VERSION 3.28 FATAL_ERROR)
set(CMP0155 NEW)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)

I’ve also confirmed that the file with the export foo is contained inside of TEST_MODULE_FILES, so that file should have FILE_SET CXX_MODULES.

However I am still getting the same error. That said, I was going through the build directory and foo.pcm is being built. I can also see that the module is being picked up by tests (build/Debug/CMakeFiles/tests.dir):

...
	"language" : "CXX",
	"linked-target-dirs" : 
	[
		"/home/nicobuzeta/Documents/CORE_Project/CORE/build/Debug/CMakeFiles/tests_modules.dir"
	],
	"module-dir" : "/home/nicobuzeta/Documents/CORE_Project/CORE/build/Debug/CMakeFiles/tests.dir"

and

{
	"modules" : {},
	"references" : 
	{
		"foo" : 
		{
			"lookup-method" : "by-name",
			"path" : "CMakeFiles/tests_modules.dir/foo.pcm"
		}
	},
	"usages" : {}
}

In the tests_modules.dir, I can also see that it is suppose to provide the module:

{
	"modules" : 
	{
		"foo" : 
		{
			"bmi" : "/home/nicobuzeta/Documents/CORE_Project/CORE/build/Debug/CMakeFiles/tests_modules.dir/foo.pcm",
			"is-private" : false
		}
	},
	"references" : 
	{
		"foo" : 
		{
			"lookup-method" : "by-name",
			"path" : "CMakeFiles/tests_modules.dir/foo.pcm"
		}
	},
	"usages" : {}
}

In the common.cpp.o.modmap I also have:

-fmodule-file=foo=CMakeFiles/tests_modules.dir/foo.pcm

However I still get:

FAILED: CMakeFiles/tests.dir/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp.o
/usr/bin/clang++ -DCORE_DEBUG -DSODIUM_STATIC -DZMQ_STATIC -I/home/nicobuzeta/Documents/CORE_Project/CORE/src -isystem /home/nicobuzeta/.conan2/p/b/catchf35de5ff3cba0/p/include -isystem /home/nicobuzeta/.conan2/p/b/antlr5086bea15e1a6/p/include -isystem /home/nicobuzeta/.conan2/p/b/antlr5086bea15e1a6/p/include/antlr4-runtime -isystem /home/nicobuzeta/.conan2/p/cerea4cf7b92f85513/p/include -isystem /home/nicobuzeta/.conan2/p/cppzm2f79d96f7bf7d/p/include -isystem /home/nicobuzeta/.conan2/p/b/zerom0e2769d339b1b/p/include -isystem /home/nicobuzeta/.conan2/p/b/gmp8c97d807dd3b9/p/include -isystem /home/nicobuzeta/.conan2/p/b/libpq695142905b307/p/include -isystem /home/nicobuzeta/.conan2/p/b/re2cb33528ec219e/p/include -isystem /home/nicobuzeta/.conan2/p/b/absei0f32c883e8661/p/include -isystem /home/nicobuzeta/Documents/CORE_Project/CORE/build/Debug/_deps/tracy-src/public -m64 -stdlib=libstdc++ -g -g -std=gnu++20 -Werror=old-style-cast -MD -MT CMakeFiles/tests.dir/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp.o -MF CMakeFiles/tests.dir/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp.o.d @CMakeFiles/tests.dir/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp.o.modmap -o CMakeFiles/tests.dir/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp.o -c /home/nicobuzeta/Documents/CORE_Project/CORE/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp
/home/nicobuzeta/Documents/CORE_Project/CORE/src/unit_tests/core_server/internal/evaluation/evaluation_algorithm/common.cpp:1:8: fatal error: module 'foo' not found

CMP0155 is a policy, not a variable. Not that either of the set() calls matter here given the 3.28 minimum.

What do you mean “foo.cxx in a different directory”?

What version of clang?

I mean I followed this https://www.kitware.com/import-cmake-the-experiment-is-over/ and the module worked in a new project.

Clang is version 16.0.6.

tests.dir
CXXModules.json (161 Bytes)
CXXDependInfo.json (1.4 KB)

tests_modules.dir
CXXModules.json (161 Bytes)
CXXDependInfo.json (1.4 KB)

CMakeLists.txt (5.2 KB)

Clang 16 does not support GNU extensions when using modules. Set CMAKE_CXX_EXTENSIONS to OFF or upgrade to Clang 17.

I already have:
set(CMAKE_CXX_EXTENSIONS OFF)

In my last post I sent a copy of my CMakeLists.txt.

This is all the settings I have:
cmake_minimum_required(VERSION 3.28 FATAL_ERROR)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)

I figured out the problem, I accidently moved the project declaration in the CMakeLists.txt so I had:
cmake_minimum_required(VERSION 3.28 FATAL_ERROR)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)

project (core CXX)

I’ve moved the project declaration above those lines and it has fixed all the issues. That said, I am not very familiar with CMake. Why is having the project declaration below those lines break it? Do the settings not get applied unless the project gets declared beforehand?

Not sure exactly why these would be “ignored”, but project is where CMake detects compilers and sets up support bits based on that. checking those variable values after the project might serve some insight.