Emscripten: Add tests for the Emscripten toolchain

This commit is contained in:
Quinn Powell
2025-06-02 13:33:55 -04:00
parent 96d9b94a98
commit c6da668b13
18 changed files with 213 additions and 0 deletions

View File

@@ -1402,3 +1402,7 @@ if (CMake_TEST_Renesas_TOOLCHAINS)
add_RunCMake_test(Renesas -DCMake_TEST_Renesas_TOOLCHAINS=${CMake_TEST_Renesas_TOOLCHAINS})
set_property(TEST RunCMake.Renesas APPEND PROPERTY LABELS "Renesas")
endif()
if(CMake_TEST_Emscripten_TOOLCHAINS)
add_RunCMake_test(Emscripten -DCMake_TEST_Emscripten_TOOLCHAINS=${CMake_TEST_Emscripten_TOOLCHAINS})
set_property(TEST RunCMake.Emscripten APPEND PROPERTY LABELS "Emscripten")
endif()

View File

@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 4.0)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@@ -0,0 +1,66 @@
include(RunCMake)
# Locate Emscripten toolchain
if(RunCMake_GENERATOR MATCHES "Makefile|Ninja")
file(GLOB _emscripten_toolchains
"${CMake_TEST_Emscripten_TOOLCHAINS}/emcc" )
if(_emscripten_toolchains STREQUAL "")
message(FATAL_ERROR "Could not find any Emscripten toolchains at: ${CMake_TEST_Emscripten_TOOLCHAINS}.")
endif()
endif()
function(run_toolchain case)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
run_cmake_with_options(${case} ${ARGN})
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
endfunction()
macro(run_cmake_target test subtest target)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(${test}-${subtest}-build ${CMAKE_COMMAND} --build . --target ${target} --config Release --verbose ${ARGN})
unset(RunCMake_TEST_BINARY_DIR)
unset(RunCMake_TEST_NO_CLEAN)
endmacro()
foreach(_emscripten_toolchain IN LISTS _emscripten_toolchains)
message(STATUS "Found Emscripten toolchain: ${_emscripten_toolchain}")
cmake_path(GET _emscripten_toolchain PARENT_PATH BIN_DIR)
if (WIN32)
set(EMCC_SUFFIX ".bat")
else()
set(EMCC_SUFFIX "")
endif()
set(c_comp ${BIN_DIR}/emcc${EMCC_SUFFIX})
set(cxx_comp ${BIN_DIR}/em++${EMCC_SUFFIX})
set(comp_ar ${BIN_DIR}/emar${EMCC_SUFFIX})
# Create an executable from .c sources only.
run_toolchain(emscripten-c
-DCMAKE_SYSTEM_NAME=Emscripten
-DCMAKE_C_COMPILER=${c_comp}
)
# Create an executable from .c and .cxx sources.
run_toolchain(emscripten-cxx
-DCMAKE_SYSTEM_NAME=Emscripten
-DCMAKE_C_COMPILER=${c_comp}
-DCMAKE_CXX_COMPILER=${cxx_comp}
)
# Create a library and executable from .c sources.
run_toolchain(emscripten-lib
-DCMAKE_SYSTEM_NAME=Emscripten
-DCMAKE_C_COMPILER=${c_comp}
)
run_cmake_with_options(emscripten-WHOLE_ARCHIVE
-DCMAKE_SYSTEM_NAME=Emscripten
-DCMAKE_C_COMPILER=${c_comp}
)
run_cmake_target(emscripten-WHOLE_ARCHIVE link-exe main)
run_cmake_target(emscripten-WHOLE_ARCHIVE circular-exe main_circular)
endforeach()

View File

@@ -0,0 +1,9 @@
#if !defined(STATIC_BASE)
# if defined(_WIN32)
__declspec(dllexport)
# endif
#endif
void base(void)
{
}

View File

@@ -0,0 +1,6 @@
void circular2(void);
void circular1(void)
{
circular2();
}

View File

@@ -0,0 +1,7 @@
void circular1(void);
void circular2(void)
{
circular1();
}

View File

@@ -0,0 +1,20 @@
enable_language(C)
add_library(base STATIC base.c unref.c)
target_compile_definitions(base PUBLIC STATIC_BASE)
add_library(lib SHARED lib.c)
target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,base>")
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)
add_library(circular1 STATIC circular1.c)
add_library(circular2 STATIC circular2.c)
target_link_libraries(circular1 PRIVATE circular2)
target_link_libraries(circular2 PRIVATE circular1)
add_executable(main_circular main_circular.c)
target_link_libraries(main_circular PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,circular1>)

View File

@@ -0,0 +1,2 @@
enable_language(C)
add_executable(exec-c module.c)

View File

@@ -0,0 +1,2 @@
enable_language(CXX)
add_executable(exec-cxx module.cxx)

View File

@@ -0,0 +1,6 @@
enable_language(C)
add_library(emscripten-test-lib libmod.c)
add_executable(exec-lib-c module.c)
target_compile_definitions(exec-lib-c PRIVATE __USE_LIBFUN)
target_link_libraries(exec-lib-c PRIVATE emscripten-test-lib)

View File

@@ -0,0 +1,15 @@
#if !defined(STATIC_BASE)
# if defined(_WIN32)
__declspec(dllimport)
# endif
#endif
void base(void);
#if defined(_WIN32)
__declspec(dllexport)
#endif
void lib(void)
{
base();
}

View File

@@ -0,0 +1,4 @@
int emscripten_libfun()
{
return 42;
}

View File

@@ -0,0 +1,18 @@
#if defined(_WIN32)
__declspec(dllimport)
#endif
void lib(void);
#if defined(_WIN32)
__declspec(dllimport)
#endif
void unref(void);
int main(void)
{
lib();
unref();
return 0;
}

View File

@@ -0,0 +1,9 @@
void circular1(void);
int main(void)
{
circular1();
return 0;
}

View File

@@ -0,0 +1,15 @@
#include "module.h"
#if defined(__USE_LIBFUN)
extern int emscripten_libfun();
#endif
int i;
int main()
{
#if defined(__USE_LIBFUN)
i = emscripten_libfun();
#else
i = INTERNAL;
#endif
return i;
}

View File

@@ -0,0 +1,7 @@
#include "module.h"
int i;
int main()
{
i = INTERNAL;
return i;
}

View File

@@ -0,0 +1,12 @@
#ifndef __MODULE_H__
#define __MODULE_H__
#if defined(__cplusplus)
# define INTERNAL 64
#elif !defined(__cplusplus)
# define INTERNAL 32
#else
# error "Unable to determine INTERNAL symbol."
#endif
#endif /* __MODULE_H__ */

View File

@@ -0,0 +1,8 @@
#if defined(_WIN32)
__declspec(dllexport)
#endif
void unref(void)
{
}