diff --git a/libcxx/test/configs/llvm-libc++-mingw.cfg.in b/libcxx/test/configs/llvm-libc++-mingw.cfg.in --- a/libcxx/test/configs/llvm-libc++-mingw.cfg.in +++ b/libcxx/test/configs/llvm-libc++-mingw.cfg.in @@ -11,7 +11,7 @@ '-nostdlib++ -L %{lib} -lc++' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site diff --git a/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in b/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in --- a/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in +++ b/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in @@ -11,7 +11,7 @@ '-nostdlib -L %{lib} -lc++ -lmsvcrt -lmsvcprt -loldnames' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site diff --git a/libcxx/test/configs/llvm-libc++-shared-no-vcruntime-clangcl.cfg.in b/libcxx/test/configs/llvm-libc++-shared-no-vcruntime-clangcl.cfg.in --- a/libcxx/test/configs/llvm-libc++-shared-no-vcruntime-clangcl.cfg.in +++ b/libcxx/test/configs/llvm-libc++-shared-no-vcruntime-clangcl.cfg.in @@ -12,7 +12,7 @@ '-nostdlib -L %{lib} -lc++ -lmsvcrt -lmsvcprt -loldnames' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site diff --git a/libcxx/utils/run.py b/libcxx/utils/run.py --- a/libcxx/utils/run.py +++ b/libcxx/utils/run.py @@ -23,7 +23,8 @@ parser = argparse.ArgumentParser() parser.add_argument('--execdir', type=str, required=True) parser.add_argument('--codesign_identity', type=str, required=False, default=None) - parser.add_argument('--env', type=str, nargs='*', required=False, default=dict()) + parser.add_argument('--env', type=str, nargs='*', required=False, default=[]) + parser.add_argument('--prepend_env', type=str, nargs='*', required=False, default=[]) parser.add_argument("command", nargs=argparse.ONE_OR_MORE) args = parser.parse_args() commandLine = args.command @@ -43,6 +44,14 @@ # Extract environment variables into a dictionary env = {k : v for (k, v) in map(lambda s: s.split('=', 1), args.env)} + + # Set environment variables where we prepend the given value to the + # existing environment variable. + for (k, v) in map(lambda s: s.split('=', 1), args.prepend_env): + if k in os.environ: + v = v + os.pathsep + os.environ[k] + env[k] = v + if platform.system() == 'Windows': # Pass some extra variables through on Windows: # COMSPEC is needed for running subprocesses via std::system(). diff --git a/libcxx/utils/ssh.py b/libcxx/utils/ssh.py --- a/libcxx/utils/ssh.py +++ b/libcxx/utils/ssh.py @@ -47,7 +47,8 @@ parser.add_argument('--extra-ssh-args', type=str, required=False) parser.add_argument('--extra-scp-args', type=str, required=False) parser.add_argument('--codesign_identity', type=str, required=False, default=None) - parser.add_argument('--env', type=str, nargs='*', required=False, default=dict()) + parser.add_argument('--env', type=str, nargs='*', required=False, default=[]) + parser.add_argument('--prepend_env', type=str, nargs='*', required=False, default=[]) parser.add_argument("command", nargs=argparse.ONE_OR_MORE) args = parser.parse_args() commandLine = args.command @@ -108,6 +109,12 @@ # temporary directory on the remote host. commandLine = (pathOnRemote(x) if isTestExe(x) else x for x in commandLine) remoteCommands.append('cd {}'.format(tmp)) + + if args.prepend_env: + # We can't sensibly know the original value of the env vars + # in order to prepend to them, so just overwrite these variables. + args.env.extend(args.prepend_env) + if args.env: env = list(map(cmd_quote, args.env)) remoteCommands.append('export {}'.format(' '.join(args.env))) diff --git a/libcxxabi/test/configs/llvm-libc++abi-mingw.cfg.in b/libcxxabi/test/configs/llvm-libc++abi-mingw.cfg.in --- a/libcxxabi/test/configs/llvm-libc++abi-mingw.cfg.in +++ b/libcxxabi/test/configs/llvm-libc++abi-mingw.cfg.in @@ -11,7 +11,7 @@ '-nostdlib++ -L %{lib} -lc++' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site diff --git a/libcxxabi/test/configs/llvm-libc++abi-shared-clangcl.cfg.in b/libcxxabi/test/configs/llvm-libc++abi-shared-clangcl.cfg.in --- a/libcxxabi/test/configs/llvm-libc++abi-shared-clangcl.cfg.in +++ b/libcxxabi/test/configs/llvm-libc++abi-shared-clangcl.cfg.in @@ -11,7 +11,7 @@ '-nostdlib -L %{lib} -lc++ -lc++abi -lmsvcrt -lmsvcprt -loldnames' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site diff --git a/libcxxabi/test/configs/llvm-libc++abi-static-clangcl.cfg.in b/libcxxabi/test/configs/llvm-libc++abi-static-clangcl.cfg.in --- a/libcxxabi/test/configs/llvm-libc++abi-static-clangcl.cfg.in +++ b/libcxxabi/test/configs/llvm-libc++abi-static-clangcl.cfg.in @@ -11,7 +11,7 @@ '-nostdlib -L %{lib} -llibc++ -llibc++abi -lmsvcrt -lmsvcprt -loldnames' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site diff --git a/libunwind/test/configs/llvm-libunwind-mingw.cfg.in b/libunwind/test/configs/llvm-libunwind-mingw.cfg.in --- a/libunwind/test/configs/llvm-libunwind-mingw.cfg.in +++ b/libunwind/test/configs/llvm-libunwind-mingw.cfg.in @@ -11,7 +11,7 @@ '-L %{lib} -lunwind' )) config.substitutions.append(('%{exec}', - '%{executor} --execdir %T --env PATH=%{lib} -- ' + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' )) import os, site