I want to write a CMake script for building a web application.

Description

I’m trying to build a C++ project using raylib and glm for a web application, but I don’t know how to resolve the error shown in the terminal log below.

What I’ve Tried

I searched through the raylib samples, copied and pasted the code, and ran it → Same error
URL: loading...

Implemented using Gemini → Encountered the error shown in the log

With the provided CMake file, I was able to build and run the project before adding the lines for the web version, so
the error is caused by those additions.

The libraries I’m using are raylib and glm. I downloaded them from GitHub, built them, and installed them.

The directory is /home/amagi/clones/raylib/src/raylib, but I navigated to my home directory
by typing cd home/amagi/clones/raylib/src/ and used ls to confirm the presence of raylib.a. However, for some reason,
I’m still getting the same error.

I also added #include at the top of the source file, but I’m still getting the same error.

What I Want to Know

I want to know how to resolve the issue shown in the console log and how to write the CMake file correctly.

Terminal log

 ~/dev/top-down/build ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 2m 58s ─╮
╰─❯ emcmake cmake ..                                                                                                                                                                                      ─╯
    cmake --build .
configure: cmake .. -DCMAKE_TOOLCHAIN_FILE=/usr/share/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/node
-- Configuring done (0.5s)
-- Generating done (0.0s)
-- Build files have been written to: /home/amagi/dev/top-down/build
gmake[2]: *** 'app.html' に必要なターゲット '/home/amagi/clones/raylib/src/raylib' を make するルールがありません.  中止.
gmake[1]: *** [CMakeFiles/Makefile2:87: CMakeFiles/app.dir/all] エラー 2
gmake: *** [Makefile:91: all] エラー 2

translate to english from japanese

gmake[2]: *** There is no rule to build the target ‘/home/amagi/clones/raylib/src/raylib’ required by ‘app.html’.  Aborting.
gmake[1]: *** [CMakeFiles/Makefile2:87: CMakeFiles/app.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

# compiler
set(CMAKE_CXX_COMPILER "clang++")
set(CMAKE_C_COMPILER "clang")

# project
set(PROJECT_NAME "app")


set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(PROJECT_VERSION "1.0.0")
project(${PROJECT_NAME} VERSION ${PROJECT_VERSION})

#####################################################################
# Project
#####################################################################

set(EXE_NAME ${PROJECT_NAME})
set(EXE_SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(EXE_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include")


#file(GLOB_RECURSE EXE_SOURCE_LIST CONFIGURE_DEPENDS "${EXE_SOURCE_PATH}/*.cpp" "${EXE_SOURCE_PATH}/*.c")

set(EXE_SOURCE_LIST
    "${EXE_SOURCE_PATH}/Main.cpp"
)

add_executable(${EXE_NAME} ${EXE_SOURCE_LIST})

target_precompile_headers(${PROJECT_NAME} PRIVATE
    # <glm/glm.hpp>
    # <box2d/box2d.h>
    # <entt/entt.hpp>
    <vector>
    <variant>
    <iostream>
    <memory>
)


# ==========================================
# Emscripten
# ==========================================
if(EMSCRIPTEN)
    # 1. 出力ファイルの拡張子を .html にする
    set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")

    target_link_libraries(${EXE_NAME} PRIVATE "$ENV{HOME}/clones/raylib/src/raylib")
    target_link_libraries(${EXE_NAME} PRIVATE "$ENV{HOME}/clones/glm/build/glm/glm")

target_include_directories(${EXE_NAME} PRIVATE "${EXE_INCLUDE_PATH}" "$ENV{HOME}/clones/glm" "$ENV{HOME}/clones/raylib/src/")

    # 2. 必要なリンクオプション(ご提示のコマンドに対応)
    target_link_options(${PROJECT_NAME} PRIVATE
        -sUSE_GLFW=3
        -sASYNCIFY
        -sINITIAL_MEMORY=67108864  # ※近代的なEmscriptenでは TOTAL_MEMORY より INITIAL_MEMORY が推奨されます
        -O2
        # シェルファイルを指定する場合
        # "--shell-file" "${CMAKE_CURRENT_SOURCE_DIR}/shell.html"

        # アセット(resourcesフォルダなど)を同梱する場合
        # "--preload-file" "${CMAKE_CURRENT_SOURCE_DIR}/resources@resources"
    )
endif()



target_link_libraries(${EXE_NAME} PRIVATE "$ENV{HOME}/clones/raylib/src/raylib")
target_link_libraries(${EXE_NAME} PRIVATE "$ENV{HOME}/clones/glm/build/glm/glm")
# target_link_libraries(${EXE_NAME} PRIVATE "glm")
# target_link_libraries(${EXE_NAME} PRIVATE "box2d")

target_link_libraries(${EXE_NAME} PRIVATE "GL")
target_link_libraries(${EXE_NAME} PRIVATE "m")
target_link_libraries(${EXE_NAME} PRIVATE "pthread")
target_link_libraries(${EXE_NAME} PRIVATE "dl")
target_link_libraries(${EXE_NAME} PRIVATE "rt")
target_link_libraries(${EXE_NAME} PRIVATE "X11")

Main.cpp




#include "raylib.h"
#include "glm/glm.hpp"

#if defined(PLATFORM_WEB)
    #include <emscripten/emscripten.h>
#endif

//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;

//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
void UpdateDrawFrame(void);     // Update and Draw one frame

//----------------------------------------------------------------------------------
// Program main entry point
//----------------------------------------------------------------------------------
int main(void)
{
    // Initialization
    //--------------------------------------------------------------------------------------
    InitWindow(screenWidth, screenHeight, "raylib [core] example - window web");

#if defined(PLATFORM_WEB)
    emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
    SetTargetFPS(60);   // Set our game to run at 60 frames-per-second
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        UpdateDrawFrame();
    }
#endif

    // De-Initialization
    //--------------------------------------------------------------------------------------
    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}

//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
void UpdateDrawFrame(void)
{
    // Update
    //----------------------------------------------------------------------------------
    // TODO: Update your variables here
    //----------------------------------------------------------------------------------

    // Draw
    //----------------------------------------------------------------------------------
    BeginDrawing();

        ClearBackground(RAYWHITE);

        DrawText("Welcome to raylib web structure!", 220, 200, 20, SKYBLUE);

    EndDrawing();
    //----------------------------------------------------------------------------------
}


The target_link_libraries() should (ideally) operate with targets, but instead you are providing a path (to a folder?). And even before that the target should be discovered first with something like find_package(raylib CONFIG REQUIRED) (perhaps without CONFIG), depending on how this dependency is resolved in your system.

But you claim that it works with “non-web” version, and I can’t say why it is so.

Thank you.
Based on what I’ve looked into, it seems I need a .a file built for the web, so I ran the following commands to create it. Since the system installation is for the desktop,
I deliberately left it in the clones/ directory and did not install it.
I adjusted the path, deleted the build directory, and ran the same commands, but I still got the same error.

cd raylib
emcmake cmake . -DPLATFORM=Web
emmake make