blob: 9e6e789276a7949b96924ebece8fdfffd496acf2 [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(
Philipp Schrader5dd9eda2020-11-08 10:16:35 -080062 allow_single_file = [".f"],
Brian Silverman8dd8a052018-09-02 17:08:31 -070063 ),
64 "cc_libs": attr.label_list(providers = ["cc"]),
65 # TODO(Brian): Replace this with something more fine-grained from the
66 # configuration fragment or something.
67 "_cc_toolchain": attr.label(
68 default = Label("@//tools/cpp:toolchain"),
69 ),
70 },
71 fragments = [
72 "cpp",
73 ],
74 outputs = _define_fortran_output,
75 implementation = _single_fortran_object_impl,
Austin Schuh1f9aeb42015-11-12 23:34:49 -080076)
77
78def fortran_library(name, srcs, deps = [], visibility = None):
Austin Schuh8e17be92019-12-24 09:32:11 -080079 """Builds a shared library from a set of fortran files.
Austin Schuh1f9aeb42015-11-12 23:34:49 -080080
Austin Schuh8e17be92019-12-24 09:32:11 -080081 Args:
82 srcs: list of fortran files ending in .f
83 deps: cc_library or fortran_library dependencies.
84 """
85 pic_o_files = []
86 for src in srcs:
87 pic_o_file = src[:-2] + ".pic.o"
88 _single_fortran_object(
89 name = name + "_" + pic_o_file,
90 src = src,
91 visibility = ["//visibility:private"],
92 restricted_to = ["@//tools:k8"],
93 )
94 pic_o_files.append(pic_o_file)
95
96 native.cc_library(
97 name = name,
98 deps = deps,
99 srcs = pic_o_files,
100 linkopts = [
101 "-lgfortran",
102 ],
103 visibility = visibility,
104 restricted_to = ["@//tools:k8"],
Brian Silvermanb2215d02015-11-23 19:10:15 -0500105 )
Brian Silvermand3ad1652018-02-18 22:16:29 -0500106
107f2c_copts = compiler_select({
Brian Silverman8dd8a052018-09-02 17:08:31 -0700108 "clang": [
109 "-Wno-incompatible-pointer-types-discards-qualifiers",
110 # Clang appears to be a bit over-eager about this and the comma operator.
111 "-Wno-sometimes-uninitialized",
112 ],
113 "gcc": [
114 # TODO(Brian): Remove this once we can actually disable all the warnings.
115 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43245 isn't fixed in our
116 # roborio toolchain yet, so we can't for now.
117 "-Wno-error",
118 ],
Brian Silvermand3ad1652018-02-18 22:16:29 -0500119}) + [
Brian Silverman8dd8a052018-09-02 17:08:31 -0700120 # f2c appears to know what it's doing without adding extra ().
121 "-Wno-parentheses",
122 "-Wno-unused-parameter",
123 "-Wno-missing-field-initializers",
124 "-Wno-unused-variable",
Brian Silvermand3ad1652018-02-18 22:16:29 -0500125]
Brian Silvermand3ad1652018-02-18 22:16:29 -0500126
Brian Silverman8dd8a052018-09-02 17:08:31 -0700127"""Copts to use when compiling f2c-generated files.
128
129This is useful when building externally-f2ced files."""
Brian Silvermand3ad1652018-02-18 22:16:29 -0500130
131def f2c_library(name, srcs, copts = [], **kwargs):
Austin Schuh8e17be92019-12-24 09:32:11 -0800132 """Converts Fortran code to C and then compiles it.
Brian Silvermand3ad1652018-02-18 22:16:29 -0500133
Austin Schuh8e17be92019-12-24 09:32:11 -0800134 Attrs:
135 srcs: .f source files
136 **kwargs: passed to native.cc_library
137 """
138 c_srcs = [f[:-2] + ".c" for f in srcs]
Brian Silvermand3ad1652018-02-18 22:16:29 -0500139
Austin Schuh8e17be92019-12-24 09:32:11 -0800140 out_dir = c_srcs[0].split("/")[:-1]
141 for c_src in c_srcs:
142 if c_src.split("/")[:-1] != out_dir:
143 # Need to figure out how to make multiple f2c calls or something to
144 # support this, and we haven't had a use case yet.
145 fail("Multiple output directories not supported", "srcs")
Brian Silvermand3ad1652018-02-18 22:16:29 -0500146
Austin Schuh8e17be92019-12-24 09:32:11 -0800147 native.genrule(
148 name = "_%s_f2c" % name,
149 visibility = ["//visibility:private"],
150 srcs = srcs,
151 outs = c_srcs,
152 tools = [
153 "@f2c",
154 "@//tools/build_rules:quiet_success",
155 ],
156 cmd = " ".join([
157 "$(location @//tools/build_rules:quiet_success)",
158 "$(location @f2c)",
159 "-d$(@D)/%s" % ("/".join(out_dir),),
160 "$(SRCS)",
161 ]),
162 )
163 native.cc_library(
164 name = name,
165 srcs = c_srcs,
166 copts = f2c_copts + copts,
167 **kwargs
168 )