rules_apple icon indicating copy to clipboard operation
rules_apple copied to clipboard

Duplicate symbol errors when indirectly linking cc_binary with objc_library

Open oakad opened this issue 3 years ago • 13 comments

I have a project where a cc_library depends on objc_library. When building an ios_application target everything works fine (the actual application is in turn based on objc_library).

However, when I try to build a cc_binary for macos, which depends on the cc_library, the link can not succeed. It appears, that dependencies, common to cc_library and its dependent objc_library are compiled twice, with different destination prefixes, and then added to the link twice, resulting in failure.

For example:

# ... innumerable similar errors skipped
duplicate symbol '_ares_inet_ntop' in:
    bazel-out/darwin-dbg/bin/external/com_github_cares_cares/libares.lo(inet_ntop.o)
    bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_github_cares_cares/libares.lo(inet_ntop.o)
ld: 96 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error in child process '/usr/bin/xcrun'. 1

This appears to happen, because cc_library and objc_library both depend on cares, and cares gets added to link twice (applies to the rest of similar libs the same).

oakad avatar May 15 '22 12:05 oakad

If you use a macos_command_line_application instead of a cc_binary does it work?

keith avatar May 16 '22 22:05 keith

Yes, I figured it all out the hard way.

I have a project with a large number of small binaries, cc_binary style. The project is cross-platform and the binaries compile fine on macOS, unless some features from "above the BSD" layer are needed.

Right now, the only solution I could work out is to setup alias rules of the following sort:

alias(
	name = "some-app",
	actual = select({
		"//:macos": ":some-app-apple",
		"//conditions:default": ":some-app-generic",
	}),
)

Which is a major pain, because for each affected app I now need 3 extra targets: the usual "unix like" cc_binary and then objc_library, macos_command_line_application and alias targets for macOS specifically.

Yet, it seems that normal cc_binary could work on macOS as is with some output prefix or linker command line tweaking.

oakad avatar May 17 '22 02:05 oakad

Yea I think there's a bug in the combination between propagating CcInfo and ObjC info leading to duplicates. If you can create a repro case I can debug futher. Note that ObjC info is going away in bazel, hopefully soon, in which case this likely wouldn't be a problem anymore

keith avatar May 17 '22 17:05 keith

https://github.com/oakad/rules_apple_issue_1474

I have created this simple repro. I could not make it to actually fail the link (for whatever reason). However, if you look at bazel-out/darwin-dbg/bin/t2-2.params after building the t2 target, you will see the duplication in linker deps.

Seemingly, most of the times linker is happy to resolve in order and doesn't care that there's a duplication. However, it is clearly wrong to to it like that and in a more complicated project the issue triggers.

oakad avatar May 18 '22 10:05 oakad

Just ran into this bug as well. Here is a reproducible simple example: https://github.com/olarozenfeld/botc/commit/a7ed90611745f184cfaee9b2285bbafa8e2e09e0

To repro, run bazel build //src/bazel_link_bug_example:foo

In this case, I try to define the Bar function inline in the header foo.h, and it fails to link the main. But it really shouldn't. For example, if we change the build rule for foo from cc_binary to cc_test, then the link works just fine.

olarozenfeld avatar May 24 '22 01:05 olarozenfeld

Somewhat later I found out that alwayslink = 1 in my bigger project is the immediate culprit. Which makes all the sense.

oakad avatar May 24 '22 01:05 oakad

@olarozenfeld I think your case is a bit different, you're not pulling in rules_apple at all, just a cc_library + cc_binary, it looks to me like the core of your issue is that you're getting the Bar symbol in both translation units which I suppose violates ODR, so that's likely your core issue.

@oakad using your repro case I don't actually see what you mean, my link params file contains:

-lc++
-fobjc-link-runtime
-Wl,-S
-o
bazel-out/darwin_arm64-fastbuild/bin/t2
bazel-out/darwin_arm64-fastbuild/bin/_objs/t2/t2.o
-Wl,-force_load,bazel-out/darwin_arm64-fastbuild/bin/libt1-cc.lo
bazel-out/darwin_arm64-fastbuild/bin/libt1-objc.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/strings/libstr_format_internal.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/types/libbad_optional_access.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/strings/libstrings.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/strings/libinternal.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/base/libbase.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/base/libspinlock_wait.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/base/libthrow_delegate.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/base/libraw_logging_internal.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/base/liblog_severity.a
bazel-out/darwin_arm64-fastbuild/bin/external/com_google_absl/absl/numeric/libint128.a
-headerpad_max_install_names
-pthread
-no-canonical-prefixes
-target
arm64-apple-macosx12.3
-lc++
-target
arm64-apple-macosx12.3

can you clarify? it might be a bazel version issue, I was testing with 5.2 which is the newest release atm

keith avatar Jun 08 '22 00:06 keith

That's what it looks like on my side, Bazel-5.1.1-homebrew:

% cat t2-2.params -lc++ -fobjc-link-runtime -o bazel-out/darwin-dbg/bin/t2 bazel-out/darwin-dbg/bin/_objs/t2/t2.o -Wl,-force_load,bazel-out/darwin-dbg/bin/libt1-cc.lo bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/libt1-objc.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/strings/libstr_format_internal.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/types/libbad_optional_access.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/strings/libstrings.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/strings/libinternal.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/base/libbase.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/base/libspinlock_wait.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/base/libthrow_delegate.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/base/libraw_logging_internal.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/base/liblog_severity.a bazel-out/applebin_macos-darwin_x86_64-dbg-ST-cd2b3b8d4835/bin/external/com_google_absl/absl/numeric/libint128.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/strings/libstr_format_internal.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/strings/libstrings.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/strings/libinternal.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/base/libbase.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/base/libspinlock_wait.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/numeric/libint128.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/types/libbad_optional_access.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/base/libthrow_delegate.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/base/libraw_logging_internal.a bazel-out/darwin-dbg/bin/external/com_google_absl/absl/base/liblog_severity.a -headerpad_max_install_names -pthread -no-canonical-prefixes -target x86_64-apple-macosx -mmacosx-version-min=12.3 -lc++ -target x86_64-apple-macosx

oakad avatar Jun 08 '22 05:06 oakad

Does a newer version of bazel or rules_apple fix the issue? 🤔

keith avatar Jun 08 '22 17:06 keith

Bazel: 5.2.0-homebrew rules-apple: 0.34.2 (I updated the test repo)

Exactly the same outcome: libs are added twice with both applebin_macos-darwin_x86_64-fastbuild-ST-cd2b3b8d4835 and darwin-fastbuild directory prefixes.

oakad avatar Jun 09 '22 08:06 oakad

Is there any news on this? seems to still persist

Evizero avatar Apr 27 '23 13:04 Evizero

hi, any investigation on this? I'm facing the same issue as well. And its very frustrated when my project is very large, and it takes a lot of time to confirm that the modification can work or not. But finally, I cannot find a solution after wasting 2weeks of investigation. please help!! cc: @keith

sepcon avatar Jul 28 '23 04:07 sepcon

a repro case would be helpful

keith avatar Aug 10 '23 16:08 keith