Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add beginnings of WebAssembly build support for mono. #33551

Merged
merged 10 commits into from
Apr 10, 2020
3 changes: 2 additions & 1 deletion eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<PropertyGroup>
<DefaultSubsets>clr+mono+libs+installer</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'Android' or '$(TargetOS)' == 'tvOS'">mono+libs+installer</DefaultSubsets>
<DefaultSubsetCategories Condition="'$(TargetOS)' == 'WebAssembly'">mono+libs</DefaultSubsetCategories>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -66,7 +67,7 @@
</PropertyGroup>

<PropertyGroup>
<RuntimeFlavor Condition="'$(TargetOS)' == 'tvOS' or '$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'Android'">Mono</RuntimeFlavor>
<RuntimeFlavor Condition="'$(TargetOS)' == 'tvOS' or '$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'Android' or '$(TargetOS)' == 'WebAssembly'">Mono</RuntimeFlavor>
<RuntimeFlavor Condition="'$(RuntimeFlavor)' == '' and $(_subset.Contains('+mono.runtime+')) and !$(_subset.Contains('+clr.runtime+'))">Mono</RuntimeFlavor>
<RuntimeFlavor Condition="'$(RuntimeFlavor)' == ''">CoreCLR</RuntimeFlavor>
</PropertyGroup>
Expand Down
9 changes: 7 additions & 2 deletions eng/native/build-commons.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,13 @@ build_native()

popd
else
echo "Executing cmake --build \"$intermediatesDir\" --target install -j $__NumProc"
cmake --build "$intermediatesDir" --target install -j "$__NumProc"
cmake_command=cmake
if [[ "$build_arch" == "wasm" ]]; then
cmake_command="emcmake $cmake_command"
fi

echo "Executing $cmake_command --build \"$intermediatesDir\" --target install -j $__NumProc"
$cmake_command --build "$intermediatesDir" --target install -j "$__NumProc"
fi

local exit_code="$?"
Expand Down
20 changes: 17 additions & 3 deletions eng/native/configureplatform.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ if(CLR_CMAKE_HOST_OS STREQUAL Windows)
endif(CLR_CMAKE_HOST_OS STREQUAL Windows)

if(CLR_CMAKE_HOST_OS STREQUAL Emscripten)
set(CLR_CMAKE_HOST_ARCH_WASM 1)
#set(CLR_CMAKE_HOST_UNIX 1) # TODO: this should be reenabled but it activates a bunch of additional compiler flags in configurecompiler.cmake
set(CLR_CMAKE_HOST_UNIX_WASM 1)
endif(CLR_CMAKE_HOST_OS STREQUAL Emscripten)

#--------------------------------------------
Expand Down Expand Up @@ -196,6 +197,9 @@ elseif(CLR_CMAKE_HOST_UNIX_AMD64)
elseif(CLR_CMAKE_HOST_UNIX_X86)
set(CLR_CMAKE_HOST_ARCH_I386 1)
set(CLR_CMAKE_HOST_ARCH "x86")
elseif(CLR_CMAKE_HOST_UNIX_WASM)
set(CLR_CMAKE_HOST_ARCH_WASM 1)
set(CLR_CMAKE_HOST_ARCH "wasm")
elseif(WIN32)
# CLR_CMAKE_HOST_ARCH is passed in as param to cmake
if (CLR_CMAKE_HOST_ARCH STREQUAL x64)
Expand Down Expand Up @@ -237,6 +241,8 @@ if (CLR_CMAKE_TARGET_ARCH STREQUAL x64)
set(CLR_CMAKE_TARGET_ARCH_ARM 1)
set(CLR_CMAKE_TARGET_ARCH_ARMV7L 1)
set(ARM_SOFTFP 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL wasm)
set(CLR_CMAKE_TARGET_ARCH_WASM 1)
else()
clr_unknown_arch()
endif()
Expand Down Expand Up @@ -306,6 +312,12 @@ if(CLR_CMAKE_TARGET_OS STREQUAL SunOS)
set(CLR_CMAKE_TARGET_SUNOS 1)
endif(CLR_CMAKE_TARGET_OS STREQUAL SunOS)

if(CLR_CMAKE_TARGET_OS STREQUAL Emscripten)
set(CLR_CMAKE_TARGET_UNIX 1)
set(CLR_CMAKE_TARGET_LINUX 1)
set(CLR_CMAKE_TARGET_EMSCRIPTEN 1)
endif(CLR_CMAKE_TARGET_OS STREQUAL Emscripten)

if(CLR_CMAKE_TARGET_UNIX)
if(CLR_CMAKE_TARGET_ARCH STREQUAL x64)
set(CLR_CMAKE_TARGET_UNIX_AMD64 1)
Expand All @@ -317,6 +329,8 @@ if(CLR_CMAKE_TARGET_UNIX)
set(CLR_CMAKE_TARGET_UNIX_ARM64 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL x86)
set(CLR_CMAKE_TARGET_UNIX_X86 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL wasm)
set(CLR_CMAKE_TARGET_UNIX_WASM 1)
else()
clr_unknown_arch()
endif()
Expand All @@ -343,7 +357,7 @@ else()
endif()
endif()

if(NOT CLR_CMAKE_HOST_ARCH_WASM)
if(NOT CLR_CMAKE_TARGET_EMSCRIPTEN)
# Skip check_pie_supported call on Android as ld from llvm toolchain with NDK API level 21
# complains about missing linker flag `-no-pie` (while level 28's ld does support this flag,
# but since we know that PIE is supported, we can safely skip this redundant check).
Expand All @@ -363,7 +377,7 @@ if(NOT CLR_CMAKE_HOST_ARCH_WASM)
endif(NOT CLR_CMAKE_TARGET_ANDROID)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
endif(NOT CLR_CMAKE_TARGET_EMSCRIPTEN)

string(TOLOWER "${CMAKE_BUILD_TYPE}" LOWERCASE_CMAKE_BUILD_TYPE)
if(LOWERCASE_CMAKE_BUILD_TYPE STREQUAL debug)
Expand Down
2 changes: 1 addition & 1 deletion eng/native/configuretools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if (CMAKE_C_COMPILER MATCHES "-?[0-9]+(\.[0-9]+)?$")
set(CLR_CMAKE_COMPILER_FILE_NAME_VERSION "${CMAKE_MATCH_0}")
endif()

if(NOT WIN32)
if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(APPLE)
set(TOOLSET_PREFIX "")
Expand Down
4 changes: 4 additions & 0 deletions eng/native/gen-buildsys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ if [[ "$scan_build" == "ON" && -n "$SCAN_BUILD_COMMAND" ]]; then
cmake_command="$SCAN_BUILD_COMMAND $cmake_command"
fi

if [[ "$build_arch" == "wasm" ]]; then
cmake_command="emcmake $cmake_command"
fi

# Include CMAKE_USER_MAKE_RULES_OVERRIDE as uninitialized since it will hold its value in the CMake cache otherwise can cause issues when branch switching
$cmake_command \
-G "$generator" \
Expand Down
2 changes: 1 addition & 1 deletion eng/pipelines/common/platform-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ jobs:
archType: wasm
platform: WebAssembly_wasm
container:
image: ubuntu-16.04-20200401182342-fe8b85d
image: ubuntu-18.04-webassembly-20200409132031-f70ea41
registry: mcr
jobParameters:
runtimeFlavor: ${{ parameters.runtimeFlavor }}
Expand Down
5 changes: 1 addition & 4 deletions eng/pipelines/libraries/base-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubGroup, ''), eq(parameters.archType, 'arm')) }}:
- _runtimeOSArg: /p:RuntimeOS=ubuntu.16.04

# force a value for OS when cross-building WebAssembly
- ${{ if eq(parameters.osGroup, 'WebAssembly') }}:
- _runtimeOSArg: -os ${{ parameters.osGroup }}

Expand Down Expand Up @@ -107,10 +108,6 @@ jobs:
- _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)'
- _testRunNamePrefixSuffix: $(runtimeFlavorName)_${{ parameters.liveRuntimeBuildConfig }}

# WebAssembly uses linux implementation detail
- ${{ if eq(parameters.osGroup, 'WebAssembly') }}:
- _runtimeArtifactName: 'CoreLib_Linux_x64_${{ parameters.liveRuntimeBuildConfig }}'

# Windows variables
- ${{ if eq(parameters.osGroup, 'Windows_NT') }}:
- _runtimeOSArg: /p:RuntimeOS=win10
Expand Down
24 changes: 6 additions & 18 deletions eng/pipelines/libraries/build-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,18 @@ jobs:

