blob: 22882acecf1bddbf9737dba9b31fb739c413a1b4 [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):
Austin Schuh8e17be92019-12-24 09:32:11 -08004 toolchain_cflags = (ctx.fragments.cpp.compiler_options([]) +
5 ctx.fragments.cpp.c_options +
6 ctx.fragments.cpp.unfiltered_compiler_options([]) +
7 [
8 "-fPIC",
9 "-Wno-maybe-uninitialized",
10 "-Wno-unused-dummy-argument",
11 "-Wno-conversion",
12 "-Wno-unused-variable",
13 "-Wno-character-truncation",
14 ])
Austin Schuh1f9aeb42015-11-12 23:34:49 -080015
Austin Schuh8e17be92019-12-24 09:32:11 -080016 cmd = toolchain_cflags + ["-c", ctx.file.src.path, "-o", ctx.outputs.pic_o.path]
17 filtered_cmd = []
Austin Schuh1f9aeb42015-11-12 23:34:49 -080018
Austin Schuh8e17be92019-12-24 09:32:11 -080019 # Strip out the C/C++/Clang specific flags.
20 exclude_flags = [
21 "-fcolor-diagnostics",
22 "-Wswitch-enum",
23 "-Wpointer-arith",
24 "-Wcast-qual",
25 "-Wwrite-strings",
26 "-Wsign-compare",
27 "-Wformat=2",
28 "-Werror",
29 "-Wextra",
30 "-Wno-builtin-macro-redefined",
31 "-Wunused-local-typedefs",
32 "-D__has_feature(x)=0",
33 "-fmacro-backtrace-limit=0",
34 ]
Austin Schuh1f9aeb42015-11-12 23:34:49 -080035
Austin Schuh8e17be92019-12-24 09:32:11 -080036 for flag in cmd:
37 if flag not in exclude_flags and not (flag.startswith("-fsanitize") or
38 flag.startswith("-fno-sanitize")):
39 filtered_cmd.append(flag)
40
41 ctx.action(
42 inputs = [ctx.file.src] + ctx.files._cc_toolchain,
43 outputs = [ctx.outputs.pic_o],
44 mnemonic = "Fortran",
45 executable = ctx.fragments.cpp.compiler_executable,
46 arguments = filtered_cmd,
47 progress_message = "Building %s" % ctx.outputs.pic_o.short_path,
48 )
Austin Schuh1f9aeb42015-11-12 23:34:49 -080049
Brian Silvermanb200c172017-01-02 17:35:35 -080050def _define_fortran_output(src):
Austin Schuh8e17be92019-12-24 09:32:11 -080051 if not src.name.endswith(".f"):
52 fail("Fortran files must end in '.f'", "src")
Austin Schuh1f9aeb42015-11-12 23:34:49 -080053
Austin Schuh8e17be92019-12-24 09:32:11 -080054 fortran_file_base = src.name[:-2]
55 return {
56 "pic_o": fortran_file_base + ".pic.o",
57 }
Austin Schuh1f9aeb42015-11-12 23:34:49 -080058
Austin Schuh1f9aeb42015-11-12 23:34:49 -080059_single_fortran_object = rule(
Brian Silverman8dd8a052018-09-02 17:08:31 -070060 attrs = {
61 "src": attr.label(
62 single_file = True,
63 allow_files = FileType([".f"]),
64 ),
65 "cc_libs": attr.label_list(providers = ["cc"]),
66 # TODO(Brian): Replace this with something more fine-grained from the
67 # configuration fragment or something.
68 "_cc_toolchain": attr.label(
69 default = Label("@//tools/cpp:toolchain"),
70 ),
71 },
72 fragments = [
73 "cpp",
74 ],
75 outputs = _define_fortran_output,
76 implementation = _single_fortran_object_impl,
Austin Schuh1f9aeb42015-11-12 23:34:49 -080077)
78
79def fortran_library(name, srcs, deps = [], visibility = None):
Austin Schuh8e17be92019-12-24 09:32:11 -080080 """Builds a shared library from a set of fortran files.
Austin Schuh1f9aeb42015-11-12 23:34:49 -080081
Austin Schuh8e17be92019-12-24 09:32:11 -080082 Args:
83 srcs: list of fortran files ending in .f
84 deps: cc_library or fortran_library dependencies.
85 """
86 pic_o_files = []
87 for src in srcs:
88 pic_o_file = src[:-2] + ".pic.o"
89 _single_fortran_object(
90 name = name + "_" + pic_o_file,
91 src = src,
92 visibility = ["//visibility:private"],
93 restricted_to = ["@//tools:k8"],
94 )
95 pic_o_files.append(pic_o_file)
96
97 native.cc_library(
98 name = name,
99 deps = deps,
100 srcs = pic_o_files,
101 linkopts = [
102 "-lgfortran",
103 ],
104 visibility = visibility,
105 restricted_to = ["@//tools:k8"],
Brian Silvermanb2215d02015-11-23 19:10:15 -0500106 )
Brian Silvermand3ad1652018-02-18 22:16:29 -0500107
108f2c_copts = compiler_select({
Brian Silverman8dd8a052018-09-02 17:08:31 -0700109 "clang": [
110 "-Wno-incompatible-pointer-types-discards-qualifiers",
111 # Clang appears to be a bit over-eager about this and the comma operator.
112 "-Wno-sometimes-uninitialized",
113 ],
114 "gcc": [
115 # TODO(Brian): Remove this once we can actually disable all the warnings.
116 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43245 isn't fixed in our
117 # roborio toolchain yet, so we can't for now.
118 "-Wno-error",
119 ],
Brian Silvermand3ad1652018-02-18 22:16:29 -0500120}) + [
Brian Silverman8dd8a052018-09-02 17:08:31 -0700121 # f2c appears to know what it's doing without adding extra ().
122 "-Wno-parentheses",
123 "-Wno-unused-parameter",
124 "-Wno-missing-field-initializers",
125 "-Wno-unused-variable",
Brian Silvermand3ad1652018-02-18 22:16:29 -0500126]
Brian Silvermand3ad1652018-02-18 22:16:29 -0500127
Brian Silverman8dd8a052018-09-02 17:08:31 -0700128"""Copts to use when compiling f2c-generated files.
129
130This is useful when building externally-f2ced files."""
Brian Silvermand3ad1652018-02-18 22:16:29 -0500131
132def f2c_library(name, srcs, copts = [], **kwargs):
Austin Schuh8e17be92019-12-24 09:32:11 -0800133 """Converts Fortran code to C and then compiles it.
Brian Silvermand3ad1652018-02-18 22:16:29 -0500134
Austin Schuh8e17be92019-12-24 09:32:11 -0800135 Attrs:
136 srcs: .f source files
137 **kwargs: passed to native.cc_library
138 """
139 c_srcs = [f[:-2] + ".c" for f in srcs]
Brian Silvermand3ad1652018-02-18 22:16:29 -0500140
Austin Schuh8e17be92019-12-24 09:32:11 -0800141 out_dir = c_srcs[0].split("/")[:-1]
142 for c_src in c_srcs:
143 if c_src.split("/")[:-1] != out_dir:
144 # Need to figure out how to make multiple f2c calls or something to
145 # support this, and we haven't had a use case yet.
146 fail("Multiple output directories not supported", "srcs")
Brian Silvermand3ad1652018-02-18 22:16:29 -0500147
Austin Schuh8e17be92019-12-24 09:32:11 -0800148 native.genrule(
149 name = "_%s_f2c" % name,
150 visibility = ["//visibility:private"],
151 srcs = srcs,
152 outs = c_srcs,
153 tools = [
154 "@f2c",
155 "@//tools/build_rules:quiet_success",
156 ],
157 cmd = " ".join([
158 "$(location @//tools/build_rules:quiet_success)",
159 "$(location @f2c)",
160 "-d$(@D)/%s" % ("/".join(out_dir),),
161 "$(SRCS)",
162 ]),
163 )
164 native.cc_library(
165 name = name,
166 srcs = c_srcs,
167 copts = f2c_copts + copts,
168 **kwargs
169 )