diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index 6fdf75197..99151473a 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -42,6 +42,13 @@ jobs: llvm_enable_projects: "clang;lld" llvm_targets_to_build: "WebAssembly" emsdk_ver: "3.1.73" + - name: win2025-x86-clang-repl-19-emscripten + os: windows-2025 + clang-runtime: '19' + cling: Off + llvm_enable_projects: "clang;lld" + llvm_targets_to_build: "WebAssembly" + emsdk_ver: "3.1.73" steps: - uses: actions/checkout@v4 @@ -113,7 +120,7 @@ jobs: lookup-only: true - name: Setup emsdk - if: ${{ runner.os != 'windows' && steps.cache.outputs.cache-hit != 'true' }} + if: ${{ steps.cache.outputs.cache-hit != 'true' }} run: | git clone --depth=1 https://github.com/emscripten-core/emsdk.git cd emsdk @@ -136,8 +143,9 @@ jobs: - name: Install deps on Windows if: ${{ runner.os == 'windows' && steps.cache.outputs.cache-hit != 'true' }} run: | - choco install findutils + choco install findutils ninja $env:PATH="C:\Program Files (x86)\GnuWin32\bin;$env:PATH" + $env:PATH="C:\Program Files (x86)\Ninja\bin;$env:PATH" - name: Install deps on MacOS if: ${{ runner.os == 'macOS' && steps.cache.outputs.cache-hit != 'true' }} @@ -258,10 +266,11 @@ jobs: fi - - name: Build LLVM/Cling on Windows systems if the cache is invalid + - name: Build LLVM/Cling on Windows systems if the cache is invalid (emscripten) if: ${{ runner.os == 'windows' && steps.cache.outputs.cache-hit != 'true' }} run: | - + .\emsdk\emsdk activate ${{matrix.emsdk_ver}} + .\emsdk\emsdk_env.ps1 if ( "${{ matrix.cling }}" -imatch "On" ) { git clone https://github.com/root-project/cling.git @@ -284,54 +293,66 @@ jobs: if ( "${{ matrix.cling }}" -imatch "On" ) { cd build - cmake -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects}}" ` - -DLLVM_EXTERNAL_PROJECTS=cling ` - -DLLVM_EXTERNAL_CLING_SOURCE_DIR="$env:CLING_DIR" ` - -DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" ` - -DCMAKE_BUILD_TYPE=Release ` - -DLLVM_ENABLE_ASSERTIONS=ON ` - -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` - -DCLANG_ENABLE_ARCMT=OFF ` - -DCLANG_ENABLE_FORMAT=OFF ` - -DCLANG_ENABLE_BOOTSTRAP=OFF ` - -DLLVM_ENABLE_ZSTD=OFF ` - -DLLVM_ENABLE_TERMINFO=OFF ` - -DLLVM_ENABLE_LIBXML2=OFF ` + emcmake cmake -DLLVM_EXTERNAL_PROJECTS=cling ` + -DLLVM_EXTERNAL_CLING_SOURCE_DIR=../../cling ` + -DCMAKE_BUILD_TYPE=Release ` + -DLLVM_HOST_TRIPLE=wasm32-unknown-emscripten ` + -DLLVM_ENABLE_ASSERTIONS=ON ` + -DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" ` + -DLLVM_ENABLE_LIBEDIT=OFF ` + -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects }}" ` + -DLLVM_ENABLE_ZSTD=OFF ` + -DLLVM_ENABLE_LIBXML2=OFF ` + -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` + -DCLANG_ENABLE_ARCMT=OFF ` + -DCLANG_ENABLE_BOOTSTRAP=OFF ` + -DCMAKE_CXX_FLAGS="-Dwait4=__syscall_wait4" ` + -DLLVM_INCLUDE_BENCHMARKS=OFF ` + -DLLVM_INCLUDE_EXAMPLES=OFF ` + -DLLVM_INCLUDE_TESTS=OFF ` + -DLLVM_ENABLE_THREADS=OFF ` + -G Ninja ` + -DLLVM_BUILD_TOOLS=OFF ` + -DLLVM_ENABLE_LIBPFM=OFF ` + -DCLANG_BUILD_TOOLS=OFF ` ..\llvm - cmake --build . --config Release --target clang --parallel ${{ env.ncpus }} - cmake --build . --config Release --target cling --parallel ${{ env.ncpus }} - # Now build gtest.a and gtest_main for CppInterOp to run its tests. - cmake --build . --config Release --target gtest_main --parallel ${{ env.ncpus }} + emmake make clang cling lld gtest_main } else { - cp -r ..\patches\llvm\clang${{ matrix.clang-runtime }}* + cp -r ..\patches\llvm\emscripten-clang${{ matrix.clang-runtime }}* + cp -r ..\patches\llvm\Windows-emscripten-clang${{ matrix.clang-runtime }}* #FIXME: Apply patches without hardcoding - if ( "${{ matrix.clang-runtime }}" -imatch "16" ) + if ( "${{ matrix.clang-runtime }}" -imatch "19" ) { - git apply -v clang16-1-Value.patch - git apply -v clang16-2-CUDA.patch - git apply -v clang16-3-WeakRef.patch - } - elseif ( "${{ matrix.clang-runtime }}" -imatch "17" ) - { - git apply -v clang17-1-NewOperator.patch + git apply -v Windows-emscripten-clang19-1-CrossCompile.patch + git apply -v emscripten-clang19-2-shift-temporary-files-to-tmp-dir.patch + git apply -v emscripten-clang19-3-remove-zdefs.patch } cd build echo "Apply clang${{ matrix.clang-runtime }}-*.patch patches:" - cmake -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects}}" ` - -DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" ` - -DCMAKE_BUILD_TYPE=Release ` - -DLLVM_ENABLE_ASSERTIONS=ON ` - -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` - -DCLANG_ENABLE_ARCMT=OFF ` - -DCLANG_ENABLE_FORMAT=OFF ` - -DCLANG_ENABLE_BOOTSTRAP=OFF ` - -DLLVM_ENABLE_ZSTD=OFF ` - -DLLVM_ENABLE_TERMINFO=OFF ` - -DLLVM_ENABLE_LIBXML2=OFF ` - ..\llvm - cmake --build . --config Release --target clang clang-repl --parallel ${{ env.ncpus }} + emcmake cmake -DCMAKE_BUILD_TYPE=Release ` + -DLLVM_HOST_TRIPLE=wasm32-unknown-emscripten ` + -DLLVM_ENABLE_ASSERTIONS=ON ` + -DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" ` + -DLLVM_ENABLE_LIBEDIT=OFF ` + -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects }}" ` + -DLLVM_ENABLE_ZSTD=OFF ` + -DLLVM_ENABLE_LIBXML2=OFF ` + -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` + -DCLANG_ENABLE_ARCMT=OFF ` + -DCLANG_ENABLE_BOOTSTRAP=OFF ` + -DCMAKE_CXX_FLAGS="-Dwait4=__syscall_wait4" ` + -DLLVM_INCLUDE_BENCHMARKS=OFF ` + -DLLVM_INCLUDE_EXAMPLES=OFF ` + -DLLVM_INCLUDE_TESTS=OFF ` + -DLLVM_ENABLE_THREADS=OFF ` + -DLLVM_BUILD_TOOLS=OFF ` + -DLLVM_ENABLE_LIBPFM=OFF ` + -DCLANG_BUILD_TOOLS=OFF ` + -G Ninja ` + ..\llvm + emmake ninja libclang clangInterpreter clangStaticAnalyzerCore lldWasm } cd ..\ rm -r -force $(find.exe . -maxdepth 1 ! -name "build" ! -name "llvm" ! -name "clang" ! -name ".") @@ -352,9 +373,9 @@ jobs: cd ..\.. } - - name: Save Cache LLVM/Clang runtime build directory (Unix Systems Emscripten) + - name: Save Cache LLVM/Clang runtime build directory uses: actions/cache/save@v4 - if: ${{ runner.os != 'windows' && steps.cache.outputs.cache-hit != 'true' }} + if: ${{ steps.cache.outputs.cache-hit != 'true' }} with: path: | llvm-project @@ -387,6 +408,12 @@ jobs: cling: Off micromamba_shell_init: bash emsdk_ver: "3.1.73" + - name: win2025-x86-clang-repl-19-emscripten + os: windows-2025 + clang-runtime: '19' + cling: Off + micromamba_shell_init: powershell + emsdk_ver: "3.1.73" steps: - uses: actions/checkout@v4 @@ -426,6 +453,14 @@ jobs: echo "ncpus=$(nproc --all)" >> $GITHUB_ENV fi + - name: Setup default Build Type on Windows + if: ${{ runner.os == 'windows' }} + run: | + echo "BUILD_TYPE=Release" >> $env:GITHUB_ENV + echo "CODE_COVERAGE=0" >> $env:GITHUB_ENV + $env:ncpus=$([Environment]::ProcessorCount) + echo "ncpus=$env:ncpus" >> $env:GITHUB_ENV + - name: install mamba uses: mamba-org/setup-micromamba@main with: @@ -517,7 +552,100 @@ jobs: echo "CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH" >> $GITHUB_ENV echo "PREFIX=$PREFIX" >> $GITHUB_ENV + - name: micromamba shell hook + if: ${{ runner.os == 'windows' }} + shell: powershell + run: | + micromamba shell hook -s cmd.exe --root-prefix C:\Users\runneradmin\micromamba-root + + - name: Build and Test/Install CppInterOp on Windows systems + continue-on-error: true + if: ${{ runner.os == 'windows' }} + shell: powershell + run: | + micromamba create -f environment-wasm.yml --platform=emscripten-wasm32 + .\emsdk\emsdk activate ${{matrix.emsdk_ver}} + .\emsdk\emsdk_env.ps1 + $env:PWD_DIR= $PWD.Path + $env:SYSROOT_PATH="$env:EMSDK/upstream/emscripten/cache/sysroot" + $env:PREFIX="%CONDA_PREFIX%/envs/CppInterOp-wasm" + $env:CMAKE_PREFIX_PATH=$env:PREFIX + $env:CMAKE_SYSTEM_PREFIX_PATH=$env:PREFIX + + $env:LLVM_DIR="$env:PWD_DIR\llvm-project" + echo "LLVM_DIR=$env:LLVM_DIR" + echo "LLVM_DIR=$env:LLVM_DIR" >> $env:GITHUB_ENV + + $env:LLVM_BUILD_DIR="$env:PWD_DIR\llvm-project\build" + echo "LLVM_BUILD_DIR=$env:LLVM_BUILD_DIR" + echo "LLVM_BUILD_DIR=$env:LLVM_BUILD_DIR" >> $env:GITHUB_ENV + + if ( "${{ matrix.cling }}" -imatch "On" ) + { + $env:CLING_DIR="$env:PWD_DIR\cling" + echo "CLING_DIR=$env:CLING_DIR" + echo "CLING_DIR=$env:CLING_DIR" >> $env:GITHUB_ENV + + $env:CLING_BUILD_DIR="$env:PWD_DIR\cling\build" + echo "CLING_BUILD_DIR=$env:CLING_BUILD_DIR" + echo "CLING_BUILD_DIR=$env:CLING_BUILD_DIR" >> $env:GITHUB_ENV + + $env:CPLUS_INCLUDE_PATH="$env:CLING_DIR\tools\cling\include;$env:CLING_BUILD_DIR\include;$env:LLVM_DIR\llvm\include;$env:LLVM_DIR\clang\include;$env:LLVM_BUILD_DIR\include;$env:LLVM_BUILD_DIR\tools\clang\include;$env:PWD_DIR\include;" + echo "CPLUS_INCLUDE_PATH=$env:CPLUS_INCLUDE_PATH" + echo "CPLUS_INCLUDE_PATH=$env:CPLUS_INCLUDE_PATH" >> $env:GITHUB_ENV + } + else + { + $env:CPLUS_INCLUDE_PATH="$env:LLVM_DIR\llvm\include;$env:LLVM_DIR\clang\include;$env:LLVM_BUILD_DIR\include;$env:LLVM_BUILD_DIR\tools\clang\include;$env:PWD_DIR\include;" + echo "CPLUS_INCLUDE_PATH=$env:CPLUS_INCLUDE_PATH" + echo "CPLUS_INCLUDE_PATH=$env:CPLUS_INCLUDE_PATH" >> $env:GITHUB_ENV + } + + # Build CppInterOp next to cling and llvm-project. + mkdir build + cd build + $env:CPPINTEROP_BUILD_DIR="$env:PWD_DIR" + echo "CPPINTEROP_BUILD_DIR=$env:CPPINTEROP_BUILD_DIR" + echo "CPPINTEROP_BUILD_DIR=$env:CPPINTEROP_BUILD_DIR" >> $env:GITHUB_ENV + if ( "${{ matrix.cling }}" -imatch "On" ) + { + emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} ` + -DCPPINTEROP_USE_CLING=ON ` + -DCPPINTEROP_USE_REPL=OFF ` + -DCMAKE_PREFIX_PATH="$env:PREFIX" ` + -DCling_DIR="$env:LLVM_BUILD_DIR\tools\cling" ` + -DLLVM_DIR="$env:LLVM_BUILD_DIR\lib\cmake\llvm" ` + -DLLD_DIR="$env:LLVM_BUILD_DIR\lib\cmake\lld" ` + -DClang_DIR="$env:LLVM_BUILD_DIR\lib\cmake\clang" ` + -DBUILD_SHARED_LIBS=ON ` + -DCODE_COVERAGE=${{ env.CODE_COVERAGE }} ` + -DCMAKE_INSTALL_PREFIX="$env:PREFIX" ` + -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON ` + -DLLVM_ENABLE_WERROR=On ` + -DSYSROOT_PATH="$env:SYSROOT_PATH" ` + ..\ + } + else + { + emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} ` + -DCMAKE_PREFIX_PATH="$env:PREFIX" ` + -DLLVM_DIR="$env:LLVM_BUILD_DIR\lib\cmake\llvm" ` + -DLLD_DIR="$env:LLVM_BUILD_DIR\lib\cmake\lld" ` + -DClang_DIR="$env:LLVM_BUILD_DIR\lib\cmake\clang" ` + -DBUILD_SHARED_LIBS=ON ` + -DCODE_COVERAGE=${{ env.CODE_COVERAGE }} ` + -DCMAKE_INSTALL_PREFIX="$env:PREFIX" ` + -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON ` + -DLLVM_ENABLE_WERROR=On ` + -DSYSROOT_PATH="$env:SYSROOT_PATH" ` + ..\ + } + emmake make -j ${{ env.ncpus }} check-cppinterop + emmake make -j ${{ env.ncpus }} install + + - name: Build xeus-cpp + if: ${{ runner.os != 'windows' }} shell: bash -l {0} run: | ./emsdk/emsdk activate ${{matrix.emsdk_ver}} @@ -540,9 +668,10 @@ jobs: emmake make -j ${{ env.ncpus }} install - name: Test xeus-cpp C++ Emscripten + if: ${{ runner.os != 'windows' }} shell: bash -l {0} run: | set -e micromamba activate CppInterOp-wasm cd ./xeus-cpp/build/test - node test_xeus_cpp.js \ No newline at end of file + node test_xeus_cpp.js diff --git a/Emscripten-build-instructions.md b/Emscripten-build-instructions.md index 5e9194b2d..512aa4d7e 100644 --- a/Emscripten-build-instructions.md +++ b/Emscripten-build-instructions.md @@ -5,7 +5,7 @@ It should be noted that the wasm build of CppInterOp is still experimental and s ## CppInterOp Wasm Build Instructions This document first starts with the instructions on how to build a wasm build of CppInterOp. Before we start it should be noted that -unlike the non wasm version of CppInterOp we currently only support the Clang-REPL backend using llvm>19 for osx and Linux. +unlike the non wasm version of CppInterOp we currently only support the Clang-REPL backend using llvm>19. We will first make folder to build our wasm build of CppInterOp. This can be done by executing the following command ```bash @@ -25,7 +25,7 @@ git clone https://github.com/emscripten-core/emsdk.git ./emsdk/emsdk install 3.1.73 ``` -and activate the emsdk environment (we are defining SYSROOT_PATH for use later) +and to activate the emsdk environment on Linux and osx execute (we are defining SYSROOT_PATH for use later) ```bash ./emsdk/emsdk activate 3.1.73 @@ -33,8 +33,17 @@ source ./emsdk/emsdk_env.sh export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot ``` +and on Windows execute in Powershell + +```powershell +.\emsdk\emsdk activate 3.1.73 +.\emsdk\emsdk_env.ps1 +$env:PWD_DIR= $PWD.Path +$env:SYSROOT_PATH="$env:EMSDK/upstream/emscripten/cache/sysroot" +``` + Now clone the 19.x release of the LLVM project repository and CppInterOp (the building of the emscripten version of llvm can be -avoided by executing micromamba install llvm -c and setting the LLVM_BUILD_DIR appropriately) +avoided by executing micromamba install llvm -c and setting the LLVM_BUILD_DIR/$env:LLVM_BUILD_DIR appropriately) ```bash @@ -42,14 +51,27 @@ git clone --depth=1 --branch release/19.x https://github.com/llvm/llvm-project.g git clone --depth=1 https://github.com/compiler-research/CppInterOp.git ``` -Now move into the cloned llvm-project folder and apply the required patches +Now move into the cloned llvm-project folder and apply the required patches. On Linux and osx this +executing ```bash cd ./llvm-project/ git apply -v ../CppInterOp/patches/llvm/emscripten-clang19-*.patch ``` -We are now in a position to build an emscripten build of llvm by executing the following +On Windows execute the following + +```powershell +cd .\llvm-project\ +cp -r ..\patches\llvm\emscripten-clang${{ matrix.clang-runtime }}* +cp -r ..\patches\llvm\Windows-emscripten-clang${{ matrix.clang-runtime }}* +git apply -v Windows-emscripten-clang19-1-CrossCompile.patch +git apply -v emscripten-clang19-2-shift-temporary-files-to-tmp-dir.patch +git apply -v emscripten-clang19-3-remove-zdefs.patch +``` + +We are now in a position to build an emscripten build of llvm by executing the following on Linux +and osx ```bash mkdir build cd build @@ -78,13 +100,49 @@ emmake make clangInterpreter clangStaticAnalyzerCore -j $(nproc --all) emmake make lldWasm -j $(nproc --all) ``` -Once this finishes building we need to take note of where we built our llvm build. This can be done by executing the following +or executing + +```powershell +mkdir build +cd build +emcmake cmake -DCMAKE_BUILD_TYPE=Release ` + -DLLVM_HOST_TRIPLE=wasm32-unknown-emscripten ` + -DLLVM_ENABLE_ASSERTIONS=ON ` + -DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" ` + -DLLVM_ENABLE_LIBEDIT=OFF ` + -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects }}" ` + -DLLVM_ENABLE_ZSTD=OFF ` + -DLLVM_ENABLE_LIBXML2=OFF ` + -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` + -DCLANG_ENABLE_ARCMT=OFF ` + -DCLANG_ENABLE_BOOTSTRAP=OFF ` + -DCMAKE_CXX_FLAGS="-Dwait4=__syscall_wait4" ` + -DLLVM_INCLUDE_BENCHMARKS=OFF ` + -DLLVM_INCLUDE_EXAMPLES=OFF ` + -DLLVM_INCLUDE_TESTS=OFF ` + -DLLVM_ENABLE_THREADS=OFF ` + -DLLVM_BUILD_TOOLS=OFF ` + -DLLVM_ENABLE_LIBPFM=OFF ` + -DCLANG_BUILD_TOOLS=OFF ` + -G Ninja ` + ..\llvm +emmake ninja libclang clangInterpreter clangStaticAnalyzerCore lldWasm +``` + +on Windows. Once this finishes building we need to take note of where we built our llvm build. This can be done by executing the following on Linux and osx ```bash export LLVM_BUILD_DIR=$PWD ``` -We can move onto building the wasm version of CppInterOp. We will do this within a Conda environment. We can achieve this +and + +```powershell +$env:PWD_DIR= $PWD.Path +$env:LLVM_BUILD_DIR="$env:PWD_DIR\llvm-project\build" +``` + +on Windows. We can move onto building the wasm version of CppInterOp. We will do this within a Conda environment. We can achieve this by executing (assumes you have micromamba installed and that your shell is initialised for the micromamba install) ```bash @@ -93,7 +151,7 @@ micromamba create -f environment-wasm.yml --platform=emscripten-wasm32 micromamba activate CppInterOp-wasm ``` -You will also want to set a few environment variables +You will also want to set a few environment variables. On Linux and osx you define them as follows ```bash export PREFIX=$CONDA_PREFIX @@ -101,7 +159,15 @@ export CMAKE_PREFIX_PATH=$PREFIX export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX ``` -Now to build and test your Emscripten build of CppInterOp by executing the following +and + +```powershell +$env:PREFIX="%CONDA_PREFIX%/envs/CppInterOp-wasm" +$env:CMAKE_PREFIX_PATH=$env:PREFIX +$env:CMAKE_SYSTEM_PREFIX_PATH=$env:PREFIX +``` + +on Windows. Now to build and test your Emscripten build of CppInterOp on Linux and osx execute the following ```bash mkdir build @@ -118,6 +184,24 @@ emcmake cmake -DCMAKE_BUILD_TYPE=Release \ emmake make -j $(nproc --all) check-cppinterop ``` +To build and test your Emscripten build of CppInterOp on Windows execute the following + +```powershell +emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} ` + -DCMAKE_PREFIX_PATH="$env:PREFIX" ` + -DLLVM_DIR="$env:LLVM_BUILD_DIR\lib\cmake\llvm" ` + -DLLD_DIR="$env:LLVM_BUILD_DIR\lib\cmake\lld" ` + -DClang_DIR="$env:LLVM_BUILD_DIR\lib\cmake\clang" ` + -DBUILD_SHARED_LIBS=ON ` + -DCODE_COVERAGE=${{ env.CODE_COVERAGE }} ` + -DCMAKE_INSTALL_PREFIX="$env:PREFIX" ` + -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON ` + -DLLVM_ENABLE_WERROR=On ` + -DSYSROOT_PATH="$env:SYSROOT_PATH" ` + ..\ + emmake make -j $(nproc --all) check-cppinterop +``` + Assuming it passes all test you can install by executing the following ```bash diff --git a/cmake/modules/GoogleTest.cmake b/cmake/modules/GoogleTest.cmake index 4fd88d565..9164811c9 100644 --- a/cmake/modules/GoogleTest.cmake +++ b/cmake/modules/GoogleTest.cmake @@ -20,8 +20,13 @@ endif() include(ExternalProject) if (EMSCRIPTEN) - set(config_cmd emcmake cmake) - set(build_cmd emmake make) + if (CMAKE_C_COMPILER MATCHES ".bat") + set(config_cmd emcmake.bat cmake) + set(build_cmd emmake.bat make) + else() + set(config_cmd emcmake cmake) + set(build_cmd emmake make) + endif() else() set(config_cmd ${CMAKE_COMMAND}) set(build_cmd ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/unittests/googletest-prefix/src/googletest-build/ --config $) diff --git a/docs/Emscripten-build-instructions.rst b/docs/Emscripten-build-instructions.rst index 3bab43315..22f9e3f89 100644 --- a/docs/Emscripten-build-instructions.rst +++ b/docs/Emscripten-build-instructions.rst @@ -12,7 +12,7 @@ experimental and subject to change. This document first starts with the instructions on how to build a wasm build of CppInterOp. Before we start it should be noted that unlike the non wasm version of CppInterOp we currently only support the Clang-REPL -backend using llvm>19 for osx and Linux. We will first make folder to +backend using llvm>19. We will first make folder to build our wasm build of CppInterOp. This can be done by executing the following command @@ -35,7 +35,8 @@ This can be installed by executing (we only currently support version git clone https://github.com/emscripten-core/emsdk.git ./emsdk/emsdk install 3.1.73 -and activate the emsdk environment (we are defining SYSROOT_PATH for use later) +and to activate the emsdk environment on Linux and osx execute +(we are defining SYSROOT_PATH for use later) .. code:: bash @@ -43,10 +44,19 @@ and activate the emsdk environment (we are defining SYSROOT_PATH for use later) source ./emsdk/emsdk_env.sh export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot +and on Windows execute in Powershell + +.. code:: powershell + + .\emsdk\emsdk activate 3.1.73 + .\emsdk\emsdk_env.ps1 + $env:PWD_DIR= $PWD.Path + $env:SYSROOT_PATH="$env:EMSDK/upstream/emscripten/cache/sysroot" + Now clone the 19.x release of the LLVM project repository and CppInterOp (the building of the emscripten version of llvm can be avoided by executing micromamba install llvm -c - and setting the LLVM_BUILD_DIR + and setting the LLVM_BUILD_DIR/$env:LLVM_BUILD_DIR appropriately) .. code:: bash @@ -54,16 +64,27 @@ appropriately) git clone --depth=1 --branch release/19.x https://github.com/llvm/llvm-project.git git clone --depth=1 https://github.com/compiler-research/CppInterOp.git -Now move into the cloned llvm-project folder and apply the required -patches +Now move into the cloned llvm-project folder and apply the required patches. On Linux and osx this +executing .. code:: bash cd ./llvm-project/ git apply -v ../CppInterOp/patches/llvm/emscripten-clang19-*.patch -We are now in a position to build an emscripten build of llvm by -executing the following +On Windows execute the following + +.. code:: powershell + + cd .\llvm-project\ + cp -r ..\patches\llvm\emscripten-clang${{ matrix.clang-runtime }}* + cp -r ..\patches\llvm\Windows-emscripten-clang${{ matrix.clang-runtime }}* + git apply -v Windows-emscripten-clang19-1-CrossCompile.patch + git apply -v emscripten-clang19-2-shift-temporary-files-to-tmp-dir.patch + git apply -v emscripten-clang19-3-remove-zdefs.patch + +We are now in a position to build an emscripten build of llvm by executing the following on Linux +and osx .. code:: bash @@ -93,14 +114,52 @@ executing the following emmake make clangInterpreter clangStaticAnalyzerCore -j $(nproc --all) emmake make lldWasm -j $(nproc --all) -Once this finishes building we need to take note of where we built our -llvm build. This can be done by executing the following +or executing + +.. code:: powershell + + mkdir build + cd build + emcmake cmake -DCMAKE_BUILD_TYPE=Release ` + -DLLVM_HOST_TRIPLE=wasm32-unknown-emscripten ` + -DLLVM_ENABLE_ASSERTIONS=ON ` + -DLLVM_TARGETS_TO_BUILD="${{ matrix.llvm_targets_to_build }}" ` + -DLLVM_ENABLE_LIBEDIT=OFF ` + -DLLVM_ENABLE_PROJECTS="${{ matrix.llvm_enable_projects }}" ` + -DLLVM_ENABLE_ZSTD=OFF ` + -DLLVM_ENABLE_LIBXML2=OFF ` + -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` + -DCLANG_ENABLE_ARCMT=OFF ` + -DCLANG_ENABLE_BOOTSTRAP=OFF ` + -DCMAKE_CXX_FLAGS="-Dwait4=__syscall_wait4" ` + -DLLVM_INCLUDE_BENCHMARKS=OFF ` + -DLLVM_INCLUDE_EXAMPLES=OFF ` + -DLLVM_INCLUDE_TESTS=OFF ` + -DLLVM_ENABLE_THREADS=OFF ` + -DLLVM_BUILD_TOOLS=OFF ` + -DLLVM_ENABLE_LIBPFM=OFF ` + -DCLANG_BUILD_TOOLS=OFF ` + -G Ninja ` + ..\llvm + emmake ninja libclang clangInterpreter clangStaticAnalyzerCore lldWasm + +on Windows. Once this finishes building we need to take note of where we built our llvm build. +This can be done by executing the following on Linux and osx .. code:: bash export LLVM_BUILD_DIR=$PWD -We can move onto building the wasm version of CppInterOp. We will do + +and + +.. code:: powershell + + $env:PWD_DIR= $PWD.Path + $env:LLVM_BUILD_DIR="$env:PWD_DIR\llvm-project\build" + + +on Windows. We can move onto building the wasm version of CppInterOp. We will do this within a Conda environment. We can achieve this by executing (assumes you have micromamba installed and that your shell is initialised for the micromamba install) @@ -111,7 +170,7 @@ initialised for the micromamba install) micromamba create -f environment-wasm.yml --platform=emscripten-wasm32 micromamba activate CppInterOp-wasm -You will also want to set a few environment variables +You will also want to set a few environment variables. On Linux and osx you define them as follows .. code:: bash @@ -119,7 +178,15 @@ You will also want to set a few environment variables export CMAKE_PREFIX_PATH=$PREFIX export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX -Now to build and test your Emscripten build of CppInterOp by executing the following +and + +.. code:: powershell + + $env:PREFIX="%CONDA_PREFIX%/envs/CppInterOp-wasm" + $env:CMAKE_PREFIX_PATH=$env:PREFIX + $env:CMAKE_SYSTEM_PREFIX_PATH=$env:PREFIX + +on Windows. Now to build and test your Emscripten build of CppInterOp on Linux and osx execute the following .. code:: bash @@ -136,6 +203,24 @@ Now to build and test your Emscripten build of CppInterOp by executing the follo ../ emmake make -j $(nproc --all) check-cppinterop +To build and test your Emscripten build of CppInterOp on Windows execute the following + +.. code:: powershell + + emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} ` + -DCMAKE_PREFIX_PATH="$env:PREFIX" ` + -DLLVM_DIR="$env:LLVM_BUILD_DIR\lib\cmake\llvm" ` + -DLLD_DIR="$env:LLVM_BUILD_DIR\lib\cmake\lld" ` + -DClang_DIR="$env:LLVM_BUILD_DIR\lib\cmake\clang" ` + -DBUILD_SHARED_LIBS=ON ` + -DCODE_COVERAGE=${{ env.CODE_COVERAGE }} ` + -DCMAKE_INSTALL_PREFIX="$env:PREFIX" ` + -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON ` + -DLLVM_ENABLE_WERROR=On ` + -DSYSROOT_PATH="$env:SYSROOT_PATH" ` + ..\ + emmake make -j $(nproc --all) check-cppinterop + Assuming it passes all test you can install by executing the following. .. code:: bash diff --git a/patches/llvm/Windows-emscripten-clang19-1-CrossCompile.patch b/patches/llvm/Windows-emscripten-clang19-1-CrossCompile.patch new file mode 100644 index 000000000..a1ffeccc8 --- /dev/null +++ b/patches/llvm/Windows-emscripten-clang19-1-CrossCompile.patch @@ -0,0 +1,20 @@ +diff --git a/llvm/cmake/modules/CrossCompile.cmake b/llvm/cmake/modules/CrossCompile.cmake +index 39b4abaa0..474ceddbb 100644 +--- a/llvm/cmake/modules/CrossCompile.cmake ++++ b/llvm/cmake/modules/CrossCompile.cmake +@@ -74,10 +74,12 @@ function(llvm_create_cross_target project_name target_name toolchain buildtype) + endif() + + add_custom_command(OUTPUT ${${project_name}_${target_name}_BUILD}/CMakeCache.txt +- COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" ++ COMMAND ${CMAKE_COMMAND} -G Ninja + -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}" +- -DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_C_COMPILER_LAUNCHER}" +- -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CXX_COMPILER_LAUNCHER}" ++ -DCMAKE_C_COMPILER="clang-cl" ++ -DCMAKE_CXX_COMPILER="clang-cl" ++ -DCMAKE_ASM_MASM_COMPILER=llvm-ml ++ -DCMAKE_ASM_MASM_FLAGS="-m64" + ${CROSS_TOOLCHAIN_FLAGS_${target_name}} ${CMAKE_CURRENT_SOURCE_DIR} + ${CROSS_TOOLCHAIN_FLAGS_${project_name}_${target_name}} + -DLLVM_TARGET_IS_CROSSCOMPILE_HOST=TRUE