blob: cbd44475576a9a65ddd0cc873879a69dce7569bc [file] [log] [blame]
Brian Silverman8dd8a052018-09-02 17:08:31 -07001load("@//tools/build_rules:select.bzl", "compiler_select")
Brian Silvermand3ad1652018-02-18 22:16:29 -05002
Austin Schuh1f9aeb42015-11-12 23:34:49 -08003def _single_fortran_object_impl(ctx):
4 toolchain_cflags = (ctx.fragments.cpp.compiler_options([]) +
5 ctx.fragments.cpp.c_options +
Austin Schuh3b3fee02015-11-26 17:26:32 -08006 ctx.fragments.cpp.unfiltered_compiler_options([]) +
7 ['-fPIC', '-Wno-maybe-uninitialized', '-Wno-unused-dummy-argument',
Austin Schuh2461e5e2015-11-28 13:23:45 -08008 '-Wno-conversion', '-Wno-unused-variable', '-Wno-character-truncation'])
Austin Schuh1f9aeb42015-11-12 23:34:49 -08009
10 cmd = toolchain_cflags + ['-c', ctx.file.src.path, '-o', ctx.outputs.pic_o.path]
11 filtered_cmd = []
Brian Silvermana4a4ea62015-11-27 10:27:53 -050012 # Strip out the C/C++/Clang specific flags.
Austin Schuh1f9aeb42015-11-12 23:34:49 -080013 exclude_flags = ['-fcolor-diagnostics',
14 '-Wswitch-enum',
15 '-Wpointer-arith',
16 '-Wcast-qual',
17 '-Wwrite-strings',
18 '-Wsign-compare',
19 '-Wformat=2',
20 '-Werror',
Austin Schuh3b3fee02015-11-26 17:26:32 -080021 '-Wextra',
Austin Schuh1f9aeb42015-11-12 23:34:49 -080022 '-Wno-builtin-macro-redefined',
Austin Schuhc65df862015-12-27 14:04:49 -080023 '-Wunused-local-typedefs',
Brian Silvermana4a4ea62015-11-27 10:27:53 -050024 '-D__has_feature(x)=0',
25 '-fmacro-backtrace-limit=0']
Austin Schuh1f9aeb42015-11-12 23:34:49 -080026
27 for flag in cmd:
Brian Silvermaned79de62015-11-28 18:10:17 -050028 if flag not in exclude_flags and not (flag.startswith('-fsanitize') or
29 flag.startswith('-fno-sanitize')):
Austin Schuh1f9aeb42015-11-12 23:34:49 -080030 filtered_cmd.append(flag)
31
32 ctx.action(
Brian Silvermanb2215d02015-11-23 19:10:15 -050033 inputs = [ctx.file.src] + ctx.files._cc_toolchain,
Austin Schuh1f9aeb42015-11-12 23:34:49 -080034 outputs = [ctx.outputs.pic_o],
35 mnemonic = "Fortran",
36 executable = ctx.fragments.cpp.compiler_executable,
37 arguments = filtered_cmd,
38 progress_message = 'Building %s' % ctx.outputs.pic_o.short_path,
39 )
40
Brian Silvermanb200c172017-01-02 17:35:35 -080041def _define_fortran_output(src):
42 if not src.name.endswith('.f'):
Austin Schuh1f9aeb42015-11-12 23:34:49 -080043 fail('Fortran files must end in \'.f\'', 'src')
44
Brian Silvermanb200c172017-01-02 17:35:35 -080045 fortran_file_base = src.name[:-2]
Austin Schuh1f9aeb42015-11-12 23:34:49 -080046 return {
47 'pic_o': fortran_file_base + '.pic.o',
48 }
49
Austin Schuh1f9aeb42015-11-12 23:34:49 -080050_single_fortran_object = rule(
Brian Silverman8dd8a052018-09-02 17:08:31 -070051 attrs = {
52 "src": attr.label(
53 single_file = True,
54 allow_files = FileType([".f"]),
55 ),
56 "cc_libs": attr.label_list(providers = ["cc"]),
57 # TODO(Brian): Replace this with something more fine-grained from the
58 # configuration fragment or something.
59 "_cc_toolchain": attr.label(
60 default = Label("@//tools/cpp:toolchain"),
61 ),
62 },
63 fragments = [
64 "cpp",
65 ],
66 outputs = _define_fortran_output,
67 implementation = _single_fortran_object_impl,
Austin Schuh1f9aeb42015-11-12 23:34:49 -080068)
69
70def fortran_library(name, srcs, deps = [], visibility = None):
71 """Builds a shared library from a set of fortran files.
72
73 Args:
74 srcs: list of fortran files ending in .f
75 deps: cc_library or fortran_library dependencies.
76 """
77 pic_o_files = []
78 for src in srcs:
79 pic_o_file = src[:-2] + '.pic.o'
Brian Silvermanb2215d02015-11-23 19:10:15 -050080 _single_fortran_object(
81 name = name + '_' + pic_o_file,
82 src = src,
83 visibility = ['//visibility:private'],
Austin Schuh9d92e6b2017-10-17 01:19:38 -070084 restricted_to = ['@//tools:k8'],
Brian Silvermanb2215d02015-11-23 19:10:15 -050085 )
Austin Schuh1f9aeb42015-11-12 23:34:49 -080086 pic_o_files.append(pic_o_file)
87
88 native.cc_library(
89 name = name,
90 deps = deps,
91 srcs = pic_o_files,
92 linkopts = [
93 '-lgfortran',
94 ],
95 visibility = visibility,
Austin Schuh9d92e6b2017-10-17 01:19:38 -070096 restricted_to = ['@//tools:k8'],
Austin Schuh1f9aeb42015-11-12 23:34:49 -080097 )
Brian Silvermand3ad1652018-02-18 22:16:29 -050098
99f2c_copts = compiler_select({
Brian Silverman8dd8a052018-09-02 17:08:31 -0700100 "clang": [
101 "-Wno-incompatible-pointer-types-discards-qualifiers",
102 # Clang appears to be a bit over-eager about this and the comma operator.
103 "-Wno-sometimes-uninitialized",
104 ],
105 "gcc": [
106 # TODO(Brian): Remove this once we can actually disable all the warnings.
107 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43245 isn't fixed in our
108 # roborio toolchain yet, so we can't for now.
109 "-Wno-error",
110 ],
Brian Silvermand3ad1652018-02-18 22:16:29 -0500111}) + [
Brian Silverman8dd8a052018-09-02 17:08:31 -0700112 # f2c appears to know what it's doing without adding extra ().
113 "-Wno-parentheses",
114 "-Wno-unused-parameter",
115 "-Wno-missing-field-initializers",
116 "-Wno-unused-variable",
Brian Silvermand3ad1652018-02-18 22:16:29 -0500117]
Brian Silvermand3ad1652018-02-18 22:16:29 -0500118
Brian Silverman8dd8a052018-09-02 17:08:31 -0700119"""Copts to use when compiling f2c-generated files.
120
121This is useful when building externally-f2ced files."""
Brian Silvermand3ad1652018-02-18 22:16:29 -0500122
123def f2c_library(name, srcs, copts = [], **kwargs):
124 '''Converts Fortran code to C and then compiles it.
125
126 Attrs:
127 srcs: .f source files
128 **kwargs: passed to native.cc_library
129 '''
130 c_srcs = [f[:-2] + '.c' for f in srcs]
131
132 out_dir = c_srcs[0].split('/')[:-1]
133 for c_src in c_srcs:
134 if c_src.split('/')[:-1] != out_dir:
135 # Need to figure out how to make multiple f2c calls or something to
136 # support this, and we haven't had a use case yet.
137 fail('Multiple output directories not supported', 'srcs')
138
139 native.genrule(
140 name = '_%s_f2c' % name,
141 visibility = ['//visibility:private'],
142 srcs = srcs,
143 outs = c_srcs,
144 tools = [
145 '@f2c',
Brian Silverman8dd8a052018-09-02 17:08:31 -0700146 '@//tools/build_rules:quiet_success',
Brian Silvermand3ad1652018-02-18 22:16:29 -0500147 ],
Brian Silverman8dd8a052018-09-02 17:08:31 -0700148 cmd = ' '.join([
149 '$(location @//tools/build_rules:quiet_success)',
150 '$(location @f2c)',
151 '-d$(@D)/%s' % ('/'.join(out_dir),),
152 '$(SRCS)',
153 ]),
Brian Silvermand3ad1652018-02-18 22:16:29 -0500154 )
155 native.cc_library(
156 name = name,
157 srcs = c_srcs,
158 copts = f2c_copts + copts,
159 **kwargs
160 )