From 7e8245cf06a5edba91176193278f74e689476dc3 Mon Sep 17 00:00:00 2001 From: Jeremy Nimmer Date: Mon, 2 Oct 2023 13:23:14 -0700 Subject: [PATCH] [workspace] Build libpng_internal from source (#20276) Deprecate libpng from the host OS and remove it from setup prereqs. --- setup/mac/binary_distribution/Brewfile | 1 - .../binary_distribution/packages-focal.txt | 1 - .../binary_distribution/packages-jammy.txt | 1 - .../source_distribution/packages-focal.txt | 1 - .../source_distribution/packages-jammy.txt | 1 - tools/wheel/image/dependencies/projects.cmake | 6 - .../image/dependencies/projects/png.cmake | 16 --- tools/workspace/BUILD.bazel | 1 + tools/workspace/default.bzl | 5 + tools/workspace/libpng/repository.bzl | 1 + tools/workspace/libpng_internal/BUILD.bazel | 5 + .../libpng_internal/package.BUILD.bazel | 111 ++++++++++++++++++ .../libpng_internal/png_drake_vendor.h | 6 + .../workspace/libpng_internal/repository.bzl | 13 ++ tools/workspace/vtk_internal/settings.bzl | 5 +- 15 files changed, 143 insertions(+), 31 deletions(-) delete mode 100644 tools/wheel/image/dependencies/projects/png.cmake create mode 100644 tools/workspace/libpng_internal/BUILD.bazel create mode 100644 tools/workspace/libpng_internal/package.BUILD.bazel create mode 100644 tools/workspace/libpng_internal/png_drake_vendor.h create mode 100644 tools/workspace/libpng_internal/repository.bzl diff --git a/setup/mac/binary_distribution/Brewfile b/setup/mac/binary_distribution/Brewfile index 91171cb772a3..3293d39c4115 100644 --- a/setup/mac/binary_distribution/Brewfile +++ b/setup/mac/binary_distribution/Brewfile @@ -13,7 +13,6 @@ brew 'glib' brew 'graphviz' brew 'ipopt' brew 'jpeg' -brew 'libpng' brew 'libtiff' brew 'numpy' brew 'openblas' diff --git a/setup/ubuntu/binary_distribution/packages-focal.txt b/setup/ubuntu/binary_distribution/packages-focal.txt index 9a8033532703..5d81bfb17b4d 100644 --- a/setup/ubuntu/binary_distribution/packages-focal.txt +++ b/setup/ubuntu/binary_distribution/packages-focal.txt @@ -22,7 +22,6 @@ libmumps-seq-5.2.1 libnetcdf15 libogg0 libopengl0 -libpng16-16 libpython3.8 libqt5core5a libqt5gui5 diff --git a/setup/ubuntu/binary_distribution/packages-jammy.txt b/setup/ubuntu/binary_distribution/packages-jammy.txt index feb622279f9e..94dac25d4806 100644 --- a/setup/ubuntu/binary_distribution/packages-jammy.txt +++ b/setup/ubuntu/binary_distribution/packages-jammy.txt @@ -19,7 +19,6 @@ libmumps-seq-5.4 libnetcdf19 libogg0 libopengl0 -libpng16-16 libpython3.10 libqt5core5a libqt5gui5 diff --git a/setup/ubuntu/source_distribution/packages-focal.txt b/setup/ubuntu/source_distribution/packages-focal.txt index 41da5464efb7..2d2686bffd86 100644 --- a/setup/ubuntu/source_distribution/packages-focal.txt +++ b/setup/ubuntu/source_distribution/packages-focal.txt @@ -14,7 +14,6 @@ libjpeg-turbo8-dev liblapack-dev libmumps-seq-dev libopengl-dev -libpng-dev libtiff-dev libtinyxml-dev libtool diff --git a/setup/ubuntu/source_distribution/packages-jammy.txt b/setup/ubuntu/source_distribution/packages-jammy.txt index 118c83a982bd..0596ffe141f5 100644 --- a/setup/ubuntu/source_distribution/packages-jammy.txt +++ b/setup/ubuntu/source_distribution/packages-jammy.txt @@ -13,7 +13,6 @@ libjpeg-turbo8-dev liblapack-dev libmumps-seq-dev libopengl-dev -libpng-dev libtiff-dev libtinyxml-dev libtool diff --git a/tools/wheel/image/dependencies/projects.cmake b/tools/wheel/image/dependencies/projects.cmake index 75eec51ae48d..c13d8b66ddd9 100644 --- a/tools/wheel/image/dependencies/projects.cmake +++ b/tools/wheel/image/dependencies/projects.cmake @@ -31,12 +31,6 @@ set(libjpeg-turbo_url "https://github.com/libjpeg-turbo/libjpeg-turbo/archive/re set(libjpeg-turbo_md5 "357dc26a802c34387512a42697846d16") list(APPEND ALL_PROJECTS libjpeg-turbo) -# png -set(png_version 1.6.38) -set(png_url "https://downloads.sourceforge.net/project/libpng/libpng16/${png_version}/libpng-${png_version}.tar.xz") -set(png_md5 "122e6b7837811698563083b352bc8ca2") -list(APPEND ALL_PROJECTS png) - # TODO(jwnimmer-tri) When we purge `libtiff`, we can also purge `xz`, above. # The only user of `xz` is `libtiff`. # diff --git a/tools/wheel/image/dependencies/projects/png.cmake b/tools/wheel/image/dependencies/projects/png.cmake deleted file mode 100644 index 95033487652f..000000000000 --- a/tools/wheel/image/dependencies/projects/png.cmake +++ /dev/null @@ -1,16 +0,0 @@ -ExternalProject_Add(png - DEPENDS zlib - URL ${png_url} - URL_MD5 ${png_md5} - ${COMMON_EP_ARGS} - ${COMMON_CMAKE_EP_ARGS} - CMAKE_ARGS - ${COMMON_CMAKE_ARGS} - -DPNG_SHARED:BOOL=OFF - -DZLIB_INCLUDE_DIR:PATH=${CMAKE_INSTALL_PREFIX}/include - -DZLIB_LIBRARY:PATH=${CMAKE_INSTALL_PREFIX}/lib/libz.a - ) - -extract_license(png - LICENSE -) diff --git a/tools/workspace/BUILD.bazel b/tools/workspace/BUILD.bazel index 31648aecc698..5021f7566a17 100644 --- a/tools/workspace/BUILD.bazel +++ b/tools/workspace/BUILD.bazel @@ -89,6 +89,7 @@ _DRAKE_EXTERNAL_PACKAGE_INSTALLS = ["@%s//:install" % p for p in [ "gz_utils_internal", "ipopt", "lcm", + "libpng_internal", "meshcat", "msgpack_internal", "net_sf_jchart2d", diff --git a/tools/workspace/default.bzl b/tools/workspace/default.bzl index beff8a63060e..fbccebfaf958 100644 --- a/tools/workspace/default.bzl +++ b/tools/workspace/default.bzl @@ -57,6 +57,7 @@ load("//tools/workspace/liblz4:repository.bzl", "liblz4_repository") load("//tools/workspace/liblzma:repository.bzl", "liblzma_repository") load("//tools/workspace/libpfm:repository.bzl", "libpfm_repository") load("//tools/workspace/libpng:repository.bzl", "libpng_repository") +load("//tools/workspace/libpng_internal:repository.bzl", "libpng_internal_repository") # noqa load("//tools/workspace/libtiff:repository.bzl", "libtiff_repository") load("//tools/workspace/meshcat:repository.bzl", "meshcat_repository") load("//tools/workspace/mosek:repository.bzl", "mosek_repository") @@ -257,7 +258,11 @@ def add_default_repositories(excludes = [], mirrors = DEFAULT_MIRRORS): if "libpfm" not in excludes: libpfm_repository(name = "libpfm") if "libpng" not in excludes: + # The @libpng external is deprecated in Drake's WORKSPACE and will be + # removed on or after 2024-02-01. libpng_repository(name = "libpng") + if "libpng_internal" not in excludes: + libpng_internal_repository(name = "libpng_internal", mirrors = mirrors) if "libtiff" not in excludes: libtiff_repository(name = "libtiff") if "meshcat" not in excludes: diff --git a/tools/workspace/libpng/repository.bzl b/tools/workspace/libpng/repository.bzl index 51a850980800..a5c2a3939184 100644 --- a/tools/workspace/libpng/repository.bzl +++ b/tools/workspace/libpng/repository.bzl @@ -12,5 +12,6 @@ def libpng_repository( licenses = licenses, modname = modname, pkg_config_paths = pkg_config_paths, + extra_deprecation = "The @libpng external is deprecated in Drake's WORKSPACE and will be removed on or after 2024-02-01.", # noqa **kwargs ) diff --git a/tools/workspace/libpng_internal/BUILD.bazel b/tools/workspace/libpng_internal/BUILD.bazel new file mode 100644 index 000000000000..3875982e90a4 --- /dev/null +++ b/tools/workspace/libpng_internal/BUILD.bazel @@ -0,0 +1,5 @@ +load("//tools/lint:lint.bzl", "add_lint_tests") + +exports_files(["png_drake_vendor.h"]) + +add_lint_tests() diff --git a/tools/workspace/libpng_internal/package.BUILD.bazel b/tools/workspace/libpng_internal/package.BUILD.bazel new file mode 100644 index 000000000000..c2455c8043d9 --- /dev/null +++ b/tools/workspace/libpng_internal/package.BUILD.bazel @@ -0,0 +1,111 @@ +# -*- bazel -*- + +load("@drake//tools/install:install.bzl", "install") +load("@drake//tools/skylark:cc.bzl", "cc_library") + +licenses(["notice"]) # libpng-2.0 + +package(default_visibility = ["//visibility:private"]) + +# Allow Drake's linter cross-checks to use the headers. +exports_files(glob(["*.h"])) + +# This setting governs when we'll compile with Intel SIMD enabled. We don't use +# Intel SIMD on macOS (even for Apple hardware that supports it) to reduce our +# test matrix burden for the deprecated architecture. +config_setting( + name = "build_intel", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +_PUBLIC_HDRS = [ + "png.h", + "pngconf.h", + ":pnglibconf.h", +] + +_PRIVATE_HDRS = [ + "pngdebug.h", + "pnginfo.h", + "pngstruct.h", + "pngpriv.h", +] + +_SRCS = [ + "png.c", + "pngerror.c", + "pngget.c", + "pngmem.c", + "pngpread.c", + "pngread.c", + "pngrio.c", + "pngrtran.c", + "pngrutil.c", + "pngset.c", + "pngtrans.c", + "pngwio.c", + "pngwrite.c", + "pngwtran.c", + "pngwutil.c", +] + +_SRCS_INTEL = [ + "intel/filter_sse2_intrinsics.c", + "intel/intel_init.c", +] + +genrule( + name = "_pnglibconf.h", + srcs = [ + "scripts/pnglibconf.h.prebuilt", + "@drake//tools/workspace/libpng_internal:png_drake_vendor.h", + ], + outs = ["pnglibconf.h"], + cmd = "cat $(SRCS) > $@", +) + +cc_library( + name = "libpng", + hdrs = _PUBLIC_HDRS, + srcs = _SRCS + _PRIVATE_HDRS + select({ + ":build_intel": _SRCS_INTEL, + "//conditions:default": [], + }), + includes = ["."], + copts = [ + "-fvisibility=hidden", + "-w", + # Turn off guessing. It should be implicitly off by default, + # but it would be a disaster if the default somehow didn't work. + "-DPNG_NO_CONFIG_H=1", + # Don't allow the pngpriv.h auto-sensing of Neon to take effect. + "-DPNG_ARM_NEON_OPT=0", + "-DPNG_ARM_NEON_IMPLEMENTATION=0", + ] + select({ + ":build_intel": [ + # Use SSE4.1 (or earlier) SIMD instructions. + "-msse4.1", + "-DPNG_INTEL_SSE_OPT=1", + "-DPNG_INTEL_SSE_IMPLEMENTATION=3", + ], + "//conditions:default": [ + "-DPNG_INTEL_SSE_OPT=0", + "-DPNG_INTEL_SSE_IMPLEMENTATION=0", + ], + }), + linkopts = ["-lm"], + linkstatic = True, + deps = [ + "@zlib", + ], + visibility = ["//visibility:public"], +) + +install( + name = "install", + docs = ["LICENSE"], + visibility = ["//visibility:public"], +) diff --git a/tools/workspace/libpng_internal/png_drake_vendor.h b/tools/workspace/libpng_internal/png_drake_vendor.h new file mode 100644 index 000000000000..d5d2139790ba --- /dev/null +++ b/tools/workspace/libpng_internal/png_drake_vendor.h @@ -0,0 +1,6 @@ +#pragma once + +/* The following are Drake's adjustments to libpng. */ + +/* Always use the macros, never the slow out-of-line functions. */ +#undef PNG_READ_INT_FUNCTIONS_SUPPORTED diff --git a/tools/workspace/libpng_internal/repository.bzl b/tools/workspace/libpng_internal/repository.bzl new file mode 100644 index 000000000000..9587da124fc6 --- /dev/null +++ b/tools/workspace/libpng_internal/repository.bzl @@ -0,0 +1,13 @@ +load("//tools/workspace:github.bzl", "github_archive") + +def libpng_internal_repository( + name, + mirrors = None): + github_archive( + name = name, + repository = "glennrp/libpng", + commit = "v1.6.40", + sha256 = "62d25af25e636454b005c93cae51ddcd5383c40fa14aa3dae8f6576feb5692c2", # noqa + build_file = ":package.BUILD.bazel", + mirrors = mirrors, + ) diff --git a/tools/workspace/vtk_internal/settings.bzl b/tools/workspace/vtk_internal/settings.bzl index 3888f666c85c..0e9eac872ba4 100644 --- a/tools/workspace/vtk_internal/settings.bzl +++ b/tools/workspace/vtk_internal/settings.bzl @@ -548,10 +548,7 @@ MODULE_SETTINGS = { "VTK_MODULE_USE_EXTERNAL_vtkpng=1", ], "deps_extra": [ - # TODO(jwnimmer-tri) VTK is the only user of this library. - # We should write our own WORKSPACE rule to build it sensibly, - # or switch to VTK's vendored version. - "@libpng", + "@libpng_internal//:libpng", ], }, "VTK::tiff": {