skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.


  2. 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:

    cmake_minimum_required(VERSION 3.25)
    
    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)
    
    add_library(my_module_library)
    
    # MODULE SOURCE
    target_sources(
            my_module_library
            PRIVATE
            FILE_SET module_files
            TYPE CXX_MODULES
            BASE_DIRS "${PROJECT_SOURCE_DIR}"
            FILES
    
            ${PROJECT_SOURCE_DIR}/src/my_module.ixx
    )
    
    # HEADER FILES
    target_sources(
            my_module_library
            PUBLIC
            FILE_SET header_files
            TYPE HEADERS
            BASE_DIRS "${PROJECT_SOURCE_DIR}/src"
            FILES
    
            ${PROJECT_SOURCE_DIR}/src/my_header.hpp
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search