Featured image of post useCmakeBuildRaylib

useCmakeBuildRaylib

Building raylib and Its Related Components with CMake

# raylib overview

raylib is a simple and easy-to-use library that allows us to enjoy game programming with ease. In addition to raylib itself, the author also provides other extension components. The official website of raylib is https://www.raylib.com/, where you can find more detailed information.

# Purpose of This Blog

The author came across this lib by chance. After some hands-on experience, an idea emerged: could the modules provided by the raylib author be integrated with raylib using CMake? After a period of research, a basic integration was successfully achieved. This blog will document the integration process and the issues encountered along the way.

# begin

# environment variables

1.cmake https://cmake.org/ Just download the latest version

2.mingw https://github.com/niXman/mingw-builds-binaries/releases
Choose the appropriate version based on your operating system. Of course, you can also opt for other build tools.For Windows users, it is recommended to select the posix-seh-ucrt-rt version. Please research the differences between other versions as needed.If you download the build tools from other sources, make sure to check whether the GCC version is outdated. The author previously encountered errors caused by an outdated GCC version, which took quite some time to troubleshoot. The command to check the GCC version on Windows is: gcc -v

3.Configure environment variables
Add the bin paths of CMake and MinGW to your system’s environment variables. Please refer to online guides for instructions on how to configure environment variables.

4.Additional Operations
It is recommended for Windows users to copy mingw32-make.exe and rename it to make.exe. If Visual Studio is not installed on your computer, you may encounter errors due to the absence of compilers like MSVC.

# File structure

Create a project folder, and it is recommended to organize it with the following structure:

  • assets // Resource files
  • build // Build directory
  • include // Header files
  • lib // Third-party libraries
  • src // Source files
  • CMakeLists.txt // CMake configuration file

# Writing the CMakeLists.txt File

# Top-Level CMakeLists.txt

This is the main CMakeLists.txt file located in the root directory of your project:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Specify the minimum required version of CMake
cmake_minimum_required(VERSION 3.20)

# Set the project name
project(sol)
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 20)

# Generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Add the src directory as a subdirectory
add_subdirectory("src")

The CMake version specified here should not be higher than the version installed on your system.

# CMakeLists.txt Inside the src Directory

First, create a test .cpp file inside the src folder. Then, add the following configuration to src/CMakeLists.txt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Include all source files in the src directory
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)

# Set the output path for the executable
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# Specify the path to header files
include_directories(${PROJECT_SOURCE_DIR}/include)


# Specify the path to third-party libraries
link_directories(${PROJECT_SOURCE_DIR}/lib)

${PROJECT_SOURCE_DIR} It refers to the root directory of the project. The above configuration defines the set of files to be compiled, the paths to header files and libraries, and sets the output directory for the executable to the bin folder in the project’s root directory (this folder will be automatically created if it doesn’t exist during the build process).

Based on the example provided in the official project’s CMakeLists.txt, I have made the following integrations and modifications.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
set(RAYLIB_VERSION 5.5)
find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED
if (NOT raylib_FOUND) # If there's none, fetch and build raylib
  include(FetchContent)
  FetchContent_Declare(
    raylib
    DOWNLOAD_EXTRACT_TIMESTAMP OFF
    URL https://github.com/raysan5/raylib/archive/refs/tags/${RAYLIB_VERSION}.tar.gz
  )
  FetchContent_GetProperties(raylib)
  if (NOT raylib_POPULATED) # Have we downloaded raylib yet?
    set(FETCHCONTENT_QUIET NO)
    FetchContent_MakeAvailable(raylib)
    set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
  endif()
endif()

