Skip to content

Commit

Permalink
Merge pull request #28772 from idaholab/28771_install_so
Browse files Browse the repository at this point in the history
Add support for non-archive library dependencies in install
  • Loading branch information
loganharbour authored Oct 4, 2024
2 parents 9fb4f87 + 6cc9e44 commit bc11ff3
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 32 deletions.
75 changes: 48 additions & 27 deletions framework/app.mk
Original file line number Diff line number Diff line change
Expand Up @@ -469,19 +469,23 @@ $(app_EXEC): $(app_LIBS) $(mesh_library) $(main_object) $(app_test_LIB) $(depend

###### install stuff #############
docs_dir := $(APPLICATION_DIR)/doc
bindst = $(bin_install_dir)/$(notdir $(app_EXEC))
installed_app_binary = $(bin_install_dir)/$(notdir $(app_EXEC))
binlink = $(share_install_dir)/$(notdir $(app_EXEC))
# Strip the trailing slashes (if provided) and transform into a suitable Makefile targets
copy_input_targets := $(foreach dir,$(INSTALLABLE_DIRS),target_$(APPLICATION_NAME)_$(patsubst %/,%,$(dir)))

ifeq ($(want_exec),yes)
install_bin: $(bindst)
lib_install_targets = $(foreach lib,$(applibs),$(dir $(lib))install_lib_$(notdir $(lib)))
install_bin: $(installed_app_binary)
# Install targets for library archives, which will also install the associated .so/.dylib library
lib_archive_install_targets = $(foreach lib,$(filter %.la, $(applibs)),$(dir $(lib))install_lib_from_archive_$(notdir $(lib)))
# Install targets for libraries that do not have archives (.so/.dylib)
lib_install_targets = $(foreach lib,$(filter %.$(lib_suffix), $(applibs)),$(dir $(lib))install_lib_$(notdir $(lib)))
else
install_bin:
endif

install_libs:: $(lib_install_targets)
# Top level install target for all libraries (.so/.dylib, .la)
install_all_libs: $(lib_archive_install_targets) $(lib_install_targets)

ifneq ($(wildcard $(APPLICATION_DIR)/data/.),)
install_data_$(APPLICATION_NAME)_src := $(APPLICATION_DIR)/data
Expand Down Expand Up @@ -518,27 +522,44 @@ $(copy_input_targets):
echo "app_name = $(APPLICATION_NAME)" > $(share_install_dir)/$(dest_dir)/testroot; \
fi; \


install_lib_%: %
# Install target for a single .la library archive and the associated .so/.dylib library
install_lib_from_archive_%: %
@mkdir -p $(lib_install_dir)
@$(eval libname := $(shell grep "dlname='.*'" $< | sed -E "s/dlname='(.*)'/\1/g"))
@$(eval libdst := $(lib_install_dir)/$(libname)) # full installed path (includes library name)
@$(eval source_dir := $(dir $<))
@$(eval la_installed = $(lib_install_dir)/$(notdir $<))
@echo "Installing library $(libdst)"
@cp $< $(la_installed) # Copy the library archive file
@cp $(source_dir)/$(libname) $(libdst) # Copy the library file
@$(call patch_la,$(la_installed),$(lib_install_dir))
ifneq (,$(findstring darwin,$(libmesh_HOST)))
@$(call patch_rpath,$(libdst),../$(lib_install_suffix/.))
endif
@$(call patch_relink,$(libdst),$(libpath_pcre),$(libname_pcre))
@$(call patch_relink,$(libdst),$(libpath_framework),$(libname_framework))
@$(eval lib_archive_installed = $(lib_install_dir)/$(notdir $<))
@$(eval lib_file = $(call lib_from_archive,$<))
@$(eval lib_installed := $(lib_install_dir)/$(lib_file))
@$(eval lib_build := $(dir $<)/$(lib_file))

# Install the .so/.dylib library
@echo "Installing library $(lib_installed)"
@cp $(lib_build) $(lib_installed)
# Patch to add additional installed rpaths to the application libs
# for dependencies-of-dependencies installed in a different folder
@if [ "$(notdir $<)" == "$(notdir $(app_LIB))" ] || [ "$(notdir $<)" == "$(notdir $(app_test_LIB))" ]; then \
for lib_dir in $(ADDITIONAL_APP_INSTALL_RPATHS); do $(call patch_rpath,$(lib_installed),$(abspath $(lib_install_dir)/../$$lib_dir)); done \
fi
# Patch to add libraries in the installed folder
@$(call patch_rpath,$(lib_installed),$(lib_install_dir))

# Install the .la library, which on mac requires the library above to be installed first
@echo "Installing library archive $(lib_archive_installed)"
@cp $< $(lib_archive_installed)
@$(call patch_la,$(lib_archive_installed),$(lib_install_dir))
@$(call patch_relink,$(lib_installed),$(libpath_pcre),$(libname_pcre))
@$(call patch_relink,$(lib_installed),$(libpath_framework),$(libname_framework))
# These lines are critical in that they are a catch-all for nested applications. (e.g. These will properly remap MOOSE and the modules
# in an application library to the installed locations) - DO NOT REMOVE! Yes, this can probably be done better
@$(eval libnames := $(foreach lib,$(applibs),$(shell grep "dlname='.*'" $(lib) 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g")))
@$(eval libpaths := $(foreach lib,$(applibs),$(dir $(lib))$(shell grep "dlname='.*'" $(lib) 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g")))
@for lib in $(libpaths); do $(call patch_relink,$(libdst),$$lib,$$(basename $$lib)); done
@$(eval libnames := $(foreach lib,$(filter %.la, $(applibs)),$(call lib_from_archive,$(lib))))
@$(eval libpaths := $(foreach lib,$(filter %.la, $(applibs)),$(dir $(lib))$(call lib_from_archive,$(lib))))
@for lib in $(libpaths); do $(call patch_relink,$(lib_installed),$$lib,$$(basename $$lib)); done

# Install target for a single .so/.dylib library that is not associated with a .la library archive
install_lib_%: %
@mkdir -p $(lib_install_dir)
@$(eval lib_installed = $(lib_install_dir)/$(notdir $<))
@echo "Installing library $(lib_installed)"
@cp $< $(lib_installed)
@$(call patch_rpath,$(lib_installed),$(lib_install_dir))

$(binlink): $(copy_input_targets)
ln -sf ../../bin/$(notdir $(app_EXEC)) $@
Expand All @@ -552,17 +573,17 @@ else
@echo "Skipping docs installation."
endif

$(bindst): $(app_EXEC) $(copy_input_targets) install_$(APPLICATION_NAME)_docs install_$(APPLICATION_NAME)_resource $(binlink)
$(installed_app_binary): $(app_EXEC) $(copy_input_targets) install_$(APPLICATION_NAME)_docs install_$(APPLICATION_NAME)_resource $(binlink)
@echo "Installing binary $@"
@mkdir -p $(bin_install_dir)
@cp $< $@
@$(call patch_rpath,$@,../$(lib_install_suffix)/.)
@$(eval libnames := $(foreach lib,$(applibs),$(shell grep "dlname='.*'" $(lib) 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g")))
@$(eval libpaths := $(foreach lib,$(applibs),$(dir $(lib))$(shell grep "dlname='.*'" $(lib) 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g")))
@$(call patch_rpath,$@,$(lib_install_dir))
@$(eval libnames := $(foreach lib,$(applibs),$(call lib_from_archive,$(lib))))
@$(eval libpaths := $(foreach lib,$(applibs),$(dir $(lib))$(call lib_from_archive,$(lib))))
@for lib in $(libpaths); do $(call patch_relink,$@,$$lib,$$(basename $$lib)); done

ifeq ($(want_exec),yes)
install_bin: $(bindst)
install_bin: $(installed_app_binary)
else
install_bin:
endif
Expand Down
14 changes: 9 additions & 5 deletions framework/moose.mk
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ moose_share_dir = $(share_dir)/moose
python_install_dir = $(moose_share_dir)/python
bin_install_dir = $(PREFIX)/bin

install: all install_libs install_bin install_harness install_exodiff install_adreal_monolith install_hit install_data
install: all install_all_libs install_bin install_harness install_exodiff install_adreal_monolith install_hit install_data

install_data::
@mkdir -p $(moose_share_dir)
Expand Down Expand Up @@ -526,16 +526,20 @@ lib_install_dir = $(PREFIX)/$(lib_install_suffix)

ifneq (,$(findstring darwin,$(libmesh_HOST)))
patch_relink = install_name_tool -change $(2) @rpath/$(3) $(1)
patch_rpath = install_name_tool -add_rpath @executable_path/$(2) $(1)
patch_rpath = install_name_tool -add_rpath $(2) $(1)
patch_remove = :
else
patch_relink = :
patch_rpath = patchelf --set-rpath '$$ORIGIN'/$(2):$$(patchelf --print-rpath $(1)) $(1)
patch_rpath = patchelf --set-rpath $(2):$$(patchelf --print-rpath $(1)) $(1)
patch_remove = patchelf --remove-needed $(2) $(1)
endif
patch_la = $(FRAMEWORK_DIR)/scripts/patch_la.py $(1) $(2)
# Gets the associated library from a library archive (first argument)
lib_from_archive = `grep "dlname='.*'" $(1) 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g"`

libname_framework = $(shell grep "dlname='.*'" $(MOOSE_DIR)/framework/libmoose-$(METHOD).la 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g")
libname_framework = $(call lib_from_archive,$(MOOSE_DIR)/framework/libmoose-$(METHOD).la)
libpath_framework = $(MOOSE_DIR)/framework/$(libname_framework)
libname_pcre = $(shell grep "dlname='.*'" $(MOOSE_DIR)/framework/contrib/pcre/libpcre-$(METHOD).la 2>/dev/null | sed -E "s/dlname='(.*)'/\1/g")
libname_pcre = $(call lib_from_archive,$(MOOSE_DIR)/framework/contrib/pcre/libpcre-$(METHOD).la)
libpath_pcre = $(MOOSE_DIR)/framework/contrib/pcre/$(libname_pcre)

#
Expand Down

0 comments on commit bc11ff3

Please sign in to comment.