Log warnings to stderr (#585)
Its particularly important during `construct_env` where stdout is directly interpreted by the shell. See: #385
This commit is contained in:
119
emsdk.py
119
emsdk.py
@@ -51,6 +51,11 @@ WINDOWS = False
|
||||
if os.name == 'nt' or (os.getenv('SYSTEMROOT') is not None and 'windows' in os.getenv('SYSTEMROOT').lower()) or (os.getenv('COMSPEC') is not None and 'windows' in os.getenv('COMSPEC').lower()):
|
||||
WINDOWS = True
|
||||
|
||||
|
||||
def errlog(msg):
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
|
||||
MINGW = False
|
||||
MSYS = False
|
||||
if os.getenv('MSYSTEM'):
|
||||
@@ -62,7 +67,7 @@ if os.getenv('MSYSTEM'):
|
||||
MINGW = True
|
||||
if os.getenv('MSYSTEM') != 'MSYS' and os.getenv('MSYSTEM') != 'MINGW64':
|
||||
# https://stackoverflow.com/questions/37460073/msys-vs-mingw-internal-environment-variables
|
||||
print('Warning: MSYSTEM environment variable is present, and is set to "' + os.getenv('MSYSTEM') + '". This shell has not been tested with emsdk and may not work.')
|
||||
errlog('Warning: MSYSTEM environment variable is present, and is set to "' + os.getenv('MSYSTEM') + '". This shell has not been tested with emsdk and may not work.')
|
||||
|
||||
MACOS = False
|
||||
if platform.mac_ver()[0] != '':
|
||||
@@ -107,8 +112,8 @@ elif machine.startswith('aarch64') or machine.lower().startswith('arm64'):
|
||||
elif platform.machine().startswith('arm'):
|
||||
ARCH = 'arm'
|
||||
else:
|
||||
print("Warning: unknown machine architecture " + machine)
|
||||
print()
|
||||
errlog("Warning: unknown machine architecture " + machine)
|
||||
errlog()
|
||||
|
||||
# Don't saturate all cores to not steal the whole system, but be aggressive.
|
||||
CPU_CORES = int(os.environ.get('EMSDK_NUM_CORES', max(multiprocessing.cpu_count() - 1, 1)))
|
||||
@@ -316,8 +321,8 @@ def win_set_environment_variable_direct(key, value, system=True):
|
||||
# 'Access is denied.'
|
||||
if e.args[0] == 5:
|
||||
exit_with_error('Error! Failed to set the environment variable \'' + key + '\'! Setting environment variables permanently requires administrator access. Please rerun this command with administrative privileges. This can be done for example by holding down the Ctrl and Shift keys while opening a command prompt in start menu.')
|
||||
print('Failed to write environment variable ' + key + ':', file=sys.stderr)
|
||||
print(str(e), file=sys.stderr)
|
||||
errlog('Failed to write environment variable ' + key + ':')
|
||||
errlog(str(e))
|
||||
win32api.RegCloseKey(folder)
|
||||
os.environ['PATH'] = prev_path
|
||||
return None
|
||||
@@ -353,8 +358,8 @@ def win_get_environment_variable(key, system=True):
|
||||
except Exception as e:
|
||||
if e.args[0] != 2:
|
||||
# 'The system cannot find the file specified.'
|
||||
print('Failed to read environment variable ' + key + ':', file=sys.stderr)
|
||||
print(str(e), file=sys.stderr)
|
||||
errlog('Failed to read environment variable ' + key + ':')
|
||||
errlog(str(e))
|
||||
try:
|
||||
win32api.RegCloseKey(folder)
|
||||
except Exception:
|
||||
@@ -405,16 +410,16 @@ def win_set_environment_variable(key, value, system=True):
|
||||
# Escape % signs so that we don't expand references to environment variables.
|
||||
value = value.replace('%', '^%')
|
||||
if len(value) >= 1024:
|
||||
exit_with_error('ERROR! The new environment variable ' + key + ' is more than 1024 characters long! A value this long cannot be set via command line: please add the environment variable specified above to system environment manually via Control Panel.', file=sys.stderr)
|
||||
exit_with_error('ERROR! The new environment variable ' + key + ' is more than 1024 characters long! A value this long cannot be set via command line: please add the environment variable specified above to system environment manually via Control Panel.')
|
||||
cmd = ['SETX', key, value]
|
||||
debug_print(str(cmd))
|
||||
retcode = subprocess.call(cmd, stdout=subprocess.PIPE)
|
||||
if retcode != 0:
|
||||
print('ERROR! Failed to set environment variable ' + key + '=' + value + '. You may need to set it manually.', file=sys.stderr)
|
||||
errlog('ERROR! Failed to set environment variable ' + key + '=' + value + '. You may need to set it manually.')
|
||||
except Exception as e:
|
||||
print('ERROR! Failed to set environment variable ' + key + '=' + value + ':', file=sys.stderr)
|
||||
print(str(e), file=sys.stderr)
|
||||
print('You may need to set it manually.', file=sys.stderr)
|
||||
errlog('ERROR! Failed to set environment variable ' + key + '=' + value + ':')
|
||||
errlog(str(e))
|
||||
errlog('You may need to set it manually.')
|
||||
|
||||
|
||||
def win_delete_environment_variable(key, system=True):
|
||||
@@ -512,7 +517,7 @@ def fix_potentially_long_windows_pathname(pathname):
|
||||
return pathname
|
||||
# Test if emsdk calls fix_potentially_long_windows_pathname() with long relative paths (which is problematic)
|
||||
if not os.path.isabs(pathname) and len(pathname) > 200:
|
||||
print('Warning: Seeing a relative path "' + pathname + '" which is dangerously long for being referenced as a short Windows path name. Refactor emsdk to be able to handle this!')
|
||||
errlog('Warning: Seeing a relative path "' + pathname + '" which is dangerously long for being referenced as a short Windows path name. Refactor emsdk to be able to handle this!')
|
||||
if pathname.startswith('\\\\?\\'):
|
||||
return pathname
|
||||
pathname = os.path.normpath(pathname.replace('/', '\\'))
|
||||
@@ -701,9 +706,9 @@ def download_file(url, dstpath, download_even_if_exists=False, filename_prefix='
|
||||
print(']')
|
||||
sys.stdout.flush()
|
||||
except Exception as e:
|
||||
print("Error: Downloading URL '" + url + "': " + str(e))
|
||||
errlog("Error: Downloading URL '" + url + "': " + str(e))
|
||||
if "SSL: CERTIFICATE_VERIFY_FAILED" in str(e) or "urlopen error unknown url type: https" in str(e):
|
||||
print("Warning: Possibly SSL/TLS issue. Update or install Python SSL root certificates (2048-bit or greater) supplied in Python folder or https://pypi.org/project/certifi/ and try again.")
|
||||
errlog("Warning: Possibly SSL/TLS issue. Update or install Python SSL root certificates (2048-bit or greater) supplied in Python folder or https://pypi.org/project/certifi/ and try again.")
|
||||
rmfile(file_name)
|
||||
return None
|
||||
except KeyboardInterrupt:
|
||||
@@ -967,13 +972,13 @@ def make_build(build_root, build_type, build_target_platform='x64'):
|
||||
print('Running build: ' + str(make))
|
||||
ret = subprocess.check_call(make, cwd=build_root, env=build_env(generator_to_use))
|
||||
if ret != 0:
|
||||
print('Build failed with exit code ' + ret + '!', file=sys.stderr)
|
||||
print('Working directory: ' + build_root, file=sys.stderr)
|
||||
errlog('Build failed with exit code ' + ret + '!')
|
||||
errlog('Working directory: ' + build_root)
|
||||
return False
|
||||
except Exception as e:
|
||||
print('Build failed due to exception!', file=sys.stderr)
|
||||
print('Working directory: ' + build_root, file=sys.stderr)
|
||||
print(str(e), file=sys.stderr)
|
||||
errlog('Build failed due to exception!')
|
||||
errlog('Working directory: ' + build_root)
|
||||
errlog(str(e))
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -1004,25 +1009,25 @@ def cmake_configure(generator, build_root, src_root, build_type, extra_cmake_arg
|
||||
open(os.path.join(build_root, 'recmake.' + ('bat' if WINDOWS else 'sh')), 'w').write(' '.join(map(quote_parens, cmdline)))
|
||||
ret = subprocess.check_call(cmdline, cwd=build_root, env=build_env(CMAKE_GENERATOR))
|
||||
if ret != 0:
|
||||
print('CMake invocation failed with exit code ' + ret + '!', file=sys.stderr)
|
||||
print('Working directory: ' + build_root, file=sys.stderr)
|
||||
errlog('CMake invocation failed with exit code ' + ret + '!')
|
||||
errlog('Working directory: ' + build_root)
|
||||
return False
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
print(str(e), file=sys.stderr)
|
||||
print('Could not run CMake, perhaps it has not been installed?', file=sys.stderr)
|
||||
errlog(str(e))
|
||||
errlog('Could not run CMake, perhaps it has not been installed?')
|
||||
if WINDOWS:
|
||||
print('Installing this package requires CMake. Get it from http://www.cmake.org/', file=sys.stderr)
|
||||
errlog('Installing this package requires CMake. Get it from http://www.cmake.org/')
|
||||
elif LINUX:
|
||||
print('Installing this package requires CMake. Get it via your system package manager (e.g. sudo apt-get install cmake), or from http://www.cmake.org/', file=sys.stderr)
|
||||
errlog('Installing this package requires CMake. Get it via your system package manager (e.g. sudo apt-get install cmake), or from http://www.cmake.org/')
|
||||
elif MACOS:
|
||||
print('Installing this package requires CMake. Get it via a macOS package manager (Homebrew: "brew install cmake", or MacPorts: "sudo port install cmake"), or from http://www.cmake.org/', file=sys.stderr)
|
||||
errlog('Installing this package requires CMake. Get it via a macOS package manager (Homebrew: "brew install cmake", or MacPorts: "sudo port install cmake"), or from http://www.cmake.org/')
|
||||
return False
|
||||
raise
|
||||
except Exception as e:
|
||||
print('CMake invocation failed due to exception!', file=sys.stderr)
|
||||
print('Working directory: ' + build_root, file=sys.stderr)
|
||||
print(str(e), file=sys.stderr)
|
||||
errlog('CMake invocation failed due to exception!')
|
||||
errlog('Working directory: ' + build_root)
|
||||
errlog(str(e))
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -2112,8 +2117,8 @@ def is_emsdk_sourced_from_github():
|
||||
|
||||
def update_emsdk():
|
||||
if is_emsdk_sourced_from_github():
|
||||
print('You seem to have bootstrapped Emscripten SDK by cloning from GitHub. In this case, use "git pull" instead of "emsdk update" to update emsdk. (Not doing that automatically in case you have local changes)', file=sys.stderr)
|
||||
print('Alternatively, use "emsdk update-tags" to refresh the latest list of tags from the different Git repositories.', file=sys.stderr)
|
||||
errlog('You seem to have bootstrapped Emscripten SDK by cloning from GitHub. In this case, use "git pull" instead of "emsdk update" to update emsdk. (Not doing that automatically in case you have local changes)')
|
||||
errlog('Alternatively, use "emsdk update-tags" to refresh the latest list of tags from the different Git repositories.')
|
||||
sys.exit(1)
|
||||
if not download_and_unzip(emsdk_zip_download_url, emsdk_path(), download_even_if_exists=True, clobber=False):
|
||||
sys.exit(1)
|
||||
@@ -2174,7 +2179,7 @@ def load_llvm_precompiled_tags_64bit():
|
||||
|
||||
|
||||
def exit_with_error(msg):
|
||||
sys.stdout.write(str(msg) + '\n')
|
||||
errlog(str(msg))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -2348,7 +2353,7 @@ def remove_nonexisting_tools(tool_list, log_errors=True):
|
||||
tool = tool_list[i]
|
||||
if not tool.is_installed():
|
||||
if log_errors:
|
||||
print("Warning: The SDK/tool '" + str(tool) + "' cannot be activated since it is not installed! Skipping this tool...")
|
||||
errlog("Warning: The SDK/tool '" + str(tool) + "' cannot be activated since it is not installed! Skipping this tool...")
|
||||
tool_list.pop(i)
|
||||
continue
|
||||
i += 1
|
||||
@@ -2563,10 +2568,6 @@ def adjusted_path(tools_to_activate, log_additions=False, system_path_only=False
|
||||
return (separator.join(whole_path), new_emsdk_tools)
|
||||
|
||||
|
||||
def log_stderr(msg):
|
||||
sys.stderr.write(str(msg) + '\n')
|
||||
|
||||
|
||||
def construct_env(tools_to_activate):
|
||||
env_string = ''
|
||||
newpath, added_path = adjusted_path(tools_to_activate)
|
||||
@@ -2585,10 +2586,10 @@ def construct_env(tools_to_activate):
|
||||
assert False
|
||||
|
||||
if added_path:
|
||||
log_stderr('Adding directories to PATH:')
|
||||
errlog('Adding directories to PATH:')
|
||||
for item in added_path:
|
||||
log_stderr('PATH += ' + item)
|
||||
log_stderr('')
|
||||
errlog('PATH += ' + item)
|
||||
errlog('')
|
||||
|
||||
# A core variable EMSDK points to the root of Emscripten SDK directory.
|
||||
env_vars = [('EMSDK', to_unix_path(emsdk_path()))]
|
||||
@@ -2611,7 +2612,7 @@ def construct_env(tools_to_activate):
|
||||
env_vars += [(key, value)]
|
||||
|
||||
if env_vars:
|
||||
log_stderr('Setting environment variables:')
|
||||
errlog('Setting environment variables:')
|
||||
for key, value in env_vars:
|
||||
if POWERSHELL:
|
||||
env_string += '$env:' + key + '="' + value + '"\n'
|
||||
@@ -2623,15 +2624,15 @@ def construct_env(tools_to_activate):
|
||||
env_string += 'export ' + key + '="' + value + '";\n'
|
||||
else:
|
||||
assert False
|
||||
log_stderr(key + ' = ' + value)
|
||||
errlog(key + ' = ' + value)
|
||||
return env_string
|
||||
|
||||
|
||||
def error_on_missing_tool(name):
|
||||
if name.endswith('-64bit') and not is_os_64bit():
|
||||
print("Error: '%s' is only provided for 64-bit OSes." % name)
|
||||
errlog("Error: '%s' is only provided for 64-bit OSes." % name)
|
||||
else:
|
||||
print("Error: No tool or SDK found by name '%s'." % name)
|
||||
errlog("Error: No tool or SDK found by name '%s'." % name)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -2684,7 +2685,7 @@ def main():
|
||||
global BUILD_FOR_TESTING, ENABLE_LLVM_ASSERTIONS, TTY_OUTPUT
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
print("Missing command; Type 'emsdk help' to get a list of commands.")
|
||||
errlog("Missing command; Type 'emsdk help' to get a list of commands.")
|
||||
return 1
|
||||
if sys.argv[1] in ('help', '--help', '-h'):
|
||||
print(' emsdk: Available commands:')
|
||||
@@ -2806,9 +2807,9 @@ def main():
|
||||
arg_uses = extract_bool_arg('--uses')
|
||||
arg_global = extract_bool_arg('--global')
|
||||
if extract_bool_arg('--embedded'):
|
||||
print('embedded mode is now the only mode available', file=sys.stderr)
|
||||
errlog('embedded mode is now the only mode available')
|
||||
if extract_bool_arg('--no-embedded'):
|
||||
print('embedded mode is now the only mode available', file=sys.stderr)
|
||||
errlog('embedded mode is now the only mode available')
|
||||
return 1
|
||||
|
||||
arg_notty = extract_bool_arg('--notty')
|
||||
@@ -2833,7 +2834,7 @@ def main():
|
||||
CMAKE_GENERATOR = build_generator.group(1)
|
||||
sys.argv[i] = ''
|
||||
else:
|
||||
print("Cannot parse CMake generator string: " + sys.argv[i] + ". Try wrapping generator string with quotes", file=sys.stderr)
|
||||
errlog("Cannot parse CMake generator string: " + sys.argv[i] + ". Try wrapping generator string with quotes")
|
||||
return 1
|
||||
elif sys.argv[i].startswith('--build='):
|
||||
build_type = re.match(r'^--build=(.+)$', sys.argv[i])
|
||||
@@ -2846,10 +2847,10 @@ def main():
|
||||
CMAKE_BUILD_TYPE_OVERRIDE = build_types[build_type_index]
|
||||
sys.argv[i] = ''
|
||||
except:
|
||||
print('Unknown CMake build type "' + build_type + '" specified! Please specify one of ' + str(build_types), file=sys.stderr)
|
||||
errlog('Unknown CMake build type "' + build_type + '" specified! Please specify one of ' + str(build_types))
|
||||
return 1
|
||||
else:
|
||||
print("Invalid command line parameter " + sys.argv[i] + ' specified!', file=sys.stderr)
|
||||
errlog("Invalid command line parameter " + sys.argv[i] + ' specified!')
|
||||
return 1
|
||||
sys.argv = [x for x in sys.argv if not len(x) == 0]
|
||||
|
||||
@@ -3014,14 +3015,14 @@ def main():
|
||||
return error_on_missing_tool(arg)
|
||||
tools_to_activate += [tool]
|
||||
if not tools_to_activate:
|
||||
print('No tools/SDKs specified to activate! Usage:\n emsdk activate tool/sdk1 [tool/sdk2] [...]')
|
||||
errlog('No tools/SDKs specified to activate! Usage:\n emsdk activate tool/sdk1 [tool/sdk2] [...]')
|
||||
return 1
|
||||
active_tools = set_active_tools(tools_to_activate, permanently_activate=arg_global)
|
||||
if not active_tools:
|
||||
print('No tools/SDKs found to activate! Usage:\n emsdk activate tool/sdk1 [tool/sdk2] [...]')
|
||||
errlog('No tools/SDKs found to activate! Usage:\n emsdk activate tool/sdk1 [tool/sdk2] [...]')
|
||||
return 1
|
||||
if WINDOWS and not arg_global:
|
||||
print('The changes made to environment variables only apply to the currently running shell instance. Use the \'emsdk_env.bat\' to re-enter this environment later, or if you\'d like to permanently register this environment globally to all users in Windows Registry, rerun this command with the option --global.')
|
||||
errlog('The changes made to environment variables only apply to the currently running shell instance. Use the \'emsdk_env.bat\' to re-enter this environment later, or if you\'d like to permanently register this environment globally to all users in Windows Registry, rerun this command with the option --global.')
|
||||
return 0
|
||||
elif cmd == 'install':
|
||||
# Process args
|
||||
@@ -3033,7 +3034,7 @@ def main():
|
||||
CPU_CORES = int(multicore.group(1))
|
||||
sys.argv[i] = ''
|
||||
else:
|
||||
print("Invalid command line parameter " + sys.argv[i] + ' specified!', file=sys.stderr)
|
||||
errlog("Invalid command line parameter " + sys.argv[i] + ' specified!')
|
||||
return 1
|
||||
elif sys.argv[i] == '--shallow':
|
||||
global GIT_CLONE_SHALLOW
|
||||
@@ -3050,7 +3051,7 @@ def main():
|
||||
sys.argv[i] = ''
|
||||
sys.argv = [x for x in sys.argv if not len(x) == 0]
|
||||
if len(sys.argv) <= 2:
|
||||
print("Missing parameter. Type 'emsdk install <tool name>' to install a tool or an SDK. Type 'emsdk list' to obtain a list of available tools. Type 'emsdk install latest' to automatically install the newest version of the SDK.")
|
||||
errlog("Missing parameter. Type 'emsdk install <tool name>' to install a tool or an SDK. Type 'emsdk list' to obtain a list of available tools. Type 'emsdk install latest' to automatically install the newest version of the SDK.")
|
||||
return 1
|
||||
for t in sys.argv[2:]:
|
||||
tool = find_tool(t)
|
||||
@@ -3064,16 +3065,16 @@ def main():
|
||||
return 0
|
||||
elif cmd == 'uninstall':
|
||||
if len(sys.argv) <= 2:
|
||||
print("Syntax error. Call 'emsdk uninstall <tool name>'. Call 'emsdk list' to obtain a list of available tools.")
|
||||
errlog("Syntax error. Call 'emsdk uninstall <tool name>'. Call 'emsdk list' to obtain a list of available tools.")
|
||||
return 1
|
||||
tool = find_tool(sys.argv[2])
|
||||
if tool is None:
|
||||
print("Error: Tool by name '" + sys.argv[2] + "' was not found.")
|
||||
errlog("Error: Tool by name '" + sys.argv[2] + "' was not found.")
|
||||
return 1
|
||||
tool.uninstall()
|
||||
return 0
|
||||
|
||||
print("Unknown command '" + cmd + "' given! Type 'emsdk help' to get a list of commands.")
|
||||
errlog("Unknown command '" + cmd + "' given! Type 'emsdk help' to get a list of commands.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user