Skip to content

Commit d502e0d

Browse files
authored
Fix C++ module usage (#421)
* Fix and test C++ module usage * Fix stale GetRay module export * Enable module scanning on example target * Match module extension flags in example * Apply suggestion from @RobLoach * Apply suggestion from @RobLoach * Apply suggestion from @RobLoach * Apply suggestion from @RobLoach
1 parent 79826ec commit d502e0d

6 files changed

Lines changed: 114 additions & 15 deletions

File tree

‎.github/workflows/Tests.yml‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,29 @@ jobs:
5757
- name: Test
5858
if: runner.os == 'Linux'
5959
run: ctest --verbose --test-dir build
60+
61+
# Verify the C++20 module target (`import raylib;`) builds. Module
62+
# dependency scanning requires the Ninja generator and a scan-capable
63+
# compiler (LLVM Clang here), so this uses its own job.
64+
modules:
65+
name: C++20 Modules (Ninja Clang)
66+
runs-on: ubuntu-24.04
67+
steps:
68+
- uses: actions/checkout@v4
69+
with:
70+
submodules: recursive
71+
- name: Install Dependencies
72+
run: sudo apt-get update && sudo apt-get install -y ninja-build clang-18 clang-tools-18 libasound2-dev libx11-dev libxrandr-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev libxcursor-dev libxinerama-dev
73+
74+
- name: Configure
75+
run: >
76+
cmake -B build -S . -G Ninja
77+
-DCMAKE_C_COMPILER=clang-18
78+
-DCMAKE_CXX_COMPILER=clang++-18
79+
-DBUILD_RAYLIB_CPP_MODULES=ON
80+
-DCMAKE_CXX_STANDARD=20
81+
-DGLFW_BUILD_WAYLAND=OFF
82+
-DCMAKE_BUILD_TYPE=Release
83+
84+
- name: Build modules
85+
run: cmake --build build --target raylib_cpp_modules module

‎README.md‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,22 +255,28 @@ raylib::Vector2 newDirection = direction.Rotate(30);
255255
256256
### Modules
257257
258-
If using C++20 or later, by passing `BUILD_RAYLIB_CPP_MODULES` to the build system the library may be imported as a module by using `import raylib;`.
258+
If using C++20 or later, enabling `BUILD_RAYLIB_CPP_MODULES` lets the library be imported as a C++ module with `import raylib;`. Link against the `raylib_cpp_modules` target instead of `raylib_cpp`.
259259
260260
```cpp
261261
import raylib;
262262
263-
using raylib::Texture;
263+
using raylib::Color;
264264
using raylib::Window;
265265
266266
int main() {
267267
int screenWidth = 800;
268268
int screenHeight = 450;
269269
270270
Window window(screenWidth, screenHeight, "raylib-cpp - basic window");
271-
Texture logo("raylib_logo.png");
272271
273-
// ...
272+
while (!window.ShouldClose()) {
273+
window.BeginDrawing();
274+
window.ClearBackground(raylib::Colors::RAYWHITE);
275+
raylib::DrawText("Imported raylib as a module!", 120, 200, 20, Color::LightGray());
276+
window.EndDrawing();
277+
}
278+
279+
return 0;
274280
}
275281
```
276282

‎examples/CMakeLists.txt‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,23 @@ endforeach()
5858
add_executable("multiple" multiple/main.cpp multiple/Player.cpp)
5959
target_link_libraries("multiple" PUBLIC raylib_cpp raylib)
6060

61+
# C++20 modules example: only built when modules are enabled and the
62+
# raylib_cpp_modules target was created (CMake 3.28+).
63+
if(BUILD_RAYLIB_CPP_MODULES AND TARGET raylib_cpp_modules)
64+
add_executable("module" module/main.cpp)
65+
target_link_libraries("module" PRIVATE raylib_cpp_modules)
66+
set_target_properties("module" PROPERTIES
67+
CXX_STANDARD 20
68+
CXX_STANDARD_REQUIRED ON
69+
# Match raylib_cpp_modules' language flags: the compiled module (BMI)
70+
# can only be imported by a consumer built with the same C++ standard
71+
# and extension settings, so keep the default extensions here.
72+
CXX_EXTENSIONS ON
73+
# The examples directory defaults to C++11, so module scanning is not
74+
# enabled for this target automatically; turn it on explicitly.
75+
CXX_SCAN_FOR_MODULES ON
76+
)
77+
endif()
78+
6179
# Copy all the resources
6280
file(COPY ${example_resources} DESTINATION "resources/")

‎examples/module/main.cpp‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* raylib-cpp example using C++20 modules.
3+
*
4+
* Build with modules enabled (requires the Ninja or Visual Studio generator
5+
* and a compiler that can scan for module dependencies):
6+
*
7+
* cmake -B build -G Ninja -DBUILD_RAYLIB_CPP_MODULES=ON -DCMAKE_CXX_STANDARD=20
8+
* cmake --build build --target module
9+
*/
10+
import raylib;
11+
12+
using raylib::Color;
13+
using raylib::Window;
14+
15+
int main() {
16+
int screenWidth = 800;
17+
int screenHeight = 450;
18+
19+
Window window(screenWidth, screenHeight, "raylib-cpp - modules example");
20+
21+
while (!window.ShouldClose()) {
22+
window.BeginDrawing();
23+
window.ClearBackground(raylib::Colors::RAYWHITE);
24+
raylib::DrawText("Congrats! You imported raylib as a module!", 120, 200, 20, Color::LightGray());
25+
window.EndDrawing();
26+
}
27+
28+
return 0;
29+
}

‎modules/CMakeLists.txt‎

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
1-
file(GLOB_RECURSE RAYLIB_CPP_MODULES raylib.cppm)
1+
# raylib-cpp C++ module target (`import raylib;`).
2+
#
3+
# Requirements
4+
# - CMake 3.28+
5+
# - Module dependency scanning generator, like Ninja, VS17.4+
6+
# - Compiler with scanning support, like CLang (16+, MSVC 19.34+ or GCC 14+
27

3-
add_library(raylib_cpp_modules)
8+
if(CMAKE_VERSION VERSION_LESS 3.28)
9+
message(WARNING
10+
"raylib-cpp: C++ modules require CMake 3.28 or newer (found "
11+
"${CMAKE_VERSION}). Skipping the raylib_cpp_modules target.")
12+
return()
13+
endif()
14+
15+
# Module dependency scanning is only implemented for the Ninja and
16+
# Visual Studio generators.
17+
if(NOT CMAKE_GENERATOR MATCHES "Ninja|Visual Studio")
18+
message(WARNING
19+
"raylib-cpp: building C++ modules requires the Ninja or Visual Studio "
20+
"generator; the '${CMAKE_GENERATOR}' generator cannot discover module "
21+
"import dependencies. Reconfigure with '-G Ninja' to use 'import raylib;'.")
22+
endif()
423

5-
cmake_minimum_required(VERSION 3.28)
24+
add_library(raylib_cpp_modules STATIC)
625

26+
# Allow a parent project to customise how the module sources are attached.
727
if(NOT COMMAND configure_cpp_module_target)
828
function(configure_cpp_module_target target)
9-
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28)
10-
target_sources(${target} PUBLIC FILE_SET CXX_MODULES FILES ${RAYLIB_CPP_MODULES})
11-
else()
12-
message(WARNING "C++ modules require CMake 3.28+. Using standard compilation.")
13-
target_sources(${target} PRIVATE ${RAYLIB_CPP_MODULES})
14-
endif()
29+
target_sources(${target}
30+
PUBLIC
31+
FILE_SET CXX_MODULES FILES ${CMAKE_CURRENT_SOURCE_DIR}/raylib.cppm
32+
)
1533
endfunction()
1634
endif()
1735

@@ -28,4 +46,6 @@ target_include_directories(raylib_cpp_modules
2846
${PROJECT_SOURCE_DIR}/include
2947
)
3048

31-
target_compile_features(raylib_cpp_modules PUBLIC cxx_std_20)
49+
# C++ modules require at least C++20; propagate the requirement to consumers
50+
# so that module scanning is enabled for targets that `import raylib;`.
51+
target_compile_features(raylib_cpp_modules PUBLIC cxx_std_20)

‎modules/raylib.cppm‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export namespace raylib {
229229
using raylib::Mouse::GetTouchX;
230230
using raylib::Mouse::GetTouchY;
231231
using raylib::Mouse::GetTouchPosition;
232-
using raylib::Mouse::GetRay;
232+
using raylib::Mouse::GetScreenToWorldRay;
233233
}
234234

235235
/**

0 commit comments

Comments
 (0)