build - Bazel : handle intermediate files in ctx.action -
i trying implement custom c_library()
rule in bazel takes bunch of .c
files input , produces .a
static library. in implementation, .c
files generate .o
objects , archives .a
library. seems .o
files not getting generated. here custom c_library()
rule (rules.bzl
file):
def _change_ext_to_x( file_list, x = 'o' ): # inputs file list (i.e. string list) # , changes extensions '.{x}' return [ "".join( onefile.split('.')[:-1] ) + '.' + x \ onefile in file_list ] def _str_to_file( ctx, file_list ): # constructor of file() object # pass context return [ ctx.new_file( onefile ) onefile in file_list ] def _c_library_impl( ctx ): # implementation of 'c_library' rule # source files list ( strings ) in_file_list = [] onefile in ctx.files.srcs: in_file_list.append( onefile.basename ) out_file_list = _str_to_file( ctx, # current context _change_ext_to_x(in_file_list, x = 'o') ) ctx.action( inputs = ctx.files.srcs, outputs = out_file_list, progress_message = "compiling <.c> <.o>", use_default_shell_env = true, command = "gcc -c -o3 %s" % " ".join( in_file_list ) ) ctx.action( inputs = out_file_list, outputs = [ ctx.outputs._libfile ], progress_message = "archiving <.o>s <.a>", use_default_shell_env = true, arguments = [ctx.outputs._libfile.basename], command = "ar cr $1 %s" % " ".join( [onefile.basename onefile in out_file_list] ) ) pass c_library = rule( # define rule 'c' library implementation = _c_library_impl, attrs = { "srcs" : attr.label_list( allow_files = true, mandatory = true, allow_empty = false ), "out" : attr.output( mandatory = false ) }, outputs = { "_libfile" : "lib%{name}.a" } )
and here build
file:
load("//:rules.bzl", "c_library") c_library( name = "foo", srcs = glob(include = ["*.c"], exclude = ["main.c"]) # there 2 files 'cmd.c' , 'utils.c' in package )
when did bazel build //:foo
, got following error:
info: found 1 target... error: /home/spyder/desktop/project/build:3:1: output 'cmd.o' not created. error: /home/spyder/desktop/project/build:3:1: output 'utils.o' not created. error: /home/spyder/desktop/project/build:3:1: not outputs created or valid. target //:foo failed build use --verbose_failures see command lines of failed build steps. info: elapsed time: 2.249s, critical path: 1.94s
how persist intermediate files between 2 successive ctx.action
s ?
you should create 1 action per .c file instead of 1 action of them, increase parallelism, , specified output:
def _c_library_impl( ctx ): # implementation of 'c_library' rule out_file_list = [] f in ctx.files.srcs: o = ctx.new_file(f.basename + ".o") out_file_list.append(o) ctx.action( inputs = [f], outputs = [o], progress_message = "compiling <.c> <.o>", use_default_shell_env = true, command = "gcc -c -o3 %s %s" % (f.path, o.path) ) ctx.action( inputs = out_file_list, outputs = [ ctx.outputs._libfile ], progress_message = "archiving <.o>s <.a>", use_default_shell_env = true, command = "ar cr %s %s" % (ctx.outputs._libfile.path, "\n".join([onefile.basename onefile in out_file_list] ) )
Comments
Post a Comment