${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
dependsOn:
- ${{ if ne(parameters.osGroup, 'WebAssembly') }}:
# Use corelib dependencies for coreclr and non test builds
- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.testScope, '')) }}:
- ${{ format('coreclr_corelib_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}
- ${{ if or(ne(parameters.runtimeFlavor, 'coreclr'), ne(parameters.testScope, '')) }}:
- ${{ format('{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}
- ${{ if eq(parameters.osGroup, 'WebAssembly') }}:
- ${{ format('coreclr_corelib_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, 'linux', parameters.osSubgroup, 'x64', parameters.liveRuntimeBuildConfig) }}
# Use corelib dependencies for coreclr and non test builds
- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.testScope, '')) }}:
- ${{ format('coreclr_corelib_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}
- ${{ if or(ne(parameters.runtimeFlavor, 'coreclr'), ne(parameters.testScope, '')) }}:
- ${{ format('{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}

variables:
- _subset: libs
- _addtionalBuildArguments: ''
- ${{ parameters.variables }}
- ${{ if eq(parameters.osGroup, 'WebAssembly') }}:
- EMSDK_PATH: $(Build.BinariesDirectory)/emsdk
- EMSDK_PATH: /usr/local/emscripten
- ${{ if eq(parameters.runTests, true) }}:
- _subset: libs+libs.tests
- _addtionalBuildArguments: /p:ArchiveTests=true
Expand All @@ -80,15 +77,6 @@ jobs:
ln -s /usr/local/opt/openssl/lib/pkgconfig/openssl.pc /usr/local/lib/pkgconfig/
displayName: Install Build Dependencies

- ${{ if eq(parameters.osGroup, 'WebAssembly') }}:
- script: |
EMSCRIPTEN_VERSION=1.38.47
git clone https://github.com/emscripten-core/emsdk.git $(EMSDK_PATH)
cd $(EMSDK_PATH)
./emsdk install ${EMSCRIPTEN_VERSION}-upstream
./emsdk activate --embedded ${EMSCRIPTEN_VERSION}-upstream
displayName: Install Emscripten

- ${{ if eq(parameters.isOfficialBuild, true) }}:
- template: /eng/pipelines/common/restore-internal-tools.yml
parameters:
Expand Down
7 changes: 7 additions & 0 deletions eng/pipelines/mono/templates/build-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ jobs:
- ${{ if eq(parameters.osGroup, 'Android') }}:
- name: osOverride
value: -os Android
- ${{ if eq(parameters.osGroup, 'WebAssembly') }}:
- name: EMSDK_PATH
value: /usr/local/emscripten
- name: archType
value: wasm
- name: osOverride
value: '-os WebAssembly'
- ${{ parameters.variables }}

steps:
Expand Down
5 changes: 4 additions & 1 deletion eng/pipelines/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ jobs:
- Linux_arm
- Linux_arm64
- Linux_musl_x64
- WebAssembly_wasm
# - Linux_musl_arm64
- Windows_NT_x64
# - Windows_NT_x86
Expand Down Expand Up @@ -302,6 +303,7 @@ jobs:
- Linux_arm
- Linux_arm64
- Linux_musl_x64
- WebAssembly_wasm
# - Linux_musl_arm64
- Windows_NT_x64
# - Windows_NT_x86
Expand Down Expand Up @@ -420,6 +422,7 @@ jobs:
# - iOS_arm # https://github.com/dotnet/runtime/issues/34465
- iOS_arm64
- iOS_x64
- WebAssembly_wasm
jobParameters:
liveRuntimeBuildConfig: release

Expand All @@ -438,6 +441,7 @@ jobs:
# - iOS_arm # https://github.com/dotnet/runtime/issues/34465
- iOS_arm64
- iOS_x64
- WebAssembly_wasm
jobParameters:
liveRuntimeBuildConfig: debug

Expand All @@ -449,7 +453,6 @@ jobs:
jobTemplate: /eng/pipelines/libraries/build-job.yml
buildConfig: ${{ variables.debugOnPrReleaseOnRolling }}
platforms:
- WebAssembly_wasm
- ${{ if eq(variables['isFullMatrix'], false) }}:
- Windows_NT_x86
jobParameters:
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/Native/Unix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ elseif (CLR_CMAKE_TARGET_ARCH_I386)
add_definitions(-DTARGET_32BIT=1)
add_definitions(-DTARGET_X86)
add_definitions(-D_FILE_OFFSET_BITS=64)
elseif (CLR_CMAKE_TARGET_ARCH_WASM)
add_definitions(-DTARGET_32BIT=1)
add_definitions(-DTARGET_WASM)
elseif (CLR_CMAKE_TARGET_ARCH_ARM64)
add_definitions(-DTARGET_64BIT=1)
add_definitions(-DTARGET_ARM64)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(System.IO.Compression.Native C)

if (CLR_CMAKE_TARGET_WASM)
if (CLR_CMAKE_TARGET_ARCH_WASM)
add_definitions(-s USE_ZLIB)
elseif (CLR_CMAKE_TARGET_ANDROID)
# need special case here since we want to link against libz.so but find_package() would resolve libz.a
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/Native/Unix/System.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ else ()
set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_console.c)
endif ()

if (CLR_CMAKE_TARGET_LINUX)
if (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_networkchange.c)

if (!HAVE_LINUX_RTNETLINK_H)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int32_t SystemNative_GetOSArchitecture()
return ARCH_ARM64;
#elif defined(TARGET_AMD64)
return ARCH_X64;
#elif defined(TARGET_X86)
#elif defined(TARGET_X86) || defined(TARGET_WASM) // TODO: add arch for WASM
return ARCH_X86;
#else
#error Unidentified Architecture
Expand All @@ -71,7 +71,7 @@ int32_t SystemNative_GetProcessArchitecture()
return ARCH_ARM64;
#elif defined(TARGET_AMD64)
return ARCH_X64;
#elif defined(TARGET_X86)
#elif defined(TARGET_X86) || defined(TARGET_WASM) // TODO: add arch for WASM
return ARCH_X86;
#else
#error Unidentified Architecture
Expand Down
6 changes: 3 additions & 3 deletions src/libraries/Native/Unix/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ include(CheckTypeSize)

if (CLR_CMAKE_TARGET_ANDROID)
set(PAL_UNIX_NAME \"ANDROID\")
elseif (CLR_CMAKE_TARGET_ARCH_WASM)
set(PAL_UNIX_NAME \"WEBASSEMBLY\")
elseif (CLR_CMAKE_TARGET_LINUX)
set(PAL_UNIX_NAME \"LINUX\")
elseif (CLR_CMAKE_TARGET_OSX)
Expand All @@ -28,8 +30,6 @@ elseif (CLR_CMAKE_TARGET_FREEBSD)
set(CMAKE_REQUIRED_INCLUDES ${CROSS_ROOTFS}/usr/local/include)
elseif (CLR_CMAKE_TARGET_NETBSD)
set(PAL_UNIX_NAME \"NETBSD\")
elseif (CLR_CMAKE_TARGET_ARCH_WASM)
set(PAL_UNIX_NAME \"WEBASSEMBLY\")
else ()
message(FATAL_ERROR "Unknown platform. Cannot define PAL_UNIX_NAME, used by RuntimeInformation.")
endif ()
Expand Down Expand Up @@ -839,7 +839,7 @@ set (CMAKE_REQUIRED_LIBRARIES ${PREVIOUS_CMAKE_REQUIRED_LIBRARIES})
set (HAVE_INOTIFY 0)
if (HAVE_INOTIFY_INIT AND HAVE_INOTIFY_ADD_WATCH AND HAVE_INOTIFY_RM_WATCH)
set (HAVE_INOTIFY 1)
elseif (CLR_CMAKE_TARGET_LINUX)
elseif (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
message(FATAL_ERROR "Cannot find inotify functions on a Linux platform.")
endif()

Expand Down
5 changes: 4 additions & 1 deletion src/libraries/Native/build-native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ source "$__RepoRootDir"/eng/native/build-commons.sh

if [[ "$__BuildArch" == wasm ]]; then
if [[ -z "$EMSDK_PATH" ]]; then
echo "Error: Should set EMSDK_PATH environment variable pointing to emsdk root."
echo "Error: You need to set the EMSDK_PATH environment variable pointing to the emscripten SDK root."
exit 1
fi
source "$EMSDK_PATH"/emsdk_env.sh

export CLR_CC=$(which emcc)
export CLR_CXX=$(which em++)
Comment on lines +57 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit, typically posix-y command -v is preferred over which in this repo. (same goes for which false below)

Copy link
Member

@akoeplinger akoeplinger Apr 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@am11 I tried that but it didn't work since we expect the full path in CLR_CC and command -v doesn't do that (for false at least)

elif [[ "$__TargetOS" == iOS ]]; then
# nothing to do here
true
Expand Down
3 changes: 2 additions & 1 deletion src/mono/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@
<TargetsiOSSimulator Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x64'">true</TargetsiOSSimulator>
<TargetstvOSSimulator Condition="'$(TargetstvOS)' == 'true' and '$(Platform)' == 'x64'">true</TargetstvOSSimulator>
<TargetsAndroid Condition="'$(TargetOS)' == 'Android'">true</TargetsAndroid>
<TargetsWASM Condition="'$(TargetOS)' == 'WebAssembly'">true</TargetsWASM>
<TargetsWindows Condition="'$(TargetOS)' == 'Windows_NT'">true</TargetsWindows>
<TargetsUnix Condition="'$(TargetsFreeBSD)' == 'true' or '$(TargetsLinux)' == 'true' or '$(TargetsNetBSD)' == 'true' or '$(TargetsOSX)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetsAndroid)' == 'true'">true</TargetsUnix>
<TargetsUnix Condition="'$(TargetsFreeBSD)' == 'true' or '$(TargetsLinux)' == 'true' or '$(TargetsNetBSD)' == 'true' or '$(TargetsOSX)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetsAndroid)' == 'true' or '$(TargetsWASM)' == 'true'">true</TargetsUnix>
</PropertyGroup>

<PropertyGroup>
Expand Down
Loading