set(RAYGUI_VERSION 4.0)
find_package(raygui ${RAYGUI_VERSION} QUIET) # QUIET or REQUIRED
if (NOT raygui_FOUND) # If there's none, fetch and build raylib
  include(FetchContent)
  FetchContent_Declare(
    raygui
    DOWNLOAD_EXTRACT_TIMESTAMP OFF
    URL https://github.com/raysan5/raygui/archive/refs/heads/master.zip
  )
  FetchContent_GetProperties(raygui)
  if (NOT raygui_POPULATED) # Have we downloaded raylib yet?
    set(FETCHCONTENT_QUIET NO)
    FetchContent_MakeAvailable(raygui)
    set(BUILD_RAYGUI_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
    add_subdirectory(${raygui_SOURCE_DIR}/projects/CMake ${raygui_BINARY_DIR})
  endif()
endif()

set(RRES_VERSION 1.2.0)
find_package(rres ${RRES_VERSION} QUIET) # QUIET or REQUIRED
if (NOT rres_FOUND) # If there's none, fetch and build raylib
  include(FetchContent)
  FetchContent_Declare(
    rres
    DOWNLOAD_EXTRACT_TIMESTAMP OFF
    URL https://github.com/raysan5/rres/archive/refs/heads/master.zip
  )
  FetchContent_GetProperties(rres)
  if (NOT rres_POPULATED) # Have we downloaded raylib yet?
    set(FETCHCONTENT_QUIET NO)
    FetchContent_MakeAvailable(rres)
    set(BUILD_RRES_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
    add_subdirectory(${rres_SOURCE_DIR}/projects/CMake ${rres_BINARY_DIR})
  endif()
endif()

option(SUPPORT_FILEFORMAT_WAV "WAV Support" TRUE)
option(SUPPORT_FILEFORMAT_OGG "OGG Support" TRUE)
option(SUPPORT_FILEFORMAT_MP3 "MP3 Support" TRUE)
option(SUPPORT_FILEFORMAT_QOA "QOA Support" TRUE)
option(SUPPORT_FILEFORMAT_FLAC "FLAC Support" TRUE)
option(SUPPORT_FILEFORMAT_XM "XM Support" TRUE)
option(SUPPORT_FILEFORMAT_MOD "MOD Support" TRUE)

file(COPY ${PROJECT_SOURCE_DIR}/include/rres/rres-raylib.h DESTINATION ${rres_SOURCE_DIR}/src)

# Our Project
add_executable(${PROJECT_NAME} ${SRC})
#set(raylib_VERBOSE 1)
target_link_libraries(${PROJECT_NAME} raylib raygui rres)

# Web Configurations
if (${PLATFORM} STREQUAL "Web")
    set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") # Tell Emscripten to build an example.html file.
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s GL_ENABLE_GET_PROC_ADDRESS=1")
endif()

# Checks if OSX and links appropriate frameworks (Only required on MacOS)
if (APPLE)
    target_link_libraries(${PROJECT_NAME} "-framework IOKit")
    target_link_libraries(${PROJECT_NAME} "-framework Cocoa")
    target_link_libraries(${PROJECT_NAME} "-framework OpenGL")
endif()

The key part lies in the use of find_package. If the corresponding package is not found, CMake will automatically use the package configured in the code.Since raudio has already been integrated into raylib by the author, you only need to download raylib, raygui, and rres.

# Write test code

If you are using C++ code, you will need to make certain modifications to the rres-raylib.h header file; otherwise, compilation errors may occur. The changes are as follows

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//line 567
crypto_argon2_inputs inputs = {
.pass = (const uint8_t *)rresGetCipherPassword(), // User password
.salt = salt, // Salt for the password
.pass_size = (uint32_t)strlen(rresGetCipherPassword()), // Password length
.salt_size = 16|
};

//line 641
crypto_argon2_inputs inputs = {
.pass = (const uint8_t *)rresGetCipherPassword(), // User password
.salt = salt, // Salt for the password
.pass_size = (uint32_t)strlen(rresGetCipherPassword()), // Password length
.salt_size = 16|
};

//line 669
int decryptResult = crypto_aead_unlock(decryptedData, mac, key, nonce, NULL, 0, (const u8 *)chunk->data.raw, (chunk->info.packedSize - 16 - 24 - 16));

It could be that the source code is written in c by the author, I’ve submitted a pull request in githut. the author has agreed to merge it, and the new version of rres won’t have this problem anymore!

# build

Finally, create a build folder in the project’s root directory. Open the command line in the build folder and enter the following commands in sequence:(. / depending on the actual path of your project)

1
2
cmake ./ 
cmake --build ./

-G “Unix Makefiles” If you are using Windows and need to makefiles, you need to add this statement. The download may fail during runtime due to network effects, just try a few more times. If everything is fine, you should see a bin folder in the root directory with an executable file in it, and if the executable file runs normally, you are done.

# End

If you don’t want to go through the trouble, you can download my project directly from github. https://github.com/IyuMashiro/raylib_raygui_rres_template

Built with Hugo
Theme Stack designed by Jimmy