[libcxx] Codesign test executables if necessary
If LLVM_CODESIGNING_IDENTITY is set, test executables need to be
codesigned.
Differential Revision: https://reviews.llvm.org/D66496
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@371126 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/libcxx/strings/basic.string/PR42676.sh.cpp b/test/libcxx/strings/basic.string/PR42676.sh.cpp
index 5aa2402..7037482 100644
--- a/test/libcxx/strings/basic.string/PR42676.sh.cpp
+++ b/test/libcxx/strings/basic.string/PR42676.sh.cpp
@@ -9,7 +9,7 @@
// Regression test for PR42676.
// RUN: %cxx %flags %s -o %t.exe %compile_flags %link_flags -D_LIBCPP_HIDE_FROM_ABI_PER_TU
-// RUN: %t.exe
+// RUN: %run
#include <memory>
#include <string>
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index fafc8fe..a435452 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -37,6 +37,9 @@
config.pstl_obj_root = "@ParallelSTL_BINARY_DIR@" if @LIBCXX_ENABLE_PARALLEL_ALGORITHMS@ else None
config.libcxx_gdb = "@LIBCXX_GDB@"
+# Code signing
+config.llvm_codesign_identity = "@LLVM_CODESIGNING_IDENTITY@"
+
# Let the main config do the real work.
config.loaded_site_config = True
lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg")
diff --git a/utils/libcxx/compiler.py b/utils/libcxx/compiler.py
index a553dbf..dd334cd 100644
--- a/utils/libcxx/compiler.py
+++ b/utils/libcxx/compiler.py
@@ -17,12 +17,13 @@
CM_Compile = 2
CM_Link = 3
- def __init__(self, path, flags=None, compile_flags=None, link_flags=None,
+ def __init__(self, config, path, flags=None, compile_flags=None, link_flags=None,
warning_flags=None, verify_supported=None,
verify_flags=None, use_verify=False,
modules_flags=None, use_modules=False,
use_ccache=False, use_warnings=False, compile_env=None,
cxx_type=None, cxx_version=None):
+ self.libcxx_config = config
self.source_lang = 'c++'
self.path = path
self.flags = list(flags or [])
@@ -163,17 +164,34 @@
cwd=cwd)
return cmd, out, err, rc
- def link(self, source_files, out=None, flags=[], cwd=None):
- cmd = self.linkCmd(source_files, out, flags)
+ def link(self, source_files, exec_path=None, flags=[], cwd=None):
+ cmd = self.linkCmd(source_files, exec_path, flags)
out, err, rc = libcxx.util.executeCommand(cmd, env=self.compile_env,
cwd=cwd)
+ cs_cmd, cs_out, cs_err, cs_rc = self.codesign(exec_path, cwd)
+ if cs_rc != 0:
+ return cs_cmd, cs_out, cs_err, cs_rc
return cmd, out, err, rc
- def compileLink(self, source_files, out=None, flags=[],
+ def compileLink(self, source_files, exec_path=None, flags=[],
cwd=None):
- cmd = self.compileLinkCmd(source_files, out, flags)
+ cmd = self.compileLinkCmd(source_files, exec_path, flags)
out, err, rc = libcxx.util.executeCommand(cmd, env=self.compile_env,
cwd=cwd)
+ cs_cmd, cs_out, cs_err, cs_rc = self.codesign(exec_path, cwd)
+ if cs_rc != 0:
+ return cs_cmd, cs_out, cs_err, cs_rc
+ return cmd, out, err, rc
+
+ def codesign(self, exec_path, cwd=None):
+ null_op = [], '', '', 0
+ if not exec_path:
+ return null_op
+ codesign_ident = self.libcxx_config.get_lit_conf('llvm_codesign_identity', '')
+ if not codesign_ident:
+ return null_op
+ cmd = ['xcrun', 'codesign', '-s', codesign_ident, exec_path]
+ out, err, rc = libcxx.util.executeCommand(cmd, cwd=cwd)
return cmd, out, err, rc
def compileLinkTwoSteps(self, source_file, out=None, object_file=None,
@@ -193,7 +211,7 @@
return cc_cmd, cc_stdout, cc_stderr, rc
link_cmd, link_stdout, link_stderr, rc = self.link(
- object_file, out=out, flags=flags, cwd=cwd)
+ object_file, exec_path=out, flags=flags, cwd=cwd)
return (cc_cmd + ['&&'] + link_cmd, cc_stdout + link_stdout,
cc_stderr + link_stderr, rc)
diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py
index 3be1aa1..670063b 100644
--- a/utils/libcxx/test/config.py
+++ b/utils/libcxx/test/config.py
@@ -228,7 +228,7 @@
if not cxx:
self.lit_config.fatal('must specify user parameter cxx_under_test '
'(e.g., --param=cxx_under_test=clang++)')
- self.cxx = CXXCompiler(cxx) if not self.cxx_is_clang_cl else \
+ self.cxx = CXXCompiler(self, cxx) if not self.cxx_is_clang_cl else \
self._configure_clang_cl(cxx)
cxx_type = self.cxx.type
if cxx_type is not None:
@@ -260,7 +260,7 @@
link_flags = _prefixed_env_list('LIB', '-L')
for path in _split_env_var('LIB'):
self.add_path(self.exec_env, path)
- return CXXCompiler(clang_path, flags=flags,
+ return CXXCompiler(self, clang_path, flags=flags,
compile_flags=compile_flags,
link_flags=link_flags)
@@ -1035,8 +1035,14 @@
self.cxx.useModules()
def configure_substitutions(self):
+ tool_env = ''
+ if platform.system() == 'Darwin':
+ # Do not pass DYLD_LIBRARY_PATH to the compiler, linker, etc. as
+ # these tools are not meant to exercise the just-built libraries.
+ tool_env += 'DYLD_LIBRARY_PATH="" '
+
sub = self.config.substitutions
- cxx_path = pipes.quote(self.cxx.path)
+ cxx_path = tool_env + pipes.quote(self.cxx.path)
# Configure compiler substitutions
sub.append(('%cxx', cxx_path))
sub.append(('%libcxx_src_root', self.libcxx_src_root))
@@ -1071,7 +1077,11 @@
sub.append(('%build', build_str))
# Configure exec prefix substitutions.
# Configure run env substitution.
- sub.append(('%run', '%t.exe'))
+ codesign_ident = self.get_lit_conf('llvm_codesign_identity', '')
+ run_py = os.path.join(self.libcxx_src_root, 'utils', 'run.py')
+ run_str = '%s %s "%s" %%t.exe' % (pipes.quote(sys.executable), \
+ pipes.quote(run_py), codesign_ident)
+ sub.append(('%run', run_str))
# Configure not program substitutions
not_py = os.path.join(self.libcxx_src_root, 'utils', 'not.py')
not_str = '%s %s ' % (pipes.quote(sys.executable), pipes.quote(not_py))
diff --git a/utils/run.py b/utils/run.py
new file mode 100644
index 0000000..fcfee96
--- /dev/null
+++ b/utils/run.py
@@ -0,0 +1,38 @@
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+
+"""run.py is a utility for running a program.
+
+It can perform code signing, forward arguments to the program, and return the
+program's error code.
+"""
+
+import subprocess
+import sys
+
+
+def main():
+ codesign_ident = sys.argv[1]
+
+ # Ignore 'run.py' and the codesigning identity.
+ argv = sys.argv[2:]
+
+ exec_path = argv[0]
+
+ # Do any necessary codesigning.
+ if codesign_ident:
+ sign_cmd = ['xcrun', 'codesign', '-f', '-s', codesign_ident, exec_path]
+ cs_rc = subprocess.call(sign_cmd, env={})
+ if cs_rc != 0:
+ sys.stderr.write('Failed to codesign: ' + exec_path)
+ return cs_rc
+
+ return subprocess.call(argv)
+
+if __name__ == '__main__':
+ exit(main())