Brian Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 1 | load("@//tools/build_rules:select.bzl", "compiler_select") |
Brian Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 2 | |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 3 | def _single_fortran_object_impl(ctx): |
| 4 | toolchain_cflags = (ctx.fragments.cpp.compiler_options([]) + |
| 5 | ctx.fragments.cpp.c_options + |
Austin Schuh | 3b3fee0 | 2015-11-26 17:26:32 -0800 | [diff] [blame] | 6 | ctx.fragments.cpp.unfiltered_compiler_options([]) + |
| 7 | ['-fPIC', '-Wno-maybe-uninitialized', '-Wno-unused-dummy-argument', |
Austin Schuh | 2461e5e | 2015-11-28 13:23:45 -0800 | [diff] [blame] | 8 | '-Wno-conversion', '-Wno-unused-variable', '-Wno-character-truncation']) |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 9 | |
| 10 | cmd = toolchain_cflags + ['-c', ctx.file.src.path, '-o', ctx.outputs.pic_o.path] |
| 11 | filtered_cmd = [] |
Brian Silverman | a4a4ea6 | 2015-11-27 10:27:53 -0500 | [diff] [blame] | 12 | # Strip out the C/C++/Clang specific flags. |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 13 | 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 Schuh | 3b3fee0 | 2015-11-26 17:26:32 -0800 | [diff] [blame] | 21 | '-Wextra', |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 22 | '-Wno-builtin-macro-redefined', |
Austin Schuh | c65df86 | 2015-12-27 14:04:49 -0800 | [diff] [blame] | 23 | '-Wunused-local-typedefs', |
Brian Silverman | a4a4ea6 | 2015-11-27 10:27:53 -0500 | [diff] [blame] | 24 | '-D__has_feature(x)=0', |
| 25 | '-fmacro-backtrace-limit=0'] |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 26 | |
| 27 | for flag in cmd: |
Brian Silverman | ed79de6 | 2015-11-28 18:10:17 -0500 | [diff] [blame] | 28 | if flag not in exclude_flags and not (flag.startswith('-fsanitize') or |
| 29 | flag.startswith('-fno-sanitize')): |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 30 | filtered_cmd.append(flag) |
| 31 | |
| 32 | ctx.action( |
Brian Silverman | b2215d0 | 2015-11-23 19:10:15 -0500 | [diff] [blame] | 33 | inputs = [ctx.file.src] + ctx.files._cc_toolchain, |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 34 | 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 Silverman | b200c17 | 2017-01-02 17:35:35 -0800 | [diff] [blame] | 41 | def _define_fortran_output(src): |
| 42 | if not src.name.endswith('.f'): |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 43 | fail('Fortran files must end in \'.f\'', 'src') |
| 44 | |
Brian Silverman | b200c17 | 2017-01-02 17:35:35 -0800 | [diff] [blame] | 45 | fortran_file_base = src.name[:-2] |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 46 | return { |
| 47 | 'pic_o': fortran_file_base + '.pic.o', |
| 48 | } |
| 49 | |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 50 | _single_fortran_object = rule( |
Brian Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 51 | 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 Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 68 | ) |
| 69 | |
| 70 | def 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 Silverman | b2215d0 | 2015-11-23 19:10:15 -0500 | [diff] [blame] | 80 | _single_fortran_object( |
| 81 | name = name + '_' + pic_o_file, |
| 82 | src = src, |
| 83 | visibility = ['//visibility:private'], |
Austin Schuh | 9d92e6b | 2017-10-17 01:19:38 -0700 | [diff] [blame] | 84 | restricted_to = ['@//tools:k8'], |
Brian Silverman | b2215d0 | 2015-11-23 19:10:15 -0500 | [diff] [blame] | 85 | ) |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 86 | 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 Schuh | 9d92e6b | 2017-10-17 01:19:38 -0700 | [diff] [blame] | 96 | restricted_to = ['@//tools:k8'], |
Austin Schuh | 1f9aeb4 | 2015-11-12 23:34:49 -0800 | [diff] [blame] | 97 | ) |
Brian Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 98 | |
| 99 | f2c_copts = compiler_select({ |
Brian Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 100 | "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 Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 111 | }) + [ |
Brian Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 112 | # 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 Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 117 | ] |
Brian Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 118 | |
Brian Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 119 | """Copts to use when compiling f2c-generated files. |
| 120 | |
| 121 | This is useful when building externally-f2ced files.""" |
Brian Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 122 | |
| 123 | def 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 Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 146 | '@//tools/build_rules:quiet_success', |
Brian Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 147 | ], |
Brian Silverman | 8dd8a05 | 2018-09-02 17:08:31 -0700 | [diff] [blame] | 148 | cmd = ' '.join([ |
| 149 | '$(location @//tools/build_rules:quiet_success)', |
| 150 | '$(location @f2c)', |
| 151 | '-d$(@D)/%s' % ('/'.join(out_dir),), |
| 152 | '$(SRCS)', |
| 153 | ]), |
Brian Silverman | d3ad165 | 2018-02-18 22:16:29 -0500 | [diff] [blame] | 154 | ) |
| 155 | native.cc_library( |
| 156 | name = name, |
| 157 | srcs = c_srcs, |
| 158 | copts = f2c_copts + copts, |
| 159 | **kwargs |
| 160 | ) |