diff --git a/tools/workspace/gfortran/package.BUILD.bazel b/tools/workspace/gfortran/package.BUILD.bazel new file mode 100644 index 000000000000..342ef50c3f20 --- /dev/null +++ b/tools/workspace/gfortran/package.BUILD.bazel @@ -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"], +) diff --git a/tools/workspace/gfortran/repository.bzl b/tools/workspace/gfortran/repository.bzl index 20f3b69a3355..bb3354bda938 100644 --- a/tools/workspace/gfortran/repository.bzl +++ b/tools/workspace/gfortran/repository.bzl @@ -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,