From ec54013d965a0d314be5b8e2577583ca207354e3 Mon Sep 17 00:00:00 2001 From: hollste Date: Wed, 18 Nov 2020 10:42:41 -0800 Subject: [PATCH] Fix copy shared libraries when target label contains subdirectories Fixes https://github.com/bazelbuild/bazel/issues/12448 Closes #12449. PiperOrigin-RevId: 343109568 --- .../build/lib/rules/cpp/CcBinary.java | 19 ++++++++------- src/test/py/bazel/bazel_windows_cpp_test.py | 24 ++++++++++++++++--- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index 5d44cef0ffa45a..8e86b88a743123 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java @@ -1049,23 +1049,26 @@ private static Packager createIntermediateDwpPackagers( private static NestedSet createDynamicLibrariesCopyActions( RuleContext ruleContext, Iterable dynamicLibrariesForRuntime) { NestedSetBuilder result = NestedSetBuilder.stableOrder(); - for (Artifact target : dynamicLibrariesForRuntime) { + for (Artifact lib : dynamicLibrariesForRuntime) { // If the binary and the DLL don't belong to the same package or the DLL is a source file, // we should copy the DLL to the binary's directory. if (!ruleContext .getLabel() .getPackageIdentifier() - .equals(target.getOwner().getPackageIdentifier()) - || target.isSourceArtifact()) { + .equals(lib.getOwner().getPackageIdentifier()) + || lib.isSourceArtifact()) { + String targetName = ruleContext.getTarget().getName(); + PathFragment targetSubDir = PathFragment.create(targetName).getParentDirectory(); // SymlinkAction on file is actually copy on Windows. - Artifact copy = ruleContext.getBinArtifact(target.getFilename()); - ruleContext.registerAction(SymlinkAction.toArtifact( - ruleContext.getActionOwner(), target, copy, "Copying Execution Dynamic Library")); + Artifact copy = ruleContext.getBinArtifact(targetSubDir.getRelative(lib.getFilename())); + ruleContext.registerAction( + SymlinkAction.toArtifact( + ruleContext.getActionOwner(), lib, copy, "Copying Execution Dynamic Library")); result.add(copy); } else { - // If the target is already in the same directory as the binary, we don't need to copy it, + // If the library is already in the same directory as the binary, we don't need to copy it, // but we still add it the result. - result.add(target); + result.add(lib); } } return result.build(); diff --git a/src/test/py/bazel/bazel_windows_cpp_test.py b/src/test/py/bazel/bazel_windows_cpp_test.py index a688e0b7666b36..737c4d5457e6e0 100644 --- a/src/test/py/bazel/bazel_windows_cpp_test.py +++ b/src/test/py/bazel/bazel_windows_cpp_test.py @@ -683,11 +683,25 @@ def testCopyDLLAsSource(self): 'cc_import(', ' name = "a_import",', ' shared_library = "A.dll",', + ' visibility = ["//:__subpackages__"],', + ')', + '' + 'filegroup(', + ' name = "bin_src",', + ' srcs = ["bin.cc"],', + ' visibility = ["//:__subpackages__"],', ')', '', 'cc_binary(', ' name = "bin",', - ' srcs = ["bin.cc"],', + ' srcs = ["//:bin_src"],', + ' deps = ["//:a_import"],', + ')', + ]) + self.ScratchFile('package/BUILD', [ + 'cc_binary(', + ' name = "dir1/dir2/bin",', + ' srcs = ["//:bin_src"],', ' deps = ["//:a_import"],', ')', ]) @@ -700,15 +714,19 @@ def testCopyDLLAsSource(self): exit_code, _, stderr = self.RunBazel([ 'build', '//:bin', + '//package:dir1/dir2/bin', ]) self.AssertExitCode(exit_code, 0, stderr) bazel_bin = self.getBazelInfo('bazel-bin') - a_dll = os.path.join(bazel_bin, 'A.dll') - # Even though A.dll is in the same package as bin.exe, but it still should + # Even though A.dll is in the same package as bin.exe, it still should # be copied to the output directory of bin.exe. + a_dll = os.path.join(bazel_bin, 'A.dll') self.assertTrue(os.path.exists(a_dll)) + nested_a_dll = os.path.join(bazel_bin, 'package/dir1/dir2/A.dll') + self.assertTrue(os.path.exists(nested_a_dll)) + def testCppErrorShouldBeVisible(self): self.CreateWorkspaceWithDefaultRepos('WORKSPACE') self.ScratchFile('BUILD', [