Skip to content

Commit

Permalink
[workspace] Simplify gfortran to be more platform-agnostic (#20583)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwnimmer-tri authored Nov 27, 2023
1 parent 335cd3e commit b9dd8c8
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 68 deletions.
36 changes: 36 additions & 0 deletions tools/workspace/gfortran/package.BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- bazel -*-

load("@drake//tools/skylark:cc.bzl", "cc_library")
load(":path.bzl", "LIBDIR")

# libgfortran: GPL-3.0-or-later WITH GCC-exception-3.1.
# libquadmath: LGPL-2.0-or-later.
licenses(["restricted"]) # See above for details.

sh_binary(
name = "compiler",
srcs = ["gfortran-found"],
visibility = ["//visibility:public"],
)

config_setting(
name = "x86_64",
constraint_values = [
"@platforms//cpu:x86_64",
],
)

cc_library(
name = "runtime",
linkopts = [
"-L{}".format(LIBDIR),
"-ldl",
"-lgfortran",
] + select({
":x86_64": [
"-lquadmath",
],
"//conditions:default": [],
}),
visibility = ["//visibility:public"],
)
96 changes: 28 additions & 68 deletions tools/workspace/gfortran/repository.bzl
Original file line number Diff line number Diff line change
@@ -1,86 +1,46 @@
load("//tools/workspace:os.bzl", "determine_os")
load("//tools/workspace:execute.bzl", "execute_or_fail", "which")

def _find_library(repo_ctx, compiler, lib_name):
return execute_or_fail(
repo_ctx,
[compiler, "--print-file-name=" + lib_name],
).stdout.strip()

def _gfortran_impl(repo_ctx):
"""Locate gfortran and alias it to `:compiler`; locate libgfortran and
libquadmath and alias then to `:runtime.`"""

# Find the compiler.
compiler = str(which(repo_ctx, "gfortran"))
if not compiler:
fail("Could not find gfortran")
repo_ctx.symlink(compiler, "gfortran-found")

# Find the runtime libraries based on the OS.
os_result = determine_os(repo_ctx)
if os_result.error != None:
fail(os_result.error)
if os_result.is_macos or os_result.is_macos_wheel:
suffix = ".dylib"
else:
suffix = ".so"
libgfortran = "libgfortran{}".format(suffix)
libgfortran_path = _find_library(repo_ctx, compiler, libgfortran)

# The cc_library linking is different on Ubuntu vs macOS.
if os_result.is_macos or os_result.is_macos_wheel:
srcs = []
linkopts = [
"-L{}".format(repo_ctx.path(libgfortran_path).dirname),
"-ldl",
"-lgfortran",
]
if os_result.macos_arch_result != "arm64":
linkopts.append("-lquadmath")
else:
libquadmath = "libquadmath{}".format(suffix)
libquadmath_path = _find_library(repo_ctx, compiler, libquadmath)
repo_ctx.symlink(libgfortran_path, libgfortran)
repo_ctx.symlink(libquadmath_path, libquadmath)
srcs = [libgfortran, libquadmath]
linkopts = ["-ldl"]

# Inquire which version we found.
# Transcribe which version we found.
dumpversion = execute_or_fail(repo_ctx, [compiler, "-dumpversion"]).stdout
repo_ctx.file("version.bzl", content = "MAJOR = {}\n".format(
int(dumpversion.strip()),
))

# Emit the build file and return.
BUILD = """
# DO NOT EDIT: generated by gfortran_repository().
load("@drake//tools/skylark:cc.bzl", "cc_library")
# libgfortran: GPL-3.0-or-later WITH GCC-exception-3.1.
# libquadmath: LGPL-2.0-or-later.
licenses(["restricted"]) # See above for details.
sh_binary(
name = "compiler",
srcs = ["gfortran-found"],
visibility = ["//visibility:public"],
repo_ctx.file(
"version.bzl",
content = "MAJOR = {}\n".format(int(dumpversion.strip())),
)
cc_library(
name = "runtime",
srcs = {},
linkopts = {},
visibility = ["//visibility:public"],

# Transcribe the library link path.
filename = execute_or_fail(
repo_ctx,
[
compiler,
"--print-file-name=libgfortran.{}".format(
"dylib" if repo_ctx.os.name == "mac os x" else "so",
),
],
).stdout
libdir = repo_ctx.path(filename.strip()).dirname
repo_ctx.file(
"path.bzl",
content = "LIBDIR = {}\n".format(repr(str(libdir))),
)
""".format(srcs, linkopts).replace(
# Strip leading indentation.
"\n ",
"\n",

# Add the build file.
repo_ctx.symlink(
Label("@drake//tools/workspace/gfortran:package.BUILD.bazel"),
"BUILD.bazel",
)
repo_ctx.file("BUILD.bazel", content = BUILD)

gfortran_repository = repository_rule(
doc = """
Locate gfortran and alias it to `:compiler`; locate libgfortran
(and libquadmath when relevant) and alias them to `:runtime`.
""",
local = True,
configure = True,
implementation = _gfortran_impl,
Expand Down

0 comments on commit b9dd8c8

Please sign in to comment.