From b205ee0515a4954cb753520ad838830c700911e6 Mon Sep 17 00:00:00 2001 From: Mark Gates Date: Thu, 23 May 2024 01:18:21 -0400 Subject: [PATCH] add shared library version. --- CMakeLists.txt | 10 +++++ GNUmakefile | 102 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 79 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc7510ee..a4ddadf4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,12 @@ project( LANGUAGES CXX ) +# See notes in GNUmakefile about using abi-compliance-checker. +# soversion is major ABI version. +set( abi_version 1.0.0 ) +string( REPLACE "." ";" abi_list "${abi_version}" ) +list( GET abi_list 0 soversion ) + include( CheckCXXCompilerFlag ) # When built as a sub-project, add a namespace to make targets unique, @@ -113,6 +119,8 @@ use_cmake_find_lapack = ${use_cmake_find_lapack} gpu_backend = ${gpu_backend} lapackpp_is_project = ${lapackpp_is_project} lapackpp_ = ${lapackpp_} +abi_version = ${abi_version} +soversion = ${soversion} " ) #------------------------------------------------------------------------------- @@ -684,6 +692,8 @@ set_target_properties( CXX_STANDARD_REQUIRED true # prohibit < c++17 CXX_EXTENSIONS false # prohibit gnu++17 WINDOWS_EXPORT_ALL_SYMBOLS ON + VERSION "${abi_version}" + SOVERSION "${soversion}" ) if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) diff --git a/GNUmakefile b/GNUmakefile index 1b66f6fd..3e62d60e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -37,17 +37,48 @@ make.inc: RANLIB ?= ranlib prefix ?= /opt/slate +abs_prefix := ${abspath ${prefix}} + # Default LD=ld won't work; use CXX. Can override in make.inc or environment. ifeq ($(origin LD),default) LD = $(CXX) endif +# Use abi-compliance-checker to compare the ABI (application binary +# interface) of 2 releases. Changing the ABI does not necessarily change +# the API (application programming interface). Rearranging a struct or +# changing a by-value argument from int64 to int doesn't change the +# API--no source code changes are required, just a recompile. +# +# if structs or routines are changed or removed: +# bump major version and reset minor, revision = 0; +# else if structs or routines are added: +# bump minor version and reset revision = 0; +# else (e.g., bug fixes): +# bump revision +# +# soversion is major ABI version. +abi_version = 1.0.0 +soversion = ${word 1, ${subst ., ,${abi_version}}} + +#------------------------------------------------------------------------------- # auto-detect OS # $OSTYPE may not be exported from the shell, so echo it ostype := $(shell echo $${OSTYPE}) ifneq ($(findstring darwin, $(ostype)),) # MacOS is darwin macos = 1 + # MacOS needs shared library's path set, and shared library version. + ldflags_shared = -install_name @rpath/${notdir $@} \ + -current_version ${abi_version} \ + -compatibility_version ${soversion} + so = dylib + so2 = .dylib + # on macOS, .dylib comes after version: libfoo.4.dylib +else + so = so + so1 = .so + # on Linux, .so comes before version: libfoo.so.4 endif #------------------------------------------------------------------------------- @@ -55,19 +86,11 @@ endif ifneq ($(static),1) CXXFLAGS += -fPIC LDFLAGS += -fPIC - lib_ext = so + lib_ext = ${so} else lib_ext = a endif -#------------------------------------------------------------------------------- -# MacOS needs shared library's path set -ifeq ($(macos),1) - install_name = -install_name @rpath/$(notdir $@) -else - install_name = -endif - #------------------------------------------------------------------------------- # Files @@ -138,8 +161,7 @@ else endif # Compile TestSweeper before LAPACK++. -$(lib_obj) $(tester_obj): | $(libblaspp) - +${lib_obj} ${tester_obj}: | ${testsweeper} #------------------------------------------------------------------------------- # Get Mercurial id, and make version.o depend on it via .id file. @@ -183,22 +205,22 @@ all: lib tester hooks pkg = lib/pkgconfig/lapackpp.pc -install: lib $(pkg) - mkdir -p $(DESTDIR)$(prefix)/include/lapack - mkdir -p $(DESTDIR)$(prefix)/lib$(LIB_SUFFIX) - mkdir -p $(DESTDIR)$(prefix)/lib$(LIB_SUFFIX)/pkgconfig - cp include/*.hh $(DESTDIR)$(prefix)/include - cp include/lapack/*.h $(DESTDIR)$(prefix)/include/lapack - cp include/lapack/*.hh $(DESTDIR)$(prefix)/include/lapack - cp -R lib/lib* $(DESTDIR)$(prefix)/lib$(LIB_SUFFIX) - cp $(pkg) $(DESTDIR)$(prefix)/lib$(LIB_SUFFIX)/pkgconfig/ - cd $(blaspp_dir) && make install prefix=$(prefix) +install: lib ${pkg} + mkdir -p ${DESTDIR}${abs_prefix}/include/lapack + mkdir -p ${DESTDIR}${abs_prefix}/lib${LIB_SUFFIX} + mkdir -p ${DESTDIR}${abs_prefix}/lib${LIB_SUFFIX}/pkgconfig + cp include/*.hh ${DESTDIR}${abs_prefix}/include + cp include/lapack/*.h ${DESTDIR}${abs_prefix}/include/lapack + cp include/lapack/*.hh ${DESTDIR}${abs_prefix}/include/lapack + cp -av ${lib_name}.* ${DESTDIR}${abs_prefix}/lib${LIB_SUFFIX} + cp ${pkg} ${DESTDIR}${abs_prefix}/lib${LIB_SUFFIX}/pkgconfig + cd ${blaspp_dir} && make install prefix=${abs_prefix} uninstall: - $(RM) $(DESTDIR)$(prefix)/include/lapack.hh - $(RM) -r $(DESTDIR)$(prefix)/include/lapack - $(RM) $(DESTDIR)$(prefix)/lib$(LIB_SUFFIX)/liblapackpp.* - $(RM) $(DESTDIR)$(prefix)/lib$(LIB_SUFFIX)/pkgconfig/lapackpp.pc + ${RM} ${DESTDIR}${abs_prefix}/include/lapack.hh + ${RM} -r ${DESTDIR}${abs_prefix}/include/lapack + ${RM} ${DESTDIR}${abs_prefix}/lib${LIB_SUFFIX}/${notdir ${lib_name}.*} + ${RM} ${DESTDIR}${abs_prefix}/lib${LIB_SUFFIX}/pkgconfig/lapackpp.pc #------------------------------------------------------------------------------- # if re-configured, recompile everything @@ -206,13 +228,21 @@ $(lib_obj) $(tester_obj): make.inc #------------------------------------------------------------------------------- # LAPACK++ library -lib_a = lib/liblapackpp.a -lib_so = lib/liblapackpp.so -lib = lib/liblapackpp.$(lib_ext) +lib_name = lib/liblapackpp +lib_a = ${lib_name}.a +lib_so = ${lib_name}.${so} +lib = ${lib_name}.${lib_ext} -$(lib_so): $(lib_obj) - mkdir -p lib - $(LD) $(LDFLAGS) -shared $(install_name) $(lib_obj) $(LIBS) -o $@ +# libfoo.so.3 or libfoo.3.dylib +lib_so_abi_version = ${lib_name}${so1}.${abi_version}${so2} +lib_so_soversion = ${lib_name}${so1}.${soversion}${so2} + +${lib_so_abi_version}: ${lib_obj} + ${LD} ${LDFLAGS} -shared ${ldflags_shared} ${lib_obj} ${LIBS} -o $@ + +${lib_so}: | ${lib_so_abi_version} + ln -fs ${notdir ${lib_so_abi_version}} ${lib_so} + ln -fs ${notdir ${lib_so_abi_version}} ${lib_so_soversion} $(lib_a): $(lib_obj) mkdir -p lib @@ -224,7 +254,7 @@ $(lib_a): $(lib_obj) lib src: $(lib) lib/clean src/clean: - $(RM) lib/*.a lib/*.so src/*.o + ${RM} ${lib_name}.* src/*.o #------------------------------------------------------------------------------- # tester @@ -274,7 +304,7 @@ LDFLAGS_clean = $(filter-out -fPIC, $(LDFLAGS)) .PHONY: $(pkg) $(pkg): perl -pe "s'#VERSION'2023.11.05'; \ - s'#PREFIX'${prefix}'; \ + s'#PREFIX'${abs_prefix}'; \ s'#CXX\b'${CXX}'; \ s'#CXXFLAGS'${CXXFLAGS_clean}'; \ s'#CPPFLAGS'${CPPFLAGS_clean}'; \ @@ -354,10 +384,15 @@ echo: @echo "static = '$(static)'" @echo "id = '$(id)'" @echo "last_id = '$(last_id)'" + @echo "abi_version = '${abi_version}'" + @echo "soversion = '${soversion}'" @echo + @echo "lib_name = ${lib_name}" @echo "lib_a = $(lib_a)" @echo "lib_so = $(lib_so)" @echo "lib = $(lib)" + @echo "lib_so_abi_version = ${lib_so_abi_version}" + @echo "lib_so_soversion = ${lib_so_soversion}" @echo @echo "lib_src = $(lib_src)" @echo @@ -385,6 +420,7 @@ echo: @echo "LD = $(LD)" @echo "LDFLAGS = $(LDFLAGS)" @echo "LIBS = $(LIBS)" + @echo "ldflags_shared = ${ldflags_shared}" @echo @echo "TEST_LDFLAGS = $(TEST_LDFLAGS)" @echo "TEST_LIBS = $(TEST_LIBS)"