I’ve spend a lot of time trying to figure out an issue of compiling the solution for my studies using the cpp 20 modules in dynamic linked library. I’ve got my project structure as following:
- Main soluition directory
CMakeLists.txt
-- Application directory (sources for executable)
--- headers
.h files
--- resources
some resources for project
--- src
.cpp files
-- Library directory (some classes for project)
--- includes
.h files
--- interfaces
.ixx file (the module itself)
As you can see the solution contains two folders and I’ve got 1 Cmake file in parent folder to compile both exe and dll from there. Thing is – as if this would work with classic header includes, it doesn’t with modules as the compilation order matters now as I learned. I’m just learning and the info on how to work with modules is scarce, I couldn’t find how to order up my CMake lists to make this work pure via console.
Problem is that when running cmake to build the project – it won’t find the dll’s .o file and fails to building linking. The dll must be compiled up front somehow.
When I open the project in VS studio I’m able to build it if I order VS to build the .dll first and THEN order to build all. Then it successfully complies everything as the files from modules are supposedly built upfront and used later.
Did anyone had any experience on how to structure the CMake file, maybe with subfolder directives and separated CMake lists, to make it run properly?
I’ve got a CMakeLists.txt in parent directory like this:
cmake_minimum_required(VERSION 3.14.0)
set (CMAKE_CXX_STANDARD 20)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
project(RaceGame)
include_directories(
${PROJECT_SOURCE_DIR}/RaceApp/headers
${PROJECT_SOURCE_DIR}/RaceApp/src
${PROJECT_SOURCE_DIR}/RaceLib/interfaces
${PROJECT_SOURCE_DIR}/RaceLib/includes
)
link_directories(${PROJECT_SOURCE_DIR}/RaceApp/interaces)
file(GLOB Lib_SRCS
"${PROJECT_SOURCE_DIR}/RaceLib/interfaces/*.ixx"
"${PROJECT_SOURCE_DIR}/RaceLib/includes/*.h"
)
file(GLOB App_SRCS
"${PROJECT_SOURCE_DIR}/RaceApp/headers/*.h"
"${PROJECT_SOURCE_DIR}/RaceApp/src/*.cpp"
)
configure_file(${PROJECT_SOURCE_DIR}/RaceApp/resources/botnames.txt botnames.txt COPYONLY)
configure_file(${PROJECT_SOURCE_DIR}/RaceApp/resources/botcallsigns.txt botcallsigns.txt COPYONLY)
add_library(RaceLib SHARED ${Lib_SRCS} "RaceLib/includes/RaceLibExceptions.h")
add_executable(RaceGame ${App_SRCS} "RaceLib/includes/RaceLibExceptions.h")
target_link_libraries(RaceGame RaceLib)
I’ve been trying many different ideas but I just have not enough experience with CMake to work this out.
————— EDITED
cmake command output:
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/JINX/DEVELOPMENT/CRaceGame/build
cmake –build command output
[ 20%] Building CXX object CMakeFiles/RaceLib.dir/RaceLib/interfaces/RaceLib.ixx.o
c++: warning: /home/JINX/DEVELOPMENT/RaceGame/RaceLib/interfaces/RaceLib.ixx: linker input file unused because linking not done
[ 40%] Linking CXX shared library libRaceLib.so
c++: error: CMakeFiles/RaceLib.dir/RaceLib/interfaces/RaceLib.ixx.o: No such file or directory
make[2]: *** [CMakeFiles/RaceLib.dir/build.make:97: libRaceLib.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/RaceLib.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
———————– EDIT 2
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
set (CMAKE_CXX_STANDARD 20)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (CMAKE_VERSION VERSION_LESS "3.26")
# 3.25
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
elseif (CMAKE_VERSION VERSION_LESS "3.27")
# 3.26
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
else ()
message(FATAL_ERROR "See `https://github.com/Kitware/CMake/blob/v${CMAKE_VERSION}/Help/dev/experimental.rst`.")
endif (CMAKE_VERSION VERSION_LESS "3.26")
# turn on the dynamic depends for ninja
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP ON)
project(RaceGame)
include_directories(
RaceApp/headers
RaceApp/src
RaceLib/interfaces
RaceLib/includes
)
link_directories(RaceApp/interaces)
file(GLOB Lib_SRCS
"RaceLib/interfaces/*.ixx"
)
file(GLOB App_SRCS
"RaceApp/src/*.cpp"
)
configure_file(RaceApp/resources/botnames.txt botnames.txt COPYONLY)
configure_file(RaceApp/resources/botcallsigns.txt botcallsigns.txt COPYONLY)
add_library(RaceLib SHARED)
target_sources(
RaceLib
PRIVATE
FILE_SET module_files
TYPE CXX_MODULES
BASE_DIRS "${PROJECT_SOURCE_DIR}"
FILES
${PROJECT_SOURCE_DIR}/RaceLib/interfaces/RaceLib.ixx
)
add_executable(RaceGame ${App_SRCS})
target_link_libraries(RaceGame RaceLib)
cmake command output
-- Building for: Visual Studio 17 2022
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19045.
-- The C compiler identification is MSVC 19.35.32215.0
-- The CXX compiler identification is MSVC 19.35.32215.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: D:/Development/MS VS 2022 Community/VC/Tools/MSVC/14.35.32215/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/Development/MS VS 2022 Community/VC/Tools/MSVC/14.35.32215/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) at CMakeLists.txt:43 (target_sources):
CMake's C++ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring done (7.6s)
CMake Warning (dev):
C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Generating done (0.1s)
-- Build files have been written to: D:/Development/SOLUTIONS/RaceGame/build
cmake –build output:
MSBuild version 17.5.0+6f08c67f3 for .NET Framework
Checking Build System
Building Custom Rule D:/Development/SOLUTIONS/RaceGame/CMakeLists.txt
Scanning sources for module dependencies...
RaceLib.ixx
Compiling...
RaceLib.ixx
... some my code warnings
Auto build dll exports
Couldn't open file 'D:/Development/SOLUTIONS/RaceGame/build/RaceLib.dir/Debug/RaceLib.obj' with Crea
teFile()
... errors
2
Answers
In the end I just switched the library to compile as STATIC library instead of SHARED. It works, tho. That's not what I wanted, but that's what I've got working.
As far as I know, to use the
module
, CMake version requirements are relatively high.What you may need is target_sources
You can use: