Skip to content

Commit b602c32

Browse files
authored
Add emscripten automated tests (#483)
1 parent 33bfa39 commit b602c32

20 files changed

+262
-73
lines changed

.github/workflows/deploy-pages.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,11 @@ jobs:
9393
if: ${{ runner.os != 'windows' }}
9494
shell: bash -l {0}
9595
run: |
96+
set -e
9697
./emsdk/emsdk activate ${{matrix.emsdk_ver}}
9798
source ./emsdk/emsdk_env.sh
9899
micromamba create -f environment-wasm.yml --platform=emscripten-wasm32
99-
100+
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
100101
export PREFIX=$MAMBA_ROOT_PREFIX/envs/CppInterOp-wasm
101102
export CMAKE_PREFIX_PATH=$PREFIX
102103
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
@@ -130,6 +131,7 @@ jobs:
130131
-DCODE_COVERAGE=${{ env.CODE_COVERAGE }} \
131132
-DCMAKE_INSTALL_PREFIX=$PREFIX \
132133
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
134+
-DSYSROOT_PATH=$SYSROOT_PATH \
133135
../
134136
else
135137
emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
@@ -141,13 +143,15 @@ jobs:
141143
-DCODE_COVERAGE=${{ env.CODE_COVERAGE }} \
142144
-DCMAKE_INSTALL_PREFIX=$PREFIX \
143145
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
146+
-DSYSROOT_PATH=$SYSROOT_PATH \
144147
../
145148
fi
146-
149+
emmake make -j ${{ env.ncpus }} check-cppinterop
147150
emmake make -j ${{ env.ncpus }} install
148151
149152
cd ..
150-
153+
154+
echo "SYSROOT_PATH=$SYSROOT_PATH" >> $GITHUB_ENV
151155
echo "CB_PYTHON_DIR=$CB_PYTHON_DIR" >> $GITHUB_ENV
152156
echo "CPPINTEROP_BUILD_DIR=$CPPINTEROP_BUILD_DIR" >> $GITHUB_ENV
153157
echo "CPPINTEROP_DIR=$CPPINTEROP_DIR" >> $GITHUB_ENV
@@ -160,7 +164,6 @@ jobs:
160164
run: |
161165
./emsdk/emsdk activate ${{matrix.emsdk_ver}}
162166
source ./emsdk/emsdk_env.sh
163-
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
164167
micromamba activate CppInterOp-wasm
165168
git clone --depth=1 https://github.com/compiler-research/xeus-cpp.git
166169
cd ./xeus-cpp
@@ -175,7 +178,7 @@ jobs:
175178
-DXEUS_CPP_EMSCRIPTEN_WASM_BUILD=ON \
176179
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
177180
-DCppInterOp_DIR="${{ env.CPPINTEROP_BUILD_DIR }}/lib/cmake/CppInterOp" \
178-
-DSYSROOT_PATH=$SYSROOT_PATH \
181+
-DSYSROOT_PATH=${{ env.SYSROOT_PATH }} \
179182
..
180183
emmake make -j ${{ env.ncpus }} install
181184

.github/workflows/emscripten.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,11 @@ jobs:
548548
if: ${{ runner.os != 'windows' }}
549549
shell: bash -l {0}
550550
run: |
551+
set -e
551552
./emsdk/emsdk activate ${{matrix.emsdk_ver}}
552553
source ./emsdk/emsdk_env.sh
553554
micromamba create -f environment-wasm.yml --platform=emscripten-wasm32
554-
555+
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
555556
export PREFIX=$MAMBA_ROOT_PREFIX/envs/CppInterOp-wasm
556557
export CMAKE_PREFIX_PATH=$PREFIX
557558
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
@@ -585,6 +586,7 @@ jobs:
585586
-DCMAKE_INSTALL_PREFIX=$PREFIX \
586587
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
587588
-DLLVM_ENABLE_WERROR=On \
589+
-DSYSROOT_PATH=$SYSROOT_PATH \
588590
../
589591
else
590592
emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
@@ -597,13 +599,15 @@ jobs:
597599
-DCMAKE_INSTALL_PREFIX=$PREFIX \
598600
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
599601
-DLLVM_ENABLE_WERROR=On \
602+
-DSYSROOT_PATH=$SYSROOT_PATH \
600603
../
601604
fi
602-
603-
emmake make -j ${{ env.ncpus }} install
604605
606+
emmake make -j ${{ env.ncpus }} check-cppinterop
607+
emmake make -j ${{ env.ncpus }} install
605608
cd ..
606-
609+
610+
echo "SYSROOT_PATH=$SYSROOT_PATH" >> $GITHUB_ENV
607611
echo "CB_PYTHON_DIR=$CB_PYTHON_DIR" >> $GITHUB_ENV
608612
echo "CPPINTEROP_BUILD_DIR=$CPPINTEROP_BUILD_DIR" >> $GITHUB_ENV
609613
echo "CPPINTEROP_DIR=$CPPINTEROP_DIR" >> $GITHUB_ENV
@@ -616,7 +620,6 @@ jobs:
616620
run: |
617621
./emsdk/emsdk activate ${{matrix.emsdk_ver}}
618622
source ./emsdk/emsdk_env.sh
619-
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
620623
micromamba activate CppInterOp-wasm
621624
git clone --depth=1 https://github.com/compiler-research/xeus-cpp.git
622625
cd ./xeus-cpp
@@ -631,6 +634,6 @@ jobs:
631634
-DXEUS_CPP_EMSCRIPTEN_WASM_BUILD=ON \
632635
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
633636
-DCppInterOp_DIR="${{ env.CPPINTEROP_BUILD_DIR }}/lib/cmake/CppInterOp" \
634-
-DSYSROOT_PATH=$SYSROOT_PATH \
637+
-DSYSROOT_PATH=${{ env.SYSROOT_PATH }} \
635638
..
636639
emmake make -j ${{ env.ncpus }} install

CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ endif()
361361

362362
# Add appropriate flags for GCC
363363
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
364-
if (APPLE)
364+
if (APPLE OR EMSCRIPTEN)
365365
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings")
366366
else()
367367
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings")
@@ -451,11 +451,6 @@ option(CPPINTEROP_ENABLE_DOXYGEN "Use doxygen to generate CppInterOp interal API
451451
option(CPPINTEROP_ENABLE_SPHINX "Use sphinx to generage CppInterOp user documentation")
452452

453453

454-
if(EMSCRIPTEN)
455-
message("Build with emscripten")
456-
set(CPPINTEROP_ENABLE_TESTING OFF)
457-
endif()
458-
459454
if(MSVC)
460455

461456
set(MSVC_EXPORTLIST

Emscripten-build-instructions.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ git clone https://github.com/emscripten-core/emsdk.git
2525
./emsdk/emsdk install 3.1.73
2626
```
2727

28-
and activate the emsdk environment
28+
and activate the emsdk environment (we are defining SYSROOT_PATH for use later)
2929

3030
```bash
3131
./emsdk/emsdk activate 3.1.73
3232
source ./emsdk/emsdk_env.sh
33+
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
3334
```
3435

3536
Now clone the 19.x release of the LLVM project repository and CppInterOp (the building of the emscripten version of llvm can be
@@ -97,7 +98,7 @@ export CMAKE_PREFIX_PATH=$PREFIX
9798
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
9899
```
99100

100-
Now to build CppInterOp execute the following
101+
Now to build and test your Emscripten build of CppInterOp by executing the following
101102

102103
```bash
103104
mkdir build
@@ -109,7 +110,14 @@ emcmake cmake -DCMAKE_BUILD_TYPE=Release \
109110
-DBUILD_SHARED_LIBS=ON \
110111
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
111112
-DCMAKE_INSTALL_PREFIX=$PREFIX \
113+
-DSYSROOT_PATH=$SYSROOT_PATH \
112114
../
115+
emmake make -j $(nproc --all) check-cppinterop
116+
```
117+
118+
Assuming it passes all test you can install by executing the following
119+
120+
```bash
113121
emmake make -j $(nproc --all) install
114122
```
115123

@@ -126,7 +134,6 @@ the CppInterOp build folder, you can build the wasm version of xeus-cpp by execu
126134

127135
```bash
128136
cd ../..
129-
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
130137
git clone --depth=1 https://github.com/compiler-research/xeus-cpp.git
131138
cd ./xeus-cpp
132139
mkdir build

cmake/modules/GoogleTest.cmake

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@ if(WIN32)
1313
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL:PATH=${_gtest_byproduct_binary_dir}/lib/
1414
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${_gtest_byproduct_binary_dir}/lib/
1515
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO:PATH=${_gtest_byproduct_binary_dir}/lib/
16-
-Dgtest_force_shared_crt=ON
17-
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>)
16+
-Dgtest_force_shared_crt=ON)
1817
elseif(APPLE)
1918
set(EXTRA_GTEST_OPTS -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT})
2019
endif()
2120

2221
include(ExternalProject)
22+
if (EMSCRIPTEN)
23+
set(config_cmd emcmake cmake)
24+
set(build_cmd emmake make)
25+
else()
26+
set(config_cmd ${CMAKE_COMMAND})
27+
set(build_cmd ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/unittests/googletest-prefix/src/googletest-build/ --config $<CONFIG>)
28+
endif()
29+
2330
ExternalProject_Add(
2431
googletest
2532
GIT_REPOSITORY https://github.com/google/googletest.git
@@ -31,7 +38,9 @@ ExternalProject_Add(
3138
# CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs
3239
# -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs
3340
# -Dgtest_force_shared_crt=ON
34-
CMAKE_ARGS -G ${CMAKE_GENERATOR}
41+
CONFIGURE_COMMAND ${config_cmd} -G ${CMAKE_GENERATOR}
42+
-S ${CMAKE_BINARY_DIR}/unittests/googletest-prefix/src/googletest/
43+
-B ${CMAKE_BINARY_DIR}/unittests/googletest-prefix/src/googletest-build/
3544
-DCMAKE_BUILD_TYPE=$<CONFIG>
3645
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
3746
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
@@ -40,6 +49,7 @@ ExternalProject_Add(
4049
-DCMAKE_AR=${CMAKE_AR}
4150
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
4251
${EXTRA_GTEST_OPTS}
52+
BUILD_COMMAND ${build_cmd}
4353
# Disable install step
4454
INSTALL_COMMAND ""
4555
BUILD_BYPRODUCTS ${_gtest_byproducts}

docs/Emscripten-build-instructions.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ This can be installed by executing (we only currently support version
3535
git clone https://github.com/emscripten-core/emsdk.git
3636
./emsdk/emsdk install 3.1.73
3737
38-
and activate the emsdk environment
38+
and activate the emsdk environment (we are defining SYSROOT_PATH for use later)
3939

4040
.. code:: bash
4141
4242
./emsdk/emsdk activate 3.1.73
4343
source ./emsdk/emsdk_env.sh
44+
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
4445
4546
Now clone the 19.x release of the LLVM project repository and CppInterOp
4647
(the building of the emscripten version of llvm can be avoided by
@@ -115,7 +116,7 @@ You will also want to set a few environment variables
115116
export CMAKE_PREFIX_PATH=$PREFIX
116117
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
117118
118-
Now to build CppInterOp execute the following
119+
Now to build and test your Emscripten build of CppInterOp by executing the following
119120

120121
.. code:: bash
121122
@@ -128,7 +129,14 @@ Now to build CppInterOp execute the following
128129
-DBUILD_SHARED_LIBS=ON \
129130
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
130131
-DCMAKE_INSTALL_PREFIX=$PREFIX \
132+
-DSYSROOT_PATH=$SYSROOT_PATH \
131133
../
134+
emmake make -j $(nproc --all) check-cppinterop
135+
136+
Assuming it passes all test you can install by executing the following.
137+
138+
.. code:: bash
139+
132140
emmake make -j $(nproc --all) install
133141
134142
Once this finishes building we need to take note of where we built
@@ -147,7 +155,6 @@ build folder, you can build the wasm version of xeus-cpp by executing
147155
.. code:: bash
148156
149157
cd ../..
150-
export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot
151158
git clone --depth=1 https://github.com/compiler-research/xeus-cpp.git
152159
cd ./xeus-cpp
153160
mkdir build

include/clang/Interpreter/CppInterOp.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -563,12 +563,12 @@ namespace Cpp {
563563
TCppIndex_t param_index);
564564

565565
///\returns arity of the operator or kNone
566-
OperatorArity GetOperatorArity(TCppFunction_t op);
566+
CPPINTEROP_API OperatorArity GetOperatorArity(TCppFunction_t op);
567567

568568
///\returns list of operator overloads
569-
void GetOperator(TCppScope_t scope, Operator op,
570-
std::vector<TCppFunction_t>& operators,
571-
OperatorArity kind = kBoth);
569+
CPPINTEROP_API void GetOperator(TCppScope_t scope, Operator op,
570+
std::vector<TCppFunction_t>& operators,
571+
OperatorArity kind = kBoth);
572572

573573
/// Creates an instance of the interpreter we need for the various interop
574574
/// services.

lib/Interpreter/CMakeLists.txt

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,7 @@
11
if(EMSCRIPTEN)
22
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
3-
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-s SIDE_MODULE=1")
4-
set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-s SIDE_MODULE=1")
53
set(CMAKE_STRIP FALSE)
6-
7-
add_llvm_library(clangCppInterOp
8-
SHARED
9-
10-
CppInterOp.cpp
11-
CXCppInterOp.cpp
12-
DynamicLibraryManager.cpp
13-
DynamicLibraryManagerSymbol.cpp
14-
Paths.cpp
15-
16-
# Additional libraries from Clang and LLD
17-
LINK_LIBS
18-
clangInterpreter
19-
)
20-
#FIXME: Setting no_soname=1 is needed until https://github.com/emscripten-core/emscripten/blob/ac676d5e437525d15df5fd46bc2c208ec6d376a3/cmake/Modules/Platform/Emscripten.cmake#L36
21-
# is patched out of emsdk, as --soname is not recognised by emscripten. A PR to do this has been done here https://github.com/emscripten-core/emscripten/pull/23453
22-
#FIXME: A patch is needed to llvm to remove -Wl,-z,defs since it is now recognised on emscripten. What needs to be removed is here
23-
# https://github.com/llvm/llvm-project/blob/128e2e446e90c3b1827cfc7d4d19e3c0976beff3/llvm/cmake/modules/HandleLLVMOptions.cmake#L318 . The PR to do try to do this is here
24-
# https://github.com/llvm/llvm-project/pull/123396
25-
set_target_properties(clangCppInterOp
26-
PROPERTIES NO_SONAME 1
27-
)
28-
target_link_options(clangCppInterOp PRIVATE
29-
PUBLIC "SHELL: -s WASM_BIGINT"
30-
)
4+
set(LLVM_LINK_COMPONENTS "")
315
else()
326
set(LLVM_LINK_COMPONENTS
337
${LLVM_TARGETS_TO_BUILD}
@@ -44,7 +18,7 @@ else()
4418
if ("LLVMOrcDebugging" IN_LIST LLVM_AVAILABLE_LIBS)
4519
list(APPEND LLVM_LINK_COMPONENTS OrcDebugging)
4620
endif()
47-
21+
endif()
4822
set(DLM
4923
DynamicLibraryManager.cpp
5024
DynamicLibraryManagerSymbol.cpp
@@ -65,6 +39,11 @@ else()
6539
set(cling_clang_interp clangInterpreter)
6640
endif()
6741

42+
if(EMSCRIPTEN)
43+
set(link_libs
44+
${cling_clang_interp}
45+
)
46+
else()
6847
set(link_libs
6948
${cling_clang_interp}
7049
clangAST
@@ -73,8 +52,9 @@ else()
7352
clangLex
7453
clangSema
7554
)
55+
endif()
7656

77-
if(NOT WIN32)
57+
if(NOT WIN32 AND NOT EMSCRIPTEN)
7858
list(APPEND link_libs dl)
7959
endif()
8060

@@ -124,7 +104,6 @@ else()
124104
clangStaticAnalyzerCore
125105
)
126106
endif(LLVM_LINK_LLVM_DYLIB)
127-
128107
add_llvm_library(clangCppInterOp
129108
DISABLE_LLVM_LINK_LLVM_DYLIB
130109
CppInterOp.cpp
@@ -134,9 +113,37 @@ else()
134113
${link_libs}
135114
)
136115

137-
target_compile_definitions(clangCppInterOp PUBLIC "_CINDEX_LIB_") # workaround for the use of `CINDEX_LINKAGE`
116+
117+
if(EMSCRIPTEN)
118+
# FIXME: When dynamically linking the Emscripten shared library to the
119+
# unit tests main_module you get errors due to undefined symbols. The reading of the file
120+
# below into a SYMBOLS_LIST variable is a temporary workaround that exports the undefined
121+
# symbols from the shared library, until it can be determined why they are not being exported already.
122+
file(READ "${CMAKE_SOURCE_DIR}/lib/Interpreter/exports.ld" SYMBOLS_LIST)
123+
124+
# Replace newlines with spaces
125+
string(REPLACE "\n" " " SYMBOLS_LIST "${SYMBOLS_LIST}")
126+
127+
#FIXME: Setting no_soname=1 is needed until https://github.com/emscripten-core/emscripten/blob/ac676d5e437525d15df5fd46bc2c208ec6d376a3/cmake/Modules/Platform/Emscripten.cmake#L36
128+
# is patched out of emsdk, as --soname is not recognised by emscripten. A PR to do this has been done here https://github.com/emscripten-core/emscripten/pull/23453
129+
#FIXME: A patch is needed to llvm to remove -Wl,-z,defs since it is now recognised on emscripten. What needs to be removed is here
130+
# https://github.com/llvm/llvm-project/blob/128e2e446e90c3b1827cfc7d4d19e3c0976beff3/llvm/cmake/modules/HandleLLVMOptions.cmake#L318 . The PR to do try to do this is here
131+
# https://github.com/llvm/llvm-project/pull/123396
132+
set_target_properties(clangCppInterOp PROPERTIES
133+
NO_SONAME 1
134+
LINK_FLAGS "-s WASM_BIGINT -s SIDE_MODULE=1 ${SYMBOLS_LIST}"
135+
)
136+
if (CPPINTEROP_ENABLE_TESTING)
137+
# When compiling Emscripten tests the shared library it links to is expected to be in the same folder as the compiled Javascript
138+
add_custom_command(TARGET clangCppInterOp POST_BUILD
139+
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:clangCppInterOp> ${CMAKE_BINARY_DIR}/unittests/CppInterOp/
140+
)
141+
endif(CPPINTEROP_ENABLE_TESTING)
142+
138143
endif()
139144

145+
target_compile_definitions(clangCppInterOp PUBLIC "_CINDEX_LIB_") # workaround for the use of `CINDEX_LINKAGE`
146+
140147
string(REPLACE ";" "\;" _VER CPPINTEROP_VERSION)
141148
set_source_files_properties(CppInterOp.cpp PROPERTIES COMPILE_DEFINITIONS
142149
"LLVM_BINARY_DIR=\"${LLVM_BINARY_DIR}\";CPPINTEROP_VERSION=\"${_VAR}\""

0 commit comments

Comments
 (0)