@@ -161,10 +161,9 @@ def _is_compiler_option_supported(repository_ctx, cc, option):
161161 ])
162162 return result .stderr .find (option ) == - 1
163163
164- def _is_linker_option_supported (repository_ctx , cc , option , pattern ):
164+ def _is_linker_option_supported (repository_ctx , cc , force_linker_flags , option , pattern ):
165165 """Checks that `option` is supported by the C linker. Doesn't %-escape the option."""
166- result = repository_ctx .execute ([
167- cc ,
166+ result = repository_ctx .execute ([cc ] + force_linker_flags + [
168167 option ,
169168 "-o" ,
170169 "/dev/null" ,
@@ -213,9 +212,9 @@ def _add_compiler_option_if_supported(repository_ctx, cc, option):
213212 """Returns `[option]` if supported, `[]` otherwise. Doesn't %-escape the option."""
214213 return [option ] if _is_compiler_option_supported (repository_ctx , cc , option ) else []
215214
216- def _add_linker_option_if_supported (repository_ctx , cc , option , pattern ):
215+ def _add_linker_option_if_supported (repository_ctx , cc , force_linker_flags , option , pattern ):
217216 """Returns `[option]` if supported, `[]` otherwise. Doesn't %-escape the option."""
218- return [option ] if _is_linker_option_supported (repository_ctx , cc , option , pattern ) else []
217+ return [option ] if _is_linker_option_supported (repository_ctx , cc , force_linker_flags , option , pattern ) else []
219218
220219def _get_no_canonical_prefixes_opt (repository_ctx , cc ):
221220 # If the compiler sometimes rewrites paths in the .d files without symlinks
@@ -420,16 +419,40 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
420419 False ,
421420 ), ":" )
422421
422+ gold_or_lld_linker_path = (
423+ _find_linker_path (repository_ctx , cc , "lld" , is_clang ) or
424+ _find_linker_path (repository_ctx , cc , "gold" , is_clang )
425+ )
426+ cc_path = repository_ctx .path (cc )
427+ if not str (cc_path ).startswith (str (repository_ctx .path ("." )) + "/" ):
428+ # cc is outside the repository, set -B
429+ bin_search_flags = ["-B" + escape_string (str (cc_path .dirname ))]
430+ else :
431+ # cc is inside the repository, don't set -B.
432+ bin_search_flags = []
433+ if not gold_or_lld_linker_path :
434+ ld_path = repository_ctx .path (tool_paths ["ld" ])
435+ if ld_path .dirname != cc_path .dirname :
436+ bin_search_flags .append ("-B" + str (ld_path .dirname ))
437+ force_linker_flags = []
438+ if gold_or_lld_linker_path :
439+ force_linker_flags .append ("-fuse-ld=" + gold_or_lld_linker_path )
440+
441+ # TODO: It's unclear why these flags aren't added on macOS.
442+ if bin_search_flags and not darwin :
443+ force_linker_flags .extend (bin_search_flags )
423444 use_libcpp = darwin or bsd
424445 is_as_needed_supported = _is_linker_option_supported (
425446 repository_ctx ,
426447 cc ,
448+ force_linker_flags ,
427449 "-Wl,-no-as-needed" ,
428450 "-no-as-needed" ,
429451 )
430452 is_push_state_supported = _is_linker_option_supported (
431453 repository_ctx ,
432454 cc ,
455+ force_linker_flags ,
433456 "-Wl,--push-state" ,
434457 "--push-state" ,
435458 )
@@ -463,21 +486,6 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
463486 bazel_linklibs ,
464487 False ,
465488 ), ":" )
466- gold_or_lld_linker_path = (
467- _find_linker_path (repository_ctx , cc , "lld" , is_clang ) or
468- _find_linker_path (repository_ctx , cc , "gold" , is_clang )
469- )
470- cc_path = repository_ctx .path (cc )
471- if not str (cc_path ).startswith (str (repository_ctx .path ("." )) + "/" ):
472- # cc is outside the repository, set -B
473- bin_search_flags = ["-B" + escape_string (str (cc_path .dirname ))]
474- else :
475- # cc is inside the repository, don't set -B.
476- bin_search_flags = []
477- if not gold_or_lld_linker_path :
478- ld_path = repository_ctx .path (tool_paths ["ld" ])
479- if ld_path .dirname != cc_path .dirname :
480- bin_search_flags .append ("-B" + str (ld_path .dirname ))
481489 coverage_compile_flags , coverage_link_flags = _coverage_flags (repository_ctx , darwin )
482490 print_resource_dir_supported = _is_compiler_option_supported (
483491 repository_ctx ,
@@ -610,19 +618,18 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
610618 ),
611619 "%{cxx_flags}" : get_starlark_list (cxx_opts + _escaped_cplus_include_paths (repository_ctx )),
612620 "%{conly_flags}" : get_starlark_list (conly_opts ),
613- "%{link_flags}" : get_starlark_list ((
614- ["-fuse-ld=" + gold_or_lld_linker_path ] if gold_or_lld_linker_path else []
615- ) + (
621+ "%{link_flags}" : get_starlark_list (force_linker_flags + (
616622 ["-Wl,-no-as-needed" ] if is_as_needed_supported else []
617623 ) + _add_linker_option_if_supported (
618624 repository_ctx ,
619625 cc ,
626+ force_linker_flags ,
620627 "-Wl,-z,relro,-z,now" ,
621628 "-z" ,
622629 ) + (
623630 [
624631 "-headerpad_max_install_names" ,
625- ] if darwin else bin_search_flags + [
632+ ] if darwin else [
626633 # Gold linker only? Can we enable this by default?
627634 # "-Wl,--warn-execstack",
628635 # "-Wl,--detect-odr-violations"
@@ -664,6 +671,7 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools):
664671 ["-Wl,-dead_strip" ] if darwin else _add_linker_option_if_supported (
665672 repository_ctx ,
666673 cc ,
674+ force_linker_flags ,
667675 "-Wl,--gc-sections" ,
668676 "-gc-sections" ,
669677 ),
0 commit comments