Skip to content

[clang] Split out and disable tests that break relative rpaths #137411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 26, 2025

Conversation

rnk
Copy link
Collaborator

@rnk rnk commented Apr 25, 2025

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Apr 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 25, 2025

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Reid Kleckner (rnk)

Changes

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.


Full diff: https://github.com/llvm/llvm-project/pull/137411.diff

7 Files Affected:

  • (modified) clang/test/CMakeLists.txt (+3)
  • (modified) clang/test/Driver/clang_f_opts.c (-13)
  • (added) clang/test/Driver/clang_f_opts_withspaces.c (+20)
  • (added) clang/test/Driver/darwin-header-search-libcxx-2.cpp (+64)
  • (modified) clang/test/Driver/darwin-header-search-libcxx.cpp (-57)
  • (modified) clang/test/lit.cfg.py (+5)
  • (modified) clang/test/lit.site.cfg.py.in (+3)
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index af3bc3853edfc..0d11fd2c07eb5 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -2,6 +2,7 @@
 # for use by Lit, and delegates to LLVM's lit test handlers.
 
 llvm_canonicalize_cmake_booleans(
+  BUILD_SHARED_LIBS
   CLANG_BUILD_EXAMPLES
   CLANG_BUILT_STANDALONE
   CLANG_DEFAULT_PIE_ON_LINUX
@@ -10,6 +11,7 @@ llvm_canonicalize_cmake_booleans(
   CLANG_SPAWN_CC1
   CLANG_ENABLE_CIR
   CLANG_ENABLE_OBJC_REWRITER
+  CLANG_LINK_CLANG_DYLIB
   ENABLE_BACKTRACES
   LLVM_BUILD_EXAMPLES
   LLVM_BYE_LINK_INTO_TOOLS
@@ -19,6 +21,7 @@ llvm_canonicalize_cmake_booleans(
   LLVM_ENABLE_PER_TARGET_RUNTIME_DIR
   LLVM_ENABLE_THREADS
   LLVM_ENABLE_REVERSE_ITERATION
+  LLVM_LINK_LLVM_DYLIB
   LLVM_WITH_Z3
   PPC_LINUX_DEFAULT_IEEELONGDOUBLE
   LLVM_TOOL_LLVM_DRIVER_BUILD
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index f6bf71417e6f8..ee7ded265769b 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -542,19 +542,6 @@
 // CHECK-RECORD-GCC-SWITCHES: "-record-command-line"
 // CHECK-NO-RECORD-GCC-SWITCHES-NOT: "-record-command-line"
 // CHECK-RECORD-GCC-SWITCHES-ERROR: error: unsupported option '-frecord-command-line' for target
-// Test when clang is in a path containing a space.
-// The initial `rm` is a workaround for https://openradar.appspot.com/FB8914243
-// (Scenario: Run tests once, `clang` gets copied and run at new location and signature
-// is cached at the new clang's inode, then clang is changed, tests run again, old signature
-// is still cached with old clang's inode, so it won't execute this time. Removing the dir
-// first guarantees a new inode without old cache entries.)
-// RUN: rm -rf "%t.r/with spaces"
-// RUN: mkdir -p "%t.r/with spaces"
-// RUN: cp %clang "%t.r/with spaces/clang"
-// RUN: "%t.r/with spaces/clang" -### -S --target=x86_64-unknown-linux -frecord-gcc-switches %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES-ESCAPED %s
-// CHECK-RECORD-GCC-SWITCHES-ESCAPED: "-record-command-line" "{{.+}}with\\ spaces{{.+}}"
-// Clean up copy of large binary copied into temp directory to avoid bloat.
-// RUN: rm -f "%t.r/with spaces/clang" || true
 
 // RUN: %clang -### -S -ftrivial-auto-var-init=uninitialized %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-UNINIT %s
 // RUN: %clang -### -S -ftrivial-auto-var-init=pattern %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-PATTERN %s
diff --git a/clang/test/Driver/clang_f_opts_withspaces.c b/clang/test/Driver/clang_f_opts_withspaces.c
new file mode 100644
index 0000000000000..e40435ed71db6
--- /dev/null
+++ b/clang/test/Driver/clang_f_opts_withspaces.c
@@ -0,0 +1,20 @@
+// UNSUPPORTED: target={{.*}}-aix{{.*}}
+
+// Copying clang to a new location and running it will not work unless it is
+// statically linked. Dynamically linked builds typically use relative rpaths,
+// which this will break.
+// REQUIRES: static-libs
+
+// Test when clang is in a path containing a space.
+// The initial `rm` is a workaround for https://openradar.appspot.com/FB8914243
+// (Scenario: Run tests once, `clang` gets copied and run at new location and signature
+// is cached at the new clang's inode, then clang is changed, tests run again, old signature
+// is still cached with old clang's inode, so it won't execute this time. Removing the dir
+// first guarantees a new inode without old cache entries.)
+// RUN: rm -rf "%t.r/with spaces"
+// RUN: mkdir -p "%t.r/with spaces"
+// RUN: cp %clang "%t.r/with spaces/clang"
+// RUN: "%t.r/with spaces/clang" -### -S --target=x86_64-unknown-linux -frecord-gcc-switches %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES-ESCAPED %s
+// CHECK-RECORD-GCC-SWITCHES-ESCAPED: "-record-command-line" "{{.+}}with\\ spaces{{.+}}"
+// Clean up copy of large binary copied into temp directory to avoid bloat.
+// RUN: rm -f "%t.r/with spaces/clang" || true
diff --git a/clang/test/Driver/darwin-header-search-libcxx-2.cpp b/clang/test/Driver/darwin-header-search-libcxx-2.cpp
new file mode 100644
index 0000000000000..055b653614dab
--- /dev/null
+++ b/clang/test/Driver/darwin-header-search-libcxx-2.cpp
@@ -0,0 +1,64 @@
+// General tests that the header search paths for libc++ detected by the driver
+// and passed to CC1 are correct on Darwin platforms. This test copies the clang
+// binary, which won't work if it uses any dynamic libraries (BUILD_SHARED_LIBS,
+// LLVM_LINK_LLVM_DYLIB, or CLANG_LINK_CLANG_DYLIB).
+
+// UNSUPPORTED: system-windows
+// REQUIRES: static-libs
+
+// ----------------------------------------------------------------------------
+// On Darwin, libc++ can be installed in one of the following places:
+// 1. Alongside the compiler in <install>/include/c++/v1
+// 2. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
+// 3. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
+
+// The build folders do not have an `include/c++/v1`; create a new
+// local folder hierarchy that meets this requirement.
+// Note: this might not work with weird RPATH configurations.
+// RUN: rm -rf %t/install
+// RUN: mkdir -p %t/install/bin
+// RUN: cp %clang %t/install/bin/clang
+// RUN: mkdir -p %t/install/include/c++/v1
+
+// Headers in (1) and in (2) -> (1) is preferred over (2)
+// RUN: rm -rf %t/symlinked1
+// RUN: mkdir -p %t/symlinked1/bin
+// RUN: ln -sf %t/install/bin/clang %t/symlinked1/bin/clang
+// RUN: mkdir -p %t/symlinked1/include/c++/v1
+
+// RUN: %t/symlinked1/bin/clang -### %s -no-canonical-prefixes -fsyntax-only 2>&1 \
+// RUN:     --target=x86_64-apple-darwin \
+// RUN:     -stdlib=libc++ \
+// RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
+// RUN:   | FileCheck -DSYMLINKED=%t/symlinked1 \
+// RUN:               -DTOOLCHAIN=%t/install \
+// RUN:               -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
+// RUN:               --check-prefix=CHECK-SYMLINKED-INCLUDE-CXX-V1 %s
+// CHECK-SYMLINKED-INCLUDE-CXX-V1: "-internal-isystem" "[[SYMLINKED]]/bin/../include/c++/v1"
+// CHECK-SYMLINKED-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
+// CHECK-SYMLINKED-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
+
+// Headers in (2) and in (3) -> (2) is preferred over (3)
+// RUN: rm -rf %t/symlinked2
+// RUN: mkdir -p %t/symlinked2/bin
+// RUN: ln -sf %t/install/bin/clang %t/symlinked2/bin/clang
+
+// RUN: %t/symlinked2/bin/clang -### %s -fsyntax-only 2>&1 \
+// RUN:     --target=x86_64-apple-darwin \
+// RUN:     -stdlib=libc++ \
+// RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
+// RUN:   | FileCheck -DTOOLCHAIN=%t/install \
+// RUN:               -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
+// RUN:               --check-prefix=CHECK-TOOLCHAIN-INCLUDE-CXX-V1 %s
+// CHECK-TOOLCHAIN-INCLUDE-CXX-V1: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
+// CHECK-TOOLCHAIN-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
+
+// Headers in (2) and nowhere else -> (2) is used
+// RUN: %t/symlinked2/bin/clang -### %s -fsyntax-only 2>&1 \
+// RUN:     --target=x86_64-apple-darwin \
+// RUN:     -stdlib=libc++ \
+// RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
+// RUN:   | FileCheck -DTOOLCHAIN=%t/install \
+// RUN:               -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
+// RUN:               --check-prefix=CHECK-TOOLCHAIN-NO-SYSROOT %s
+// CHECK-TOOLCHAIN-NO-SYSROOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
diff --git a/clang/test/Driver/darwin-header-search-libcxx.cpp b/clang/test/Driver/darwin-header-search-libcxx.cpp
index 5695f53683bab..cc8ec9ceb89b3 100644
--- a/clang/test/Driver/darwin-header-search-libcxx.cpp
+++ b/clang/test/Driver/darwin-header-search-libcxx.cpp
@@ -172,60 +172,3 @@
 // RUN:               --check-prefix=CHECK-LIBCXX-STDLIB-UNSPECIFIED %s
 // CHECK-LIBCXX-STDLIB-UNSPECIFIED: "-cc1"
 // CHECK-LIBCXX-STDLIB-UNSPECIFIED: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
-
-// ----------------------------------------------------------------------------
-// On Darwin, libc++ can be installed in one of the following places:
-// 1. Alongside the compiler in <install>/include/c++/v1
-// 2. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
-// 3. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
-
-// The build folders do not have an `include/c++/v1`; create a new
-// local folder hierarchy that meets this requirement.
-// Note: this might not work with weird RPATH configurations.
-// RUN: rm -rf %t/install
-// RUN: mkdir -p %t/install/bin
-// RUN: cp %clang %t/install/bin/clang
-// RUN: mkdir -p %t/install/include/c++/v1
-
-// Headers in (1) and in (2) -> (1) is preferred over (2)
-// RUN: rm -rf %t/symlinked1
-// RUN: mkdir -p %t/symlinked1/bin
-// RUN: ln -sf %t/install/bin/clang %t/symlinked1/bin/clang
-// RUN: mkdir -p %t/symlinked1/include/c++/v1
-
-// RUN: %t/symlinked1/bin/clang -### %s -no-canonical-prefixes -fsyntax-only 2>&1 \
-// RUN:     --target=x86_64-apple-darwin \
-// RUN:     -stdlib=libc++ \
-// RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
-// RUN:   | FileCheck -DSYMLINKED=%t/symlinked1 \
-// RUN:               -DTOOLCHAIN=%t/install \
-// RUN:               -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
-// RUN:               --check-prefix=CHECK-SYMLINKED-INCLUDE-CXX-V1 %s
-// CHECK-SYMLINKED-INCLUDE-CXX-V1: "-internal-isystem" "[[SYMLINKED]]/bin/../include/c++/v1"
-// CHECK-SYMLINKED-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
-// CHECK-SYMLINKED-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
-
-// Headers in (2) and in (3) -> (2) is preferred over (3)
-// RUN: rm -rf %t/symlinked2
-// RUN: mkdir -p %t/symlinked2/bin
-// RUN: ln -sf %t/install/bin/clang %t/symlinked2/bin/clang
-
-// RUN: %t/symlinked2/bin/clang -### %s -fsyntax-only 2>&1 \
-// RUN:     --target=x86_64-apple-darwin \
-// RUN:     -stdlib=libc++ \
-// RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
-// RUN:   | FileCheck -DTOOLCHAIN=%t/install \
-// RUN:               -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
-// RUN:               --check-prefix=CHECK-TOOLCHAIN-INCLUDE-CXX-V1 %s
-// CHECK-TOOLCHAIN-INCLUDE-CXX-V1: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
-// CHECK-TOOLCHAIN-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
-
-// Headers in (2) and nowhere else -> (2) is used
-// RUN: %t/symlinked2/bin/clang -### %s -fsyntax-only 2>&1 \
-// RUN:     --target=x86_64-apple-darwin \
-// RUN:     -stdlib=libc++ \
-// RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
-// RUN:   | FileCheck -DTOOLCHAIN=%t/install \
-// RUN:               -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
-// RUN:               --check-prefix=CHECK-TOOLCHAIN-NO-SYSROOT %s
-// CHECK-TOOLCHAIN-NO-SYSROOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index 8f1392b6a1f8f..f963b656b663c 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -225,6 +225,11 @@ def have_host_clang_repl_cuda():
 if "aarch64" in config.host_arch:
     config.available_features.add("aarch64-host")
 
+# Some tests are sensitive to whether clang is statically or dynamically linked
+# to other libraries.
+if not (config.build_shared_libs or config.link_llvm_dylib or config.link_clang_dylib):
+    config.available_features.add("static-libs")
+
 # Plugins (loadable modules)
 if config.has_plugins and config.llvm_plugin_ext:
     config.available_features.add("plugins")
diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in
index 80cded2625df4..e73acfc79d9ad 100644
--- a/clang/test/lit.site.cfg.py.in
+++ b/clang/test/lit.site.cfg.py.in
@@ -32,6 +32,9 @@ config.clang_examples = @CLANG_BUILD_EXAMPLES@
 config.enable_shared = @ENABLE_SHARED@
 config.enable_backtrace = @ENABLE_BACKTRACES@
 config.enable_threads = @LLVM_ENABLE_THREADS@
+config.build_shared_libs = @BUILD_SHARED_LIBS@
+config.link_llvm_dylib = @LLVM_LINK_LLVM_DYLIB@
+config.link_clang_dylib = @CLANG_LINK_CLANG_DYLIB@
 config.reverse_iteration = @LLVM_ENABLE_REVERSE_ITERATION@
 config.host_arch = "@HOST_ARCH@"
 config.perl_executable = "@PERL_EXECUTABLE@"

@rnk rnk requested review from compnerd and tstellar April 25, 2025 22:57
Copy link
Member

@compnerd compnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can do this check statically instead.

@rnk rnk merged commit 7afbffb into llvm:main Apr 26, 2025
14 checks passed
@rnk
Copy link
Collaborator Author

rnk commented Apr 26, 2025

I wonder if we can do this check statically instead.

I'm not sure I follow, what do you mean by "statically" in this context?

Copy link
Member

@carlocab carlocab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks; this has bugged me for a while now.

@compnerd
Copy link
Member

I wonder if we can do this check statically instead.

I'm not sure I follow, what do you mean by "statically" in this context?

Well, if this is less about ensuring the loader does the right thing and more about the encoding, we could simply check that the value for DT_RPATH or DT_RUNPATH is correct. That can be done by simply strategically inspecting the binary rather than executing the target.

jyli0116 pushed a commit to jyli0116/llvm-project that referenced this pull request Apr 28, 2025
…137411)

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…137411)

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…137411)

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…137411)

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
…137411)

These two tests copy the clang binary into the test tree and assume it
will run from a new location. This is incompatible with relative rpath
values, which is what you typically get in a dylib developer build.
Disable these tests if shared libraries are involved. Another way to
make these tests work would be to update the loader search path
environment variables, but it is difficult to do that portably.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants