Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[workspace] Simplify gfortran to be more platform-agnostic #20583

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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