@@ -5,6 +5,7 @@ load("@bazel_skylib//lib:dicts.bzl", "dicts")
55load ("@bazel_skylib//lib:paths.bzl" , "paths" )
66load ("@rules_cc//cc/common:cc_info.bzl" , "CcInfo" )
77load ("//d/private:providers.bzl" , "DInfo" )
8+ load ("//d/private/rules:cc_toolchain.bzl" , "find_cc_toolchain_for_linking" )
89
910D_FILE_EXTENSIONS = [".d" , ".di" ]
1011
@@ -37,6 +38,10 @@ runnable_attrs = dicts.add(
3738 {
3839 "env" : attr .string_dict (doc = "Environment variables for the binary at runtime. Subject of location and make variable expansion." ),
3940 "data" : attr .label_list (allow_files = True , doc = "List of files to be made available at runtime." ),
41+ "_cc_toolchain" : attr .label (
42+ default = "@rules_cc//cc:current_cc_toolchain" ,
43+ doc = "Default CC toolchain, used for linking. Remove after https://github.com/bazelbuild/bazel/issues/7260 is flipped (and support for old Bazel version is not needed)" ,
44+ ),
4045 },
4146)
4247
@@ -142,6 +147,8 @@ def compilation_action(ctx, target_type = TARGET_TYPE.LIBRARY):
142147 args .add_all (toolchain .linker_flags )
143148 args .add_all (linker_flags .to_list (), format_each = "-L=%s" )
144149 output = None
150+ cc_toolchain = None
151+ env = ctx .var
145152 if target_type in [TARGET_TYPE .BINARY , TARGET_TYPE .TEST ]:
146153 for dep in d_deps :
147154 args .add_all (dep .libraries )
@@ -150,6 +157,23 @@ def compilation_action(ctx, target_type = TARGET_TYPE.LIBRARY):
150157 args .add_all (["-main" , "-unittest" ])
151158 output = ctx .actions .declare_file (_binary_name (ctx , ctx .label .name ))
152159 args .add (output , format = "-of=%s" )
160+ cc_linker_info = find_cc_toolchain_for_linking (ctx )
161+ env = dict (cc_linker_info .env )
162+ env .update ({
163+ "CC" : cc_linker_info .cc_compiler , # Have to use the env variable here, since DMD doesn't support -gcc= flag
164+ # Ok, this is a bit weird. Local toolchain from rules_cc works fine if we don't set PATH here.
165+ # But doesn't work if we set it to an empty string.
166+ # OTOH the toolchain from toolchains_llvm doesn't work without setting PATH here. (Can't find the linker executable)
167+ # Even though the cc_wrapper script adds "/usr/bin" to the PATH variable,
168+ # it only works if the PATH is already in the environment. (I think they have to `export`)
169+ # So toolchains_llvm works if we set PATH to "" but doesn't work if we don't set it at all.
170+ # So, to get to a common ground, we set PATH to something generic.
171+ "PATH" : "/bin:/usr/bin:/usr/local/bin" ,
172+ })
173+ if _get_os (ctx ) != "windows" :
174+ # DMD doesn't support -Xcc on Windows
175+ args .add_all (cc_linker_info .cc_linking_options , format_each = "-Xcc=%s" )
176+ cc_toolchain = cc_linker_info .cc_toolchain
153177 elif target_type == TARGET_TYPE .LIBRARY :
154178 args .add ("-lib" )
155179 output = ctx .actions .declare_file (_static_library_name (ctx , ctx .label .name ))
@@ -169,11 +193,12 @@ def compilation_action(ctx, target_type = TARGET_TYPE.LIBRARY):
169193
170194 ctx .actions .run (
171195 inputs = inputs ,
196+ tools = [cc_toolchain .all_files ] if cc_toolchain else [],
172197 outputs = [output ],
173198 executable = toolchain .d_compiler [DefaultInfo ].files_to_run ,
174199 arguments = [args ],
175- env = ctx . var ,
176- use_default_shell_env = target_type != TARGET_TYPE . LIBRARY , # True to make the linker work properly
200+ env = env ,
201+ use_default_shell_env = False ,
177202 mnemonic = "Dcompile" ,
178203 progress_message = "Compiling D %s %s" % (target_type , ctx .label .name ),
179204 )
0 commit comments