Undefined Reference error using modules in C++23 with clang and cmake

Hello,

I’m getting started with C++23 modules and trying to use them in a personal project.

The plan is to create an executable for the entire project, which would contain the output of all unit tests.

Each source cpp file has an implementation and a unit test. The module cppm file exports unit tests from all source files in the same directory.

These exported unit tests are then called in main.cpp.

The project layout is:

.
|---- CMakeLists.txt
|---- src
|      |---- foo
|             |---- add.cpp
|             |---- subtract.cpp
|             |---- foo.cppm
|
|---- main.cpp

As I make more progress on this project, there will be other directories in src/ similar to foo/.

Below are the file contents (collapsing to improve overview)

`src/foo/add.cpp` (`subtract.cpp` is similar)
import std;
#include <cassert>

class AddNumbers {
public:
    int add(int a, int b) {
        return a + b;
    }
};

void testAddNumbers() {
    AddNumbers solution;

    int result = solution.add(2, 2);
    int expected = 4;

    assert(result == expected); // Assert the result
}
`src/foo/foo.cppm`
export module foo;

export void testAddNumbers();
export void testSubtractNumbers();
`src/main.cpp`
import foo;

int main() {
    testAddNumbers();
    testSubtractNumbers();

    return 0;
}
`CMakeLists.txt`
cmake_minimum_required(VERSION 3.31)

set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
set(CMAKE_CXX_MODULE_STD ON)
set(CXXFLAGS "-Wall -Werror -O2 -Wno-error=sign-compare -Wno-pre-c++20-compat -std=c++23 -stdlib=libc++")
set(CMAKE_CXX_FLAGS "${CXXFLAGS}")
set(CMAKE_CXX_COMPILER clang++)

project(testmod VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS ON)

add_executable(testmod)
target_sources(testmod
    PUBLIC
    src/main.cpp
)
target_sources(testmod
  PUBLIC
    FILE_SET testmods TYPE CXX_MODULES
    BASE_DIRS
      ${PROJECT_SOURCE_DIR}
    FILES
      src/foo/foo.cppm
)

I’m compiling and building this project like:

cmake -G Ninja -S . -B build
ninja -C build

and on the second command I’m getting an error:

main.cpp:(.text+0x2): undefined reference to `testAddNumbers@foo()'
main.cpp:(.text+0x7): undefined reference to `testSubtractNumbers@foo()'

How can get the project to work correctly ?

Add a module foo; to the top of add.cpp and subtract.cpp without this, the compiler has no idea that the defined testAddNumbers symbol is part of the foo module and instead just makes a global module symbol instead.