@@ -284,32 +284,34 @@ def vs_filewhere(installation_path, platform, file):
284284 # Detect which CMake generator to use when building on Windows
285285 if '--mingw' in sys .argv :
286286 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'
287291 elif '--vs2017' in sys .argv :
288292 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 :
290296 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'
291303 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 = ''
306306
307307
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' )]
309309
310310
311311# Computes a suitable path prefix to use when building with a given generator.
312312def cmake_generator_prefix ():
313+ if CMAKE_GENERATOR == 'Visual Studio 17' :
314+ return '_vs2022'
313315 if CMAKE_GENERATOR == 'Visual Studio 16' :
314316 return '_vs2019'
315317 if CMAKE_GENERATOR == 'Visual Studio 15' :
@@ -861,14 +863,7 @@ def decide_cmake_build_type(tool):
861863
862864# The root directory of the build.
863865def 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 ()
872867 bitness_suffix = '_32' if tool .bitness == 32 else '_64'
873868
874869 if hasattr (tool , 'git_branch' ):
@@ -916,112 +911,38 @@ def build_env(generator):
916911 # See https://groups.google.com/forum/#!topic/emscripten-discuss/5Or6QIzkqf0
917912 if MACOS :
918913 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'
955919 return build_env
956920
957921
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-
994922def make_build (build_root , build_type , build_target_platform = 'x64' ):
995923 debug_print ('make_build(build_root=' + build_root + ', build_type=' + build_type + ', build_target_platform=' + build_target_platform + ')' )
996924 if CPU_CORES > 1 :
997925 print ('Performing a parallel build with ' + str (CPU_CORES ) + ' cores.' )
998926 else :
999927 print ('Performing a singlethreaded build.' )
1000928
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 )]
1018938 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 )]
1020941
1021942 # Build
1022943 try :
1023944 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 ))
1025946 if ret != 0 :
1026947 errlog ('Build failed with exit code ' + ret + '!' )
1027948 errlog ('Working directory: ' + build_root )
@@ -1108,6 +1029,21 @@ def xcode_sdk_version():
11081029 return subprocess .checkplatform .mac_ver ()[0 ].split ('.' )
11091030
11101031
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+
11111047def build_llvm (tool ):
11121048 debug_print ('build_llvm(' + str (tool ) + ')' )
11131049 llvm_root = tool .installation_path ()
@@ -1150,16 +1086,7 @@ def build_llvm(tool):
11501086 # (there instead of $(Configuration), one would need ${CMAKE_BUILD_TYPE} ?)
11511087 # It looks like compiler-rt is not compatible to build on Windows?
11521088 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 )
11631090
11641091 if os .getenv ('LLVM_CMAKE_ARGS' ):
11651092 extra_args = os .environ ['LLVM_CMAKE_ARGS' ].split (',' )
@@ -1190,17 +1117,7 @@ def build_ninja(tool):
11901117 build_type = decide_cmake_build_type (tool )
11911118
11921119 # 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 )
12041121
12051122 cmakelists_dir = os .path .join (src_root )
12061123 success = cmake_configure (cmake_generator , build_root , cmakelists_dir , build_type , args )
@@ -1239,17 +1156,8 @@ def build_ccache(tool):
12391156 build_type = decide_cmake_build_type (tool )
12401157
12411158 # 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' ]
12531161
12541162 cmakelists_dir = os .path .join (src_root )
12551163 success = cmake_configure (cmake_generator , build_root , cmakelists_dir , build_type , args )
@@ -1409,17 +1317,8 @@ def emscripten_post_install(tool):
14091317 build_root = optimizer_build_root (tool )
14101318 build_type = decide_cmake_build_type (tool )
14111319
1412- args = []
1413-
14141320 # 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 )
14231322
14241323 success = cmake_configure (cmake_generator , build_root , src_root , build_type , args )
14251324 if not success :
@@ -1464,16 +1363,8 @@ def build_binaryen_tool(tool):
14641363 build_type = decide_cmake_build_type (tool )
14651364
14661365 # 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
14771368
14781369 if 'Visual Studio' in CMAKE_GENERATOR :
14791370 if BUILD_FOR_TESTING :
@@ -2794,7 +2685,7 @@ def main(args):
27942685 purposes. Default: Enabled
27952686 --disable-assertions: Forces assertions off during the build.
27962687
2797- --vs2017/--vs2019: If building from source, overrides to build
2688+ --vs2017/--vs2019/--vs2022 : If building from source, overrides to build
27982689 using the specified compiler. When installing
27992690 precompiled packages, this has no effect.
28002691 Note: The same compiler specifier must be
@@ -2817,7 +2708,7 @@ def main(args):
28172708
28182709 if WINDOWS :
28192710 print ('''
2820- emsdk activate [--permanent] [--system] [--build=type] [--vs2017/--vs2019] <tool/sdk>
2711+ emsdk activate [--permanent] [--system] [--build=type] [--vs2017/--vs2019/--vs2022 ] <tool/sdk>
28212712
28222713 - Activates the given tool or SDK in the
28232714 environment of the current shell.
@@ -2831,8 +2722,8 @@ def main(args):
28312722 (uses Machine environment variables).
28322723
28332724 - 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.
28362727
28372728 emcmdprompt.bat - Spawns a new command prompt window with the
28382729 Emscripten environment active.''' )
0 commit comments