From 2a68099640ddcd252dbc3eb1323428b6a7792790 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Fri, 12 Jun 2020 02:55:40 -0700 Subject: [PATCH] add `make install-with-libs` back Summary: This is mostly a partial revert of D19022905 and D19272627 for only the part of it concerned with "install-with-libs". Fixes #1260. Reviewed By: skcho Differential Revision: D21998484 fbshipit-source-id: ed884e772 --- Makefile | 57 ++++++++++++++++++++++++++++++++ Makefile.autoconf.in | 4 +++ configure.ac | 9 +++++ docker/master/Dockerfile | 2 +- scripts/create_binary_release.sh | 2 +- scripts/set_libso_path.sh | 30 +++++++++++++++++ 6 files changed, 102 insertions(+), 2 deletions(-) create mode 100755 scripts/set_libso_path.sh diff --git a/Makefile b/Makefile index 3011d167d..27ee1b9bb 100644 --- a/Makefile +++ b/Makefile @@ -715,6 +715,63 @@ else endif endif +# install dynamic libraries +# use this if you want to distribute infer binaries +install-with-libs: install + test -d '$(DESTDIR)$(libdir)'/infer/infer/libso || \ + $(MKDIR_P) '$(DESTDIR)$(libdir)'/infer/infer/libso +ifneq ($(LDD),no) +ifneq ($(PATCHELF),no) +# this sort of assumes Linux +# figure out where libgmp and libmpfr are using ldd + set -x; \ + for lib in $$($(LDD) $(INFER_BIN) \ + | cut -d ' ' -f 3 \ + | grep -e 'lib\(gmp\|mpfr\)'); do \ + $(INSTALL_PROGRAM) -C "$$lib" '$(DESTDIR)$(libdir)'/infer/infer/libso/; \ + done +# update rpath of executables + for sofile in '$(DESTDIR)$(libdir)'/infer/infer/libso/*.so*; do \ + $(PATCHELF) --set-rpath '$$ORIGIN' --force-rpath "$$sofile"; \ + done + $(PATCHELF) --set-rpath '$$ORIGIN/../libso' --force-rpath '$(DESTDIR)$(libdir)'/infer/infer/bin/infer +ifeq ($(IS_FACEBOOK_TREE),yes) + $(PATCHELF) --set-rpath '$$ORIGIN/../libso' --force-rpath '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks +endif +else # ldd found but not patchelf + echo "ERROR: ldd (Linux?) found but not patchelf, please install patchelf" >&2; exit 1 +endif +else # ldd not found +ifneq ($(OTOOL),no) +ifneq ($(INSTALL_NAME_TOOL),no) +# this sort of assumes osx +# figure out where libgmp and libmpfr are using otool + set -e; \ + set -x; \ + for lib in $$($(OTOOL) -L $(INFER_BIN) \ + | cut -d ' ' -f 1 | tr -d '\t' \ + | grep -e 'lib\(gmp\|mpfr\)'); do \ + $(INSTALL_PROGRAM) -C "$$lib" '$(DESTDIR)$(libdir)'/infer/infer/libso/; \ + done + set -x; \ + for sofile in '$(DESTDIR)$(libdir)'/infer/infer/libso/*.dylib; do \ + $(INSTALL_NAME_TOOL) -add_rpath "@executable_path" "$$sofile" 2> /dev/null || true; \ + scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso "$$sofile"; \ + done + $(INSTALL_NAME_TOOL) -add_rpath '@executable_path/../libso' '$(DESTDIR)$(libdir)'/infer/infer/bin/infer 2> /dev/null || true + scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso '$(DESTDIR)$(libdir)'/infer/infer/bin/infer +ifeq ($(IS_FACEBOOK_TREE),yes) + $(INSTALL_NAME_TOOL) -add_rpath '@executable_path/../libso' '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks 2> /dev/null || true + scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks +endif +else # install_name_tool not found + echo "ERROR: otool (OSX?) found but not install_name_tool, please install install_name_tool" >&2; exit 1 +endif +else # otool not found + echo "ERROR: need ldd + patchelf (Linux) or otool + install_name_tool (OSX) available" >&2; exit 1 +endif +endif # ldd + # Nuke objects built from OCaml. Useful when changing the OCaml compiler, for instance. .PHONY: ocaml_clean ocaml_clean: diff --git a/Makefile.autoconf.in b/Makefile.autoconf.in index b2ee976e2..868c8681e 100644 --- a/Makefile.autoconf.in +++ b/Makefile.autoconf.in @@ -36,11 +36,13 @@ INFER_MINOR = @INFER_MINOR@ INFER_PATCH = @INFER_PATCH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ +INSTALL_NAME_TOOL = @INSTALL_NAME_TOOL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ IS_FACEBOOK_TREE = @IS_FACEBOOK_TREE@ IS_RELEASE_TREE = @IS_RELEASE_TREE@ JAVA_MAJOR_VERSION = @JAVA_MAJOR_VERSION@ JAVAC = @JAVAC@ +LDD = @LDD@ LDFLAGS = @LDFLAGS@ libdir = @libdir@ # override in your `make` command to make the install relocatable @@ -66,6 +68,8 @@ OCAMLOPT = @OCAMLOPT@ OPAM = @OPAM@ OPAMROOT = @OPAMROOT@ OPAMSWITCH = @OPAMSWITCH@ +OTOOL = @OTOOL@ +PATCHELF = @PATCHELF@ PATH = @PATH@ prefix = @prefix@ SDKROOT = @SDKROOT@ diff --git a/configure.ac b/configure.ac index 22bdf8af1..15af58998 100644 --- a/configure.ac +++ b/configure.ac @@ -395,6 +395,15 @@ AC_SUBST([GNU_SED]) AC_CHECK_TOOL([BREW], [brew], [no]) +AC_CHECK_TOOL([INSTALL_NAME_TOOL], [install_name_tool], [no]) +AC_SUBST([INSTALL_NAME_TOOL]) +AC_CHECK_TOOL([LDD], [ldd], [no]) +AC_SUBST([LDD]) +AC_CHECK_TOOL([OTOOL], [otool], [no]) +AC_SUBST([OTOOL]) +AC_CHECK_TOOL([PATCHELF], [patchelf], [no]) +AC_SUBST([PATCHELF]) + AC_CHECK_INFER_MAN_LAST_MODIFIED() AC_CONFIG_FILES([ diff --git a/docker/master/Dockerfile b/docker/master/Dockerfile index f338cc944..d8ab1ddc3 100644 --- a/docker/master/Dockerfile +++ b/docker/master/Dockerfile @@ -54,7 +54,7 @@ RUN cd /infer && \ # Generate a release RUN cd /infer && \ - make install \ + make install-with-libs \ BUILD_MODE=opt \ DESTDIR="/infer-release" \ libdir_relative_to_bindir="../lib" diff --git a/scripts/create_binary_release.sh b/scripts/create_binary_release.sh index bf46114a9..d73ed762f 100755 --- a/scripts/create_binary_release.sh +++ b/scripts/create_binary_release.sh @@ -46,7 +46,7 @@ touch .release --prefix="/$RELEASE_NAME" make -j "$JOBS" \ - install \ + install-with-libs \ BUILD_MODE=opt \ DESTDIR="$ROOT_DIR" \ libdir_relative_to_bindir=../lib diff --git a/scripts/set_libso_path.sh b/scripts/set_libso_path.sh new file mode 100755 index 000000000..04af8ce68 --- /dev/null +++ b/scripts/set_libso_path.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +# Usage: set_libso_path.sh [LIBSO_DIR] [TARGET] +# +# This changes MacOSX's executable [TARGET] to use shared libraries in +# [LIBSO_DIR] when rpath has been set to [LIBSO_DIR]. + +set -e +set -o pipefail +set -u + +LIBSO_DIR=$1 +TARGET=$2 + +TMP=$( mktemp ) +trap "rm $TMP" EXIT + +otool -L "$TARGET" | tail -n +2 > "$TMP" +while IFS='' read -r line || [[ -n "$line" ]]; do + LIB_PATH=$( echo $line | awk '{print $1}' ) + LIB_FILE=$( basename "${LIB_PATH}" ) + if [ -f "${LIBSO_DIR}/${LIB_FILE}" ]; then + install_name_tool -change "${LIB_PATH}" "@rpath/${LIB_FILE}" "$TARGET" + fi +done < "$TMP"