@@ -284,32 +284,34 @@ def vs_filewhere(installation_path, platform, file):
284
284
# Detect which CMake generator to use when building on Windows
285
285
if '--mingw' in sys .argv :
286
286
CMAKE_GENERATOR = 'MinGW Makefiles'
287
+ elif '--vs2022' in sys .argv :
288
+ CMAKE_GENERATOR = 'Visual Studio 17'
289
+ elif '--vs2019' in sys .argv :
290
+ CMAKE_GENERATOR = 'Visual Studio 16'
287
291
elif '--vs2017' in sys .argv :
288
292
CMAKE_GENERATOR = 'Visual Studio 15'
289
- elif '--vs2019' in sys .argv :
293
+ elif len (vswhere (17 )) > 0 :
294
+ CMAKE_GENERATOR = 'Visual Studio 17'
295
+ elif len (vswhere (16 )) > 0 :
290
296
CMAKE_GENERATOR = 'Visual Studio 16'
297
+ elif len (vswhere (15 )) > 0 :
298
+ # VS2017 has an LLVM build issue, see
299
+ # https://github.com/kripken/emscripten-fastcomp/issues/185
300
+ CMAKE_GENERATOR = 'Visual Studio 15'
301
+ elif which ('mingw32-make' ) is not None and which ('g++' ) is not None :
302
+ CMAKE_GENERATOR = 'MinGW Makefiles'
291
303
else :
292
- vs2019_exists = len (vswhere (16 )) > 0
293
- vs2017_exists = len (vswhere (15 )) > 0
294
- mingw_exists = which ('mingw32-make' ) is not None and which ('g++' ) is not None
295
- if vs2019_exists :
296
- CMAKE_GENERATOR = 'Visual Studio 16'
297
- elif vs2017_exists :
298
- # VS2017 has an LLVM build issue, see
299
- # https://github.com/kripken/emscripten-fastcomp/issues/185
300
- CMAKE_GENERATOR = 'Visual Studio 15'
301
- elif mingw_exists :
302
- CMAKE_GENERATOR = 'MinGW Makefiles'
303
- else :
304
- # No detected generator
305
- CMAKE_GENERATOR = ''
304
+ # No detected generator
305
+ CMAKE_GENERATOR = ''
306
306
307
307
308
- sys .argv = [a for a in sys .argv if a not in ('--mingw' , '--vs2017' , '--vs2019' )]
308
+ sys .argv = [a for a in sys .argv if a not in ('--mingw' , '--vs2017' , '--vs2019' , '--vs2022' )]
309
309
310
310
311
311
# Computes a suitable path prefix to use when building with a given generator.
312
312
def cmake_generator_prefix ():
313
+ if CMAKE_GENERATOR == 'Visual Studio 17' :
314
+ return '_vs2022'
313
315
if CMAKE_GENERATOR == 'Visual Studio 16' :
314
316
return '_vs2019'
315
317
if CMAKE_GENERATOR == 'Visual Studio 15' :
@@ -861,14 +863,7 @@ def decide_cmake_build_type(tool):
861
863
862
864
# The root directory of the build.
863
865
def llvm_build_dir (tool ):
864
- generator_suffix = ''
865
- if CMAKE_GENERATOR == 'Visual Studio 15' :
866
- generator_suffix = '_vs2017'
867
- elif CMAKE_GENERATOR == 'Visual Studio 16' :
868
- generator_suffix = '_vs2019'
869
- elif CMAKE_GENERATOR == 'MinGW Makefiles' :
870
- generator_suffix = '_mingw'
871
-
866
+ generator_suffix = cmake_generator_prefix ()
872
867
bitness_suffix = '_32' if tool .bitness == 32 else '_64'
873
868
874
869
if hasattr (tool , 'git_branch' ):
@@ -916,112 +911,38 @@ def build_env(generator):
916
911
# See https://groups.google.com/forum/#!topic/emscripten-discuss/5Or6QIzkqf0
917
912
if MACOS :
918
913
build_env ['CXXFLAGS' ] = ((build_env ['CXXFLAGS' ] + ' ' ) if hasattr (build_env , 'CXXFLAGS' ) else '' ) + '-stdlib=libc++'
919
- elif 'Visual Studio 15' in generator or 'Visual Studio 16' in generator :
920
- if 'Visual Studio 16' in generator :
921
- path = vswhere (16 )
922
- else :
923
- path = vswhere (15 )
924
-
925
- # Configuring CMake for Visual Studio needs and env. var VCTargetsPath to be present.
926
- # How this is supposed to work is unfortunately very undocumented. See
927
- # https://discourse.cmake.org/t/cmake-failed-to-get-the-value-of-vctargetspath-with-vs2019-16-7/1839/16
928
- # for some conversation. Try a couple of common paths if one of them would work.
929
- # In the future as new versions of VS come out, we likely need to add new paths into this list.
930
- if 'VCTargetsPath' not in build_env :
931
- vctargets_paths = [
932
- os .path .join (path , 'MSBuild\\ Microsoft\\ VC\\ v160\\ ' ),
933
- os .path .join (path , 'Common7\\ IDE\\ VC\\ VCTargets' )
934
- ]
935
- for p in vctargets_paths :
936
- if os .path .isfile (os .path .join (p , 'Microsoft.Cpp.Default.props' )):
937
- debug_print ('Set env. var VCTargetsPath=' + p + ' for CMake.' )
938
- build_env ['VCTargetsPath' ] = p
939
- break
940
- else :
941
- debug_print ('Searched path ' + p + ' as candidate for VCTargetsPath, not working.' )
942
-
943
- if 'VCTargetsPath' not in build_env :
944
- errlog ('Unable to locate Visual Studio compiler installation for generator "' + generator + '"!' )
945
- errlog ('Either rerun installation in Visual Studio Command Prompt, or locate directory to Microsoft.Cpp.Default.props manually' )
946
- sys .exit (1 )
947
-
948
- # CMake and VS2017 cl.exe needs to have mspdb140.dll et al. in its PATH.
949
- vc_bin_paths = [vs_filewhere (path , 'amd64' , 'cl.exe' ),
950
- vs_filewhere (path , 'x86' , 'cl.exe' )]
951
- for path in vc_bin_paths :
952
- if os .path .isdir (path ):
953
- build_env ['PATH' ] = build_env ['PATH' ] + ';' + path
954
-
914
+ if WINDOWS :
915
+ # MSBuild.exe has an internal mechanism to avoid N^2 oversubscription of threads in its two-tier build model, see
916
+ # https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
917
+ build_env ['UseMultiToolTask' ] = 'true'
918
+ build_env ['EnforceProcessCountAcrossBuilds' ] = 'true'
955
919
return build_env
956
920
957
921
958
- def get_generator_for_sln_file (sln_file ):
959
- contents = open (sln_file , 'r' ).read ()
960
- if '# Visual Studio 16' in contents or '# Visual Studio Version 16' in contents : # VS2019
961
- return 'Visual Studio 16'
962
- if '# Visual Studio 15' in contents : # VS2017
963
- return 'Visual Studio 15'
964
- raise Exception ('Unknown generator used to build solution file ' + sln_file )
965
-
966
-
967
- def find_msbuild (sln_file ):
968
- # The following logic attempts to find a Visual Studio version specific
969
- # MSBuild.exe from a list of known locations.
970
- generator = get_generator_for_sln_file (sln_file )
971
- debug_print ('find_msbuild looking for generator ' + str (generator ))
972
- if generator == 'Visual Studio 16' : # VS2019
973
- path = vswhere (16 )
974
- search_paths = [os .path .join (path , 'MSBuild/Current/Bin' ),
975
- os .path .join (path , 'MSBuild/15.0/Bin/amd64' ),
976
- os .path .join (path , 'MSBuild/15.0/Bin' )]
977
- elif generator == 'Visual Studio 15' : # VS2017
978
- path = vswhere (15 )
979
- search_paths = [os .path .join (path , 'MSBuild/15.0/Bin/amd64' ),
980
- os .path .join (path , 'MSBuild/15.0/Bin' )]
981
- else :
982
- raise Exception ('Unknown generator!' )
983
-
984
- for path in search_paths :
985
- p = os .path .join (path , 'MSBuild.exe' )
986
- debug_print ('Searching for MSBuild.exe: ' + p )
987
- if os .path .isfile (p ):
988
- return p
989
- debug_print ('MSBuild.exe in PATH? ' + str (which ('MSBuild.exe' )))
990
- # Last fallback, try any MSBuild from PATH (might not be compatible, but best effort)
991
- return which ('MSBuild.exe' )
992
-
993
-
994
922
def make_build (build_root , build_type , build_target_platform = 'x64' ):
995
923
debug_print ('make_build(build_root=' + build_root + ', build_type=' + build_type + ', build_target_platform=' + build_target_platform + ')' )
996
924
if CPU_CORES > 1 :
997
925
print ('Performing a parallel build with ' + str (CPU_CORES ) + ' cores.' )
998
926
else :
999
927
print ('Performing a singlethreaded build.' )
1000
928
1001
- generator_to_use = CMAKE_GENERATOR
1002
-
1003
- if WINDOWS :
1004
- if 'Visual Studio' in CMAKE_GENERATOR :
1005
- solution_name = str (subprocess .check_output (['dir' , '/b' , '*.sln' ], shell = True , cwd = build_root ).decode ('utf-8' ).strip ())
1006
- generator_to_use = get_generator_for_sln_file (os .path .join (build_root , solution_name ))
1007
- # Disabled for now: Don't pass /maxcpucount argument to msbuild, since it
1008
- # looks like when building, msbuild already automatically spawns the full
1009
- # amount of logical cores the system has, and passing the number of
1010
- # logical cores here has been observed to give a quadratic N*N explosion
1011
- # on the number of spawned processes (e.g. on a Core i7 5960X with 16
1012
- # logical cores, it would spawn 16*16=256 cl.exe processes, which would
1013
- # start crashing when running out of system memory)
1014
- # make = [find_msbuild(os.path.join(build_root, solution_name)), '/maxcpucount:' + str(CPU_CORES), '/t:Build', '/p:Configuration=' + build_type, '/nologo', '/verbosity:minimal', solution_name]
1015
- make = [find_msbuild (os .path .join (build_root , solution_name )), '/t:Build' , '/p:Configuration=' + build_type , '/p:Platform=' + build_target_platform , '/nologo' , '/verbosity:minimal' , solution_name ]
1016
- else :
1017
- make = ['mingw32-make' , '-j' + str (CPU_CORES )]
929
+ make = ['cmake' , '--build' , '.' , '--config' , build_type ]
930
+ if 'Visual Studio' in CMAKE_GENERATOR :
931
+ # Visual Studio historically has had a two-tier problem in its build system design. A single MSBuild.exe instance only governs
932
+ # the build of a single project (.exe/.lib/.dll) in a solution. Passing the -j parameter above will only enable multiple MSBuild.exe
933
+ # instances to be spawned to build multiple projects in parallel, but each MSBuild.exe is still singlethreaded.
934
+ # To enable each MSBuild.exe instance to also compile several .cpp files in parallel inside a single project, pass the extra
935
+ # MSBuild.exe specific "Multi-ToolTask" (MTT) setting /p:CL_MPCount. This enables each MSBuild.exe to parallelize builds wide.
936
+ # This requires CMake 3.12 or newer.
937
+ make += ['-j' , str (CPU_CORES ), '--' , '/p:CL_MPCount=' + str (CPU_CORES )]
1018
938
else :
1019
- make = ['cmake' , '--build' , '.' , '--' , '-j' + str (CPU_CORES )]
939
+ # Pass -j to native make, CMake might not support -j option.
940
+ make += ['--' , '-j' , str (CPU_CORES )]
1020
941
1021
942
# Build
1022
943
try :
1023
944
print ('Running build: ' + str (make ))
1024
- ret = subprocess .check_call (make , cwd = build_root , env = build_env (generator_to_use ))
945
+ ret = subprocess .check_call (make , cwd = build_root , env = build_env (CMAKE_GENERATOR ))
1025
946
if ret != 0 :
1026
947
errlog ('Build failed with exit code ' + ret + '!' )
1027
948
errlog ('Working directory: ' + build_root )
@@ -1108,6 +1029,21 @@ def xcode_sdk_version():
1108
1029
return subprocess .checkplatform .mac_ver ()[0 ].split ('.' )
1109
1030
1110
1031
1032
+ def get_generator_and_config_args (tool ):
1033
+ args = []
1034
+ cmake_generator = CMAKE_GENERATOR
1035
+ if 'Visual Studio 16' in CMAKE_GENERATOR or 'Visual Studio 17' in CMAKE_GENERATOR : # VS2019 or VS2022
1036
+ # With Visual Studio 16 2019, CMake changed the way they specify target arch.
1037
+ # Instead of appending it into the CMake generator line, it is specified
1038
+ # with a -A arch parameter.
1039
+ args += ['-A' , 'x64' if tool .bitness == 64 else 'x86' ]
1040
+ args += ['-Thost=x64' ]
1041
+ elif 'Visual Studio' in CMAKE_GENERATOR and tool .bitness == 64 :
1042
+ cmake_generator += ' Win64'
1043
+ args += ['-Thost=x64' ]
1044
+ return (cmake_generator , args )
1045
+
1046
+
1111
1047
def build_llvm (tool ):
1112
1048
debug_print ('build_llvm(' + str (tool ) + ')' )
1113
1049
llvm_root = tool .installation_path ()
@@ -1150,16 +1086,7 @@ def build_llvm(tool):
1150
1086
# (there instead of $(Configuration), one would need ${CMAKE_BUILD_TYPE} ?)
1151
1087
# It looks like compiler-rt is not compatible to build on Windows?
1152
1088
args += ['-DLLVM_ENABLE_PROJECTS=clang;lld' ]
1153
- cmake_generator = CMAKE_GENERATOR
1154
- if 'Visual Studio 16' in CMAKE_GENERATOR : # VS2019
1155
- # With Visual Studio 16 2019, CMake changed the way they specify target arch.
1156
- # Instead of appending it into the CMake generator line, it is specified
1157
- # with a -A arch parameter.
1158
- args += ['-A' , 'x64' if tool .bitness == 64 else 'x86' ]
1159
- args += ['-Thost=x64' ]
1160
- elif 'Visual Studio' in CMAKE_GENERATOR and tool .bitness == 64 :
1161
- cmake_generator += ' Win64'
1162
- args += ['-Thost=x64' ]
1089
+ cmake_generator , args = get_generator_and_config_args (tool )
1163
1090
1164
1091
if os .getenv ('LLVM_CMAKE_ARGS' ):
1165
1092
extra_args = os .environ ['LLVM_CMAKE_ARGS' ].split (',' )
@@ -1190,17 +1117,7 @@ def build_ninja(tool):
1190
1117
build_type = decide_cmake_build_type (tool )
1191
1118
1192
1119
# Configure
1193
- cmake_generator = CMAKE_GENERATOR
1194
- args = []
1195
- if 'Visual Studio 16' in CMAKE_GENERATOR : # VS2019
1196
- # With Visual Studio 16 2019, CMake changed the way they specify target arch.
1197
- # Instead of appending it into the CMake generator line, it is specified
1198
- # with a -A arch parameter.
1199
- args += ['-A' , 'x64' if tool .bitness == 64 else 'x86' ]
1200
- args += ['-Thost=x64' ]
1201
- elif 'Visual Studio' in CMAKE_GENERATOR and tool .bitness == 64 :
1202
- cmake_generator += ' Win64'
1203
- args += ['-Thost=x64' ]
1120
+ cmake_generator , args = get_generator_and_config_args (tool )
1204
1121
1205
1122
cmakelists_dir = os .path .join (src_root )
1206
1123
success = cmake_configure (cmake_generator , build_root , cmakelists_dir , build_type , args )
@@ -1239,17 +1156,8 @@ def build_ccache(tool):
1239
1156
build_type = decide_cmake_build_type (tool )
1240
1157
1241
1158
# Configure
1242
- cmake_generator = CMAKE_GENERATOR
1243
- args = ['-DZSTD_FROM_INTERNET=ON' ]
1244
- if 'Visual Studio 16' in CMAKE_GENERATOR : # VS2019
1245
- # With Visual Studio 16 2019, CMake changed the way they specify target arch.
1246
- # Instead of appending it into the CMake generator line, it is specified
1247
- # with a -A arch parameter.
1248
- args += ['-A' , 'x64' if tool .bitness == 64 else 'x86' ]
1249
- args += ['-Thost=x64' ]
1250
- elif 'Visual Studio' in CMAKE_GENERATOR and tool .bitness == 64 :
1251
- cmake_generator += ' Win64'
1252
- args += ['-Thost=x64' ]
1159
+ cmake_generator , args = get_generator_and_config_args (tool )
1160
+ args += ['-DZSTD_FROM_INTERNET=ON' ]
1253
1161
1254
1162
cmakelists_dir = os .path .join (src_root )
1255
1163
success = cmake_configure (cmake_generator , build_root , cmakelists_dir , build_type , args )
@@ -1409,17 +1317,8 @@ def emscripten_post_install(tool):
1409
1317
build_root = optimizer_build_root (tool )
1410
1318
build_type = decide_cmake_build_type (tool )
1411
1319
1412
- args = []
1413
-
1414
1320
# Configure
1415
- cmake_generator = CMAKE_GENERATOR
1416
- if 'Visual Studio 16' in CMAKE_GENERATOR : # VS2019
1417
- # With Visual Studio 16 2019, CMake changed the way they specify target arch.
1418
- # Instead of appending it into the CMake generator line, it is specified
1419
- # with a -A arch parameter.
1420
- args += ['-A' , 'x64' if tool .bitness == 64 else 'x86' ]
1421
- elif 'Visual Studio' in CMAKE_GENERATOR and tool .bitness == 64 :
1422
- cmake_generator += ' Win64'
1321
+ cmake_generator , args = get_generator_and_config_args (tool )
1423
1322
1424
1323
success = cmake_configure (cmake_generator , build_root , src_root , build_type , args )
1425
1324
if not success :
@@ -1464,16 +1363,8 @@ def build_binaryen_tool(tool):
1464
1363
build_type = decide_cmake_build_type (tool )
1465
1364
1466
1365
# Configure
1467
- args = ['-DENABLE_WERROR=0' ] # -Werror is not useful for end users
1468
-
1469
- cmake_generator = CMAKE_GENERATOR
1470
- if 'Visual Studio 16' in CMAKE_GENERATOR : # VS2019
1471
- # With Visual Studio 16 2019, CMake changed the way they specify target arch.
1472
- # Instead of appending it into the CMake generator line, it is specified
1473
- # with a -A arch parameter.
1474
- args += ['-A' , 'x64' if tool .bitness == 64 else 'x86' ]
1475
- elif 'Visual Studio' in CMAKE_GENERATOR and tool .bitness == 64 :
1476
- cmake_generator += ' Win64'
1366
+ cmake_generator , args = get_generator_and_config_args (tool )
1367
+ args += ['-DENABLE_WERROR=0' ] # -Werror is not useful for end users
1477
1368
1478
1369
if 'Visual Studio' in CMAKE_GENERATOR :
1479
1370
if BUILD_FOR_TESTING :
@@ -2794,7 +2685,7 @@ def main(args):
2794
2685
purposes. Default: Enabled
2795
2686
--disable-assertions: Forces assertions off during the build.
2796
2687
2797
- --vs2017/--vs2019: If building from source, overrides to build
2688
+ --vs2017/--vs2019/--vs2022 : If building from source, overrides to build
2798
2689
using the specified compiler. When installing
2799
2690
precompiled packages, this has no effect.
2800
2691
Note: The same compiler specifier must be
@@ -2817,7 +2708,7 @@ def main(args):
2817
2708
2818
2709
if WINDOWS :
2819
2710
print ('''
2820
- emsdk activate [--permanent] [--system] [--build=type] [--vs2017/--vs2019] <tool/sdk>
2711
+ emsdk activate [--permanent] [--system] [--build=type] [--vs2017/--vs2019/--vs2022 ] <tool/sdk>
2821
2712
2822
2713
- Activates the given tool or SDK in the
2823
2714
environment of the current shell.
@@ -2831,8 +2722,8 @@ def main(args):
2831
2722
(uses Machine environment variables).
2832
2723
2833
2724
- If a custom compiler version was used to override
2834
- the compiler to use, pass the same --vs2017/--vs2019 parameter
2835
- here to choose which version to activate.
2725
+ the compiler to use, pass the same --vs2017/--vs2019/--vs2022
2726
+ parameter here to choose which version to activate.
2836
2727
2837
2728
emcmdprompt.bat - Spawns a new command prompt window with the
2838
2729
Emscripten environment active.''' )
0 commit comments