Browse Source

Emscripten: Add tests for the Emscripten toolchain

Quinn Powell 7 months ago
parent
commit
c6da668b13

+ 4 - 0
Tests/RunCMake/CMakeLists.txt

@@ -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()

+ 3 - 0
Tests/RunCMake/Emscripten/CMakeLists.txt

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

+ 66 - 0
Tests/RunCMake/Emscripten/RunCMakeTest.cmake

@@ -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()

+ 9 - 0
Tests/RunCMake/Emscripten/base.c

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

+ 6 - 0
Tests/RunCMake/Emscripten/circular1.c

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

+ 7 - 0
Tests/RunCMake/Emscripten/circular2.c

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

+ 20 - 0
Tests/RunCMake/Emscripten/emscripten-WHOLE_ARCHIVE.cmake

@@ -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>)

+ 2 - 0
Tests/RunCMake/Emscripten/emscripten-c.cmake

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

+ 2 - 0
Tests/RunCMake/Emscripten/emscripten-cxx.cmake

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

+ 6 - 0
Tests/RunCMake/Emscripten/emscripten-lib.cmake

@@ -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)

+ 15 - 0
Tests/RunCMake/Emscripten/lib.c

@@ -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();
+}

+ 4 - 0
Tests/RunCMake/Emscripten/libmod.c

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

+ 18 - 0
Tests/RunCMake/Emscripten/main.c

@@ -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;
+}

+ 9 - 0
Tests/RunCMake/Emscripten/main_circular.c

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

+ 15 - 0
Tests/RunCMake/Emscripten/module.c

@@ -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;
+}

+ 7 - 0
Tests/RunCMake/Emscripten/module.cxx

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

+ 12 - 0
Tests/RunCMake/Emscripten/module.h

@@ -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__ */

+ 8 - 0
Tests/RunCMake/Emscripten/unref.c

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