[wasm] windows build improvements (#49771)
authorRadek Doulik <radekdoulik@gmail.com>
Mon, 22 Mar 2021 19:42:05 +0000 (20:42 +0100)
committerGitHub <noreply@github.com>
Mon, 22 Mar 2021 19:42:05 +0000 (20:42 +0100)
Fix build on windows in folders containing space(s) in the name and also
in case where `EMSDK_PATH` contains space(s).

* Add few quotes

To fix windows build in directory containing spaces.

* Add quotes around link attributes paths

* More quotes and trimming

* More improvements related to EMSDK_PATH

* Use immediate set for EMSCRIPTEN_VERSION

* Do not set ExeExt twice

* Force ninja on Browser/windows

And check for cmake and ninja in CheckEnv

* Apply Ankit's quotation changes

* Simplify forcing wasm, fix typos

* Use -File instead of & "<ps1 script>"

* Fix typo

* Only add the escaped quotes on windows

Co-authored-by: Ankit Jain <radical@gmail.com>
eng/build.ps1
eng/native/gen-buildsys.cmd
eng/native/init-vs-env.cmd
src/libraries/Common/src/System/Security/Cryptography/Asn1/AsnXml.targets
src/libraries/illink-sharedframework.targets
src/mono/mono.proj
src/mono/mono/mini/CMakeLists.txt
src/mono/wasm/wasm.proj

index bcd9c9e..12d3d00 100644 (file)
@@ -245,9 +245,15 @@ foreach ($argument in $PSBoundParameters.Keys)
 
 $failedBuilds = @()
 
-if (($os -eq "Browser") -and ($arch -ne "wasm")) {
+if ($os -eq "Browser") {
   # override default arch for Browser, we only support wasm
   $arch = "wasm"
+
+  if ($ninja -ne $True) {
+    # we need ninja for emscripten on windows
+    $ninja = $True
+    $arguments += " /p:Ninja=$ninja"
+  }
 }
 
 foreach ($config in $configuration) {
index aef95a0..d4b0ba8 100644 (file)
@@ -68,7 +68,7 @@ goto loop
 set __ExtraCmakeParams="-DCMAKE_INSTALL_PREFIX=%__CMakeBinDir%" "-DCLR_CMAKE_HOST_ARCH=%__Arch%" %__ExtraCmakeParams%
 
 if /i "%__UseEmcmake%" == "1" (
-    call !EMSDK_PATH!/emsdk_env.bat > nul 2>&1 && emcmake "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir%
+    call "!EMSDK_PATH!/emsdk_env.bat" > nul 2>&1 && emcmake "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir%
 ) else (
     "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir% 
 )
index c05214b..629ce20 100644 (file)
@@ -68,4 +68,4 @@ set "__VCBuildArch="
 
 :: Set CMakePath by evaluating the output from set-cmake-path.ps1.
 :: In case of a failure the output is "exit /b 1".
-for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy ByPass "%~dp0set-cmake-path.ps1"') do %%a
+for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy ByPass -File "%~dp0set-cmake-path.ps1"') do %%a
index 751187d..9f72a36 100644 (file)
@@ -29,7 +29,7 @@
     <Exec
       IgnoreExitCode="true"
       StandardOutputImportance="Low"
-      Command="$(_AsnXmlDiffCmd) @(AsnXml -> '$(_AsnIntermediatePath)%(filename).cs') @(AsnXml -> '%(Identity).cs')">
+      Command="$(_AsnXmlDiffCmd) @(AsnXml -> '&quot;$(_AsnIntermediatePath)%(filename).cs&quot;') @(AsnXml -> '&quot;%(Identity).cs&quot;')">
       <Output TaskParameter="ExitCode" ItemName="_AsnXmlDiffCode" />
     </Exec>
 
index 469b959..37a345e 100644 (file)
@@ -79,7 +79,7 @@
     </ItemGroup>
 
     <PropertyGroup>
-      <ILLinkArgs Condition="'@(_SuppressionsXmls)' != ''" >$(ILLinkArgs) --link-attributes @(_SuppressionsXmls->'%(FullPath)', ' --link-attributes ')</ILLinkArgs>
+      <ILLinkArgs Condition="'@(_SuppressionsXmls)' != ''" >$(ILLinkArgs) --link-attributes &quot;@(_SuppressionsXmls->'%(FullPath)', '&quot; --link-attributes &quot;')&quot;</ILLinkArgs>
     </PropertyGroup>
 
     <!-- When running from Desktop MSBuild, DOTNET_HOST_PATH is not set.
index d92fc0f..8a50e9a 100644 (file)
@@ -18,7 +18,7 @@
     <ExeExt Condition="'$(OS)' == 'Windows_NT'">.exe</ExeExt>
     <ScriptExt Condition="'$(OS)' == 'Windows_NT'">.cmd</ScriptExt>
     <ScriptExt Condition="'$(OS)' != 'Windows_NT'">.sh</ScriptExt>
-    <ExeExt Condition="'$(OS)' == 'Windows_NT'">.exe</ExeExt>
+    <EscapedQuoteW Condition="'$(OS)' == 'Windows_NT'">\&quot;</EscapedQuoteW>
     <CoreClrFileName Condition="'$(TargetsWindows)' == 'true'">coreclr.dll</CoreClrFileName>
     <CoreClrFileName Condition="'$(TargetsOSX)' == 'true'">libcoreclr.dylib</CoreClrFileName>
     <CoreClrFileName Condition="'$(TargetsMacCatalyst)' == 'true'">libcoreclr.dylib</CoreClrFileName>
     <PropertyGroup>
       <_MonoUseNinja Condition="'$(Ninja)' == 'true' or '$(_MonoFindNinjaExitCode)' == '0'">true</_MonoUseNinja>
     </PropertyGroup>
+
+    <Exec Condition="'$(TargetArchitecture)' == 'wasm' and '$(OS)' == 'Windows_NT'" Command="cmake --version" IgnoreExitCode="true" IgnoreStandardErrorWarningFormat="true" StandardOutputImportance="Low" >
+      <Output TaskParameter="ExitCode" PropertyName="_MonoFindCmakeExitCode"/>
+    </Exec>
+    <Error Condition="'$(TargetArchitecture)' == 'wasm' and '$(OS)' == 'Windows_NT' and '$(_MonoFindCmakeExitCode)' != '0'" Text="cmake tool is required to build wasm on windows" />
+    <Exec Condition="'$(TargetArchitecture)' == 'wasm' and '$(OS)' == 'Windows_NT'" Command="ninja --version" IgnoreExitCode="true" IgnoreStandardErrorWarningFormat="true" StandardOutputImportance="Low" >
+      <Output TaskParameter="ExitCode" PropertyName="_MonoFindNinjaExitCode"/>
+    </Exec>
+    <Error Condition="'$(TargetArchitecture)' == 'wasm' and '$(OS)' == 'Windows_NT' and '$(_MonoFindNinjaExitCode)' != '0'" Text="ninja tool is required to build wasm on windows" />
+
   </Target>
 
   <!-- Sets up emscripten if you don't have the EMSDK_PATH env variable set -->
   <Target Name="BuildMonoRuntime">
     <ItemGroup>
       <_MonoCMakeArgs Condition="'$(_MonoUseNinja)' == 'true'" Include="-G Ninja"/>
-      <_MonoCMakeArgs Include="-DCMAKE_INSTALL_PREFIX=$(MonoObjDir)out"/>
+      <_MonoCMakeArgs Include="-DCMAKE_INSTALL_PREFIX=&quot;$(MonoObjDir)out&quot;"/>
       <_MonoCMakeArgs Include="-DCMAKE_INSTALL_LIBDIR=lib"/>
       <_MonoCMakeArgs Include="-DCMAKE_BUILD_TYPE=$(Configuration)"/>
       <_MonoCMakeArgs Condition="'$(CMakeArgs)' != ''" Include="$(CMakeArgs)"/>
       <_MonoCMakeArgs Include="-DENABLE_LLVM_RUNTIME=1"/>
       <_MonoCFLAGS Include="-fexceptions"/>
       <_MonoCXXFLAGS Include="-fexceptions"/>
-      <_MonoCFLAGS Include="-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))"/>
+      <_MonoCFLAGS Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))$(EscapedQuoteW)"/>
     </ItemGroup>
     <!-- iOS/tvOS specific options -->
     <PropertyGroup Condition="'$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'">
     </ItemGroup>
 
     <PropertyGroup>
-      <_MonoCMakeConfigureCommand>cmake @(_MonoCMakeArgs, ' ') $(MonoCMakeExtraArgs) $(MonoProjectRoot.TrimEnd('\/'))</_MonoCMakeConfigureCommand>
+      <EMSDK_PATH>$([MSBuild]::EnsureTrailingSlash('$(EMSDK_PATH)'))</EMSDK_PATH>
+      <_MonoCMakeConfigureCommand>cmake @(_MonoCMakeArgs, ' ') $(MonoCMakeExtraArgs) &quot;$(MonoProjectRoot.TrimEnd('\/'))&quot;</_MonoCMakeConfigureCommand>
       <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(OS)' != 'Windows_NT'">bash -c 'source $(RepositoryEngineeringDir)native/init-compiler.sh $(Platform) $(MonoCCompiler) &amp;&amp; @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)'</_MonoCMakeConfigureCommand>
       <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(_MonoRunInitCompiler)' != 'false' and '$(OS)' == 'Windows_NT'">call &quot;$(RepositoryEngineeringDir)native\init-vs-env.cmd&quot; $(Platform) &amp;&amp; cd /D &quot;$(MonoObjDir)&quot; &amp;&amp; @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)</_MonoCMakeConfigureCommand>
       <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(_MonoRunInitCompiler)' == 'false'">$(_MonoCCOption) $(_MonoCXXOption) @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)</_MonoCMakeConfigureCommand>
       <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(OS)' != 'Windows_NT'">bash -c 'source $(EMSDK_PATH)/emsdk_env.sh 2>&amp;1 &amp;&amp; emcmake $(_MonoCMakeConfigureCommand)'</_MonoCMakeConfigureCommand>
-      <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(OS)' == 'Windows_NT'">call $(EMSDK_PATH)emsdk_env.bat &amp;&amp; emcmake $(_MonoCMakeConfigureCommand)</_MonoCMakeConfigureCommand>
+      <_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(OS)' == 'Windows_NT'">call &quot;$(EMSDK_PATH)emsdk_env.bat&quot; &amp;&amp; emcmake $(_MonoCMakeConfigureCommand)</_MonoCMakeConfigureCommand>
 
       <_MonoCMakeBuildCommand>cmake --build . --target install --config $(Configuration)</_MonoCMakeBuildCommand>
       <_MonoCMakeBuildCommand Condition="'$(MonoVerboseBuild)' == 'true'">$(_MonoCMakeBuildCommand) --verbose</_MonoCMakeBuildCommand>
index c7efa1f..06ef77b 100644 (file)
@@ -75,7 +75,7 @@ if(HAVE_SYS_ICU)
       ${pal_icushim_sources_base})
   addprefix(icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}")
   set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_DEFINITIONS OSX_ICU_LIBRARY_PATH="${OSX_ICU_LIBRARY_PATH}")
-  set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I${ICU_INCLUDEDIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/System.Globalization.Native/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/Common/ ${ICU_FLAGS}")
+  set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I\"${ICU_INCLUDEDIR}\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/System.Globalization.Native/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/Common/\" ${ICU_FLAGS}")
   if(TARGET_WIN32)
       set_source_files_properties(${icu_shim_sources} PROPERTIES LANGUAGE CXX)
   endif()
index 7c7a948..9e57b6c 100644 (file)
       <EmccFlags Condition="'$(WasmEnableES6)' == 'true'">$(EmccFlags) -s MODULARIZE=1 -s EXPORT_ES6=1</EmccFlags>
       <EmccConfigurationFlags Condition="'$(Configuration)' == 'Debug'">-g -Os -s ASSERTIONS=1 -DENABLE_NETCORE=1 -DDEBUG=1</EmccConfigurationFlags>
       <EmccConfigurationFlags Condition="'$(Configuration)' == 'Release'">-Oz --llvm-opts 2 -DENABLE_NETCORE=1</EmccConfigurationFlags>
-      <StripCmd>$(EMSDK_PATH)/upstream/bin/wasm-opt --strip-dwarf $(NativeBinDir)/dotnet.wasm -o $(NativeBinDir)/dotnet.wasm</StripCmd>
+      <StripCmd>&quot;$(EMSDK_PATH)/upstream/bin/wasm-opt&quot; --strip-dwarf &quot;$(NativeBinDir)/dotnet.wasm&quot; -o &quot;$(NativeBinDir)/dotnet.wasm&quot;</StripCmd>
       <WasmObjDir>$(ArtifactsObjDir)wasm</WasmObjDir>
       <WasmVersionFile>$(WasmObjDir)\emcc-version.txt</WasmVersionFile>
       <MonoIncludeDir>$(MonoArtifactsPath)include/mono-2.0</MonoIncludeDir>
       <ICULibFiles Include="$(ICULibDir)/*.dat" />
     </ItemGroup>
 
-    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) -Oz -I$(MonoIncludeDir) runtime/corebindings.c -c -o $(MonoObjDir)corebindings.o"
+    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) -Oz -I&quot;$(MonoIncludeDir)&quot; runtime/corebindings.c -c -o &quot;$(MonoObjDir)corebindings.o&quot;"
           EmSdkPath="$(EMSDK_PATH)"
           IgnoreStandardErrorWarningFormat="true" />
 
-    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) -Oz -DCORE_BINDINGS -I$(MonoObjDir) -I$(MonoIncludeDir) runtime/driver.c -c -o $(MonoObjDir)driver.o"
+    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) -Oz -DCORE_BINDINGS -I&quot;$(MonoObjDir.TrimEnd('\/'))&quot; -I&quot;$(MonoIncludeDir)&quot; runtime/driver.c -c -o &quot;$(MonoObjDir)driver.o&quot;"
           EmSdkPath="$(EMSDK_PATH)"
           IgnoreStandardErrorWarningFormat="true" />
 
           DestinationFolder="$(MonoObjDir)"
           SkipUnchangedFiles="true" />
 
-    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) -Oz -DGEN_PINVOKE=1 -I$(MonoObjDir) -I$(MonoIncludeDir) runtime/pinvoke.c -c -o $(MonoObjDir)pinvoke.o"
+    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) -Oz -DGEN_PINVOKE=1 -I&quot;$(MonoObjDir.TrimEnd('\/'))&quot; -I&quot;$(MonoIncludeDir)&quot; runtime/pinvoke.c -c -o &quot;$(MonoObjDir)pinvoke.o&quot;"
           EmSdkPath="$(EMSDK_PATH)"
           IgnoreStandardErrorWarningFormat="true" />
 
-    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js --js-library $(SystemNativeDir)\pal_random.js $(MonoObjDir)/driver.o $(MonoObjDir)/pinvoke.o $(MonoObjDir)/corebindings.o @(MonoLibFiles->'%(FullPath)', ' ') -o $(NativeBinDir)/dotnet.js &amp;&amp; $(StripCmd)"
+    <RunWithEmSdkEnv Command="$(EmccCmd) $(EmccFlags) $(EmccConfigurationFlags) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js --js-library &quot;$(SystemNativeDir)\pal_random.js&quot; &quot;$(MonoObjDir)/driver.o&quot; &quot;$(MonoObjDir)/pinvoke.o&quot; &quot;$(MonoObjDir)/corebindings.o&quot; &quot;@(MonoLibFiles->'%(FullPath)', '&quot; &quot;')&quot; -o &quot;$(NativeBinDir)/dotnet.js&quot; &amp;&amp; $(StripCmd)"
           EmSdkPath="$(EMSDK_PATH)"
           IgnoreStandardErrorWarningFormat="true" />