From 53f5f1575a6fd89ff666f9adb393309997bdfe6c Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 28 Aug 2024 09:25:30 +0100 Subject: [PATCH 1/6] buildsys: always link gap against libgap ... even the copy we don't install system wide. On macOS this allows us an annoying issue with the linker flags used by e.g. gac for building kernel extensions: by always linking them against libgap we don't need to use a flat namespace, nor rely on a bundle loader (which breaks if you try to load the kernel extension in another binary using libgap). --- Makefile.rules | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile.rules b/Makefile.rules index ffe22eb1ba..0db16d7908 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -316,10 +316,12 @@ ifneq (,$(findstring cygwin,$(host_os))) else ifneq (,$(findstring darwin,$(host_os))) GAC_CFLAGS = -fno-common - GAC_LDFLAGS = -bundle -undefined dynamic_lookup -Wl,-no_fixup_chains + GAC_LDFLAGS = -bundle -L$(abs_builddir) -lgap + GAC_LDFLAGS_FOR_INSTALL = -bundle -L$(libdir) -lgap else GAC_CFLAGS = -fPIC - GAC_LDFLAGS = -shared -fPIC + GAC_LDFLAGS = -shared -fPIC -L$(abs_builddir) -lgap + GAC_LDFLAGS_FOR_INSTALL = -shared -fPIC -L$(libdir) -lgap endif endif @@ -518,8 +520,8 @@ libgap$(SHLIB_EXT): $(LIBGAP_FULL) ln -sf $< $@ # build rule for the main gap executable -gap$(EXEEXT): build/obj/src/main.c.o $(OBJS) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(OBJS) $(GAP_LIBS) -o $@ +gap$(EXEEXT): build/obj/src/main.c.o libgap$(SHLIB_EXT) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(GAP_LIBS) -L${abs_builddir} -lgap -o $@ # generate a special main.c which sets SYS_DEFAULT_PATHS and then includes # regular main.c; this is used to build the `gap-install` binary @@ -686,6 +688,7 @@ install-sysinfo: SYSINFO_CPPFLAGS = -I${includedir}/gap/extra $(GAP_DEFINES) install-sysinfo: SYSINFO_LDFLAGS = $(ABI_CFLAGS) install-sysinfo: SYSINFO_GAP = $(bindir)/gap install-sysinfo: SYSINFO_GAC = $(bindir)/gac +install-sysinfo: GAC_LDFLAGS = $(GAC_LDFLAGS_FOR_INSTALL) install-sysinfo: GMP_PREFIX = install-sysinfo: install-dirs @echo "$$sysinfo_gap" > $(DESTDIR)$(libdir)/gap/sysinfo.gap From 4333335f0e13f5d517d5260cb1869c138012898a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 6 Sep 2024 13:19:26 +0200 Subject: [PATCH 2/6] WIP-rpath --- Makefile.rules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.rules b/Makefile.rules index 0db16d7908..8cf50b0ebc 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -448,6 +448,7 @@ ifneq (,$(findstring cygwin,$(host_os))) LIBGAP_FULL = libgap$(SHLIB_EXT) LINK_SHLIB_FLAGS = -shared -Wl,--enable-auto-image-base -Wl,--out-implib,libgap.dll.a + GAP_LDFLAGS += -Wl,-rpath,$(libdir) else ifneq (,$(findstring darwin,$(host_os))) SHLIB_EXT=.dylib LIBGAP_FULL = libgap.$(SHLIB_MAJOR)$(SHLIB_EXT) @@ -463,6 +464,7 @@ else ifneq (,$(findstring darwin,$(host_os))) GAP_CPPFLAGS += -DPIC GAP_CFLAGS += -fno-common GAP_CXXFLAGS += -fno-common + GAP_LDFLAGS += -Wl,-rpath,$(libdir) else # Note: the following was tested on Linux -- patches making this work better # on e.g. FreeBSD/OpenBSD/... are highly welcome From 039a384dfef7bc11d068f3eebf65ed31e58ba32a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 23 Jun 2025 23:20:12 +0200 Subject: [PATCH 3/6] WIP-hack --- Makefile.rules | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Makefile.rules b/Makefile.rules index 8cf50b0ebc..8cf66a8356 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -448,7 +448,6 @@ ifneq (,$(findstring cygwin,$(host_os))) LIBGAP_FULL = libgap$(SHLIB_EXT) LINK_SHLIB_FLAGS = -shared -Wl,--enable-auto-image-base -Wl,--out-implib,libgap.dll.a - GAP_LDFLAGS += -Wl,-rpath,$(libdir) else ifneq (,$(findstring darwin,$(host_os))) SHLIB_EXT=.dylib LIBGAP_FULL = libgap.$(SHLIB_MAJOR)$(SHLIB_EXT) @@ -459,12 +458,12 @@ else ifneq (,$(findstring darwin,$(host_os))) LINK_SHLIB_FLAGS += -current_version $(LIBGAP_CURRENT_VER) LINK_SHLIB_FLAGS += -Wl,-single_module LINK_SHLIB_FLAGS += -Wl,-headerpad_max_install_names + LINK_SHLIB_FLAGS += -Wl,-install_name,$(abs_builddir)/$(LIBGAP_FULL) GAP_INSTALL_EXTRAFLAGS = -Wl,-headerpad_max_install_names GAP_CPPFLAGS += -DPIC GAP_CFLAGS += -fno-common GAP_CXXFLAGS += -fno-common - GAP_LDFLAGS += -Wl,-rpath,$(libdir) else # Note: the following was tested on Linux -- patches making this work better # on e.g. FreeBSD/OpenBSD/... are highly welcome @@ -489,7 +488,7 @@ libgap: libgap$(SHLIB_EXT) $(LIBGAP_FULL) # Linking rule and dependencies for libgap $(LIBGAP_FULL): $(OBJS) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) -o $@ $(LINK_SHLIB_FLAGS) $(GAP_LDFLAGS) $(OBJS) $(GAP_LIBS) + $(QUIET_LINK)$(LINK) -o $@ $(LINK_SHLIB_FLAGS) $(GAP_LDFLAGS) -Wl,-rpath,$(abs_builddir) $(OBJS) $(GAP_LIBS) ifneq (,$(findstring cygwin,$(host_os))) @@ -523,7 +522,7 @@ libgap$(SHLIB_EXT): $(LIBGAP_FULL) # build rule for the main gap executable gap$(EXEEXT): build/obj/src/main.c.o libgap$(SHLIB_EXT) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(GAP_LIBS) -L${abs_builddir} -lgap -o $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(GAP_LIBS) -Wl,-rpath,$(abs_builddir) -L${abs_builddir} -lgap -o $@ # generate a special main.c which sets SYS_DEFAULT_PATHS and then includes # regular main.c; this is used to build the `gap-install` binary @@ -533,7 +532,7 @@ build/main.c: sysinfo.gap # build rule for the gap executable used by the `install-bin` target build/gap-install: build/obj/build/main.c.o libgap$(SHLIB_EXT) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $(GAP_INSTALL_EXTRAFLAGS) $< $(GAP_LIBS) -L${abs_builddir} -lgap -o $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $(GAP_INSTALL_EXTRAFLAGS) -Wl,-rpath,$(libdir) $< $(GAP_LIBS) -L${abs_builddir} -lgap -o $@ $(INSTALL_NAME_TOOL) -change $(LIBGAP_FULL) $(libdir)/$(LIBGAP_FULL) $@ endif From b068a69d0545c07a81983ad0da9945121dfa13e6 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 23 Jun 2025 23:39:49 +0200 Subject: [PATCH 4/6] Better debug output for testmakeinstall --- dev/ci.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/ci.sh b/dev/ci.sh index e45ca39268..e2c4698521 100755 --- a/dev/ci.sh +++ b/dev/ci.sh @@ -309,8 +309,11 @@ GAPInput strip $GAPPREFIX/bin/gap > /dev/null strip $GAPPREFIX/lib/libgap.so > /dev/null 2>&1 || : # for Linux strip -S $GAPPREFIX/lib/libgap.dylib > /dev/null 2>&1 || : # for macOS + echo "Check if BUILDDIR=$BUILDDIR occurs in $GAPPREFIX" fgrep -r $BUILDDIR $GAPPREFIX && exit 1 + echo "Check if SRCDIR=$SRCDIR occurs in $GAPPREFIX" fgrep -r $SRCDIR $GAPPREFIX && exit 1 + echo "Check if HOME=$HOME occurs in $GAPPREFIX" fgrep -r $HOME $GAPPREFIX && exit 1 # HACK: symlink packages so we can start GAP From f82cd6f958fba33946eac54ccd1b27d7dab8b97c Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 5 May 2026 18:16:16 +0100 Subject: [PATCH 5/6] buildsys: clean up libgap runtime paths Centralize how GAP links against libgap and carries runtime search paths for the build tree and installed binaries. This keeps the build-tree Linux case working while preserving the always-link-against-libgap setup for gac and installed tools. Normalize compiler-expanded file paths in out-of-tree builds so installed libgap binaries no longer embed absolute source or build paths. The install test no longer needs LD_LIBRARY_PATH or DYLD_LIBRARY_PATH once the binaries carry the right loader metadata themselves. AI-assisted with Codex for build-system edits and Linux verification. Co-authored-by: Codex --- Makefile.rules | 50 +++++++++++++++++++++++++++++++------------------- dev/ci.sh | 4 ---- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Makefile.rules b/Makefile.rules index 8cf66a8356..0c55cce38b 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -212,6 +212,13 @@ SYSINFO_CPPFLAGS += -I$(abs_srcdir)/src/extra GAP_CPPFLAGS += $(GAP_DEFINES) SYSINFO_CPPFLAGS += $(GAP_DEFINES) +# Normalize __FILE__ expansions so installed binaries do not embed absolute +# source or build paths from out-of-tree builds. +GAP_CPPFLAGS += -fmacro-prefix-map=$(abs_srcdir)/= +GAP_CPPFLAGS += -fmacro-prefix-map=$(abs_builddir)/= +GAP_CPPFLAGS += -ffile-prefix-map=$(abs_srcdir)/= +GAP_CPPFLAGS += -ffile-prefix-map=$(abs_builddir)/= + # Add flags for dependencies GAP_CPPFLAGS += $(GMP_CPPFLAGS) GAP_CPPFLAGS += $(ZLIB_CPPFLAGS) @@ -309,6 +316,7 @@ GAP_LIBS += $(LIBS) ifneq (,$(findstring cygwin,$(host_os))) GAC_CFLAGS = GAC_LDFLAGS = -shared -Wl,$(abs_builddir)/bin/$(GAPARCH)/gap.dll -Wl,--enable-auto-image-base + GAC_LDFLAGS_FOR_INSTALL = $(GAC_LDFLAGS) # Note: the above won't be correct after "make install"; but then I am not # sure we care about "make install" on Cygwin, so I am not going to work on # this until someone specifically asks for it (and even then I'll require @@ -316,12 +324,12 @@ ifneq (,$(findstring cygwin,$(host_os))) else ifneq (,$(findstring darwin,$(host_os))) GAC_CFLAGS = -fno-common - GAC_LDFLAGS = -bundle -L$(abs_builddir) -lgap - GAC_LDFLAGS_FOR_INSTALL = -bundle -L$(libdir) -lgap + GAC_LDFLAGS = -bundle $(LIBGAP_BUILD_LDFLAGS) + GAC_LDFLAGS_FOR_INSTALL = -bundle $(LIBGAP_INSTALL_LDFLAGS) else GAC_CFLAGS = -fPIC - GAC_LDFLAGS = -shared -fPIC -L$(abs_builddir) -lgap - GAC_LDFLAGS_FOR_INSTALL = -shared -fPIC -L$(libdir) -lgap + GAC_LDFLAGS = -shared -fPIC $(LIBGAP_BUILD_LDFLAGS) + GAC_LDFLAGS_FOR_INSTALL = -shared -fPIC $(LIBGAP_INSTALL_LDFLAGS) endif endif @@ -441,7 +449,6 @@ build/obj/%.c.o: %.c cnf/GAP-CFLAGS cnf/GAP-CPPFLAGS $(obj_deps) ######################################################################## LINK=$(CC) -GAP_INSTALL_EXTRAFLAGS = SHLIB_MAJOR = $(GAP_KERNEL_MAJOR_VERSION) ifneq (,$(findstring cygwin,$(host_os))) SHLIB_EXT=.dll @@ -457,9 +464,7 @@ else ifneq (,$(findstring darwin,$(host_os))) LINK_SHLIB_FLAGS += -compatibility_version $(LIBGAP_COMPAT_VER) LINK_SHLIB_FLAGS += -current_version $(LIBGAP_CURRENT_VER) LINK_SHLIB_FLAGS += -Wl,-single_module - LINK_SHLIB_FLAGS += -Wl,-headerpad_max_install_names - LINK_SHLIB_FLAGS += -Wl,-install_name,$(abs_builddir)/$(LIBGAP_FULL) - GAP_INSTALL_EXTRAFLAGS = -Wl,-headerpad_max_install_names + LINK_SHLIB_FLAGS += -Wl,-install_name,@rpath/$(LIBGAP_FULL) GAP_CPPFLAGS += -DPIC GAP_CFLAGS += -fno-common @@ -477,10 +482,18 @@ else GAP_LDFLAGS += -Wl,--export-dynamic endif -ifneq (,$(findstring darwin,$(host_os))) -INSTALL_NAME_TOOL = @install_name_tool +# Build-tree and installed targets intentionally use different runtime search +# paths, but both link against libgap through these centralized variables. +LIBGAP_BUILD_LDFLAGS = $(abs_builddir)/libgap$(SHLIB_EXT) +LIBGAP_INSTALL_LDFLAGS = -L$(libdir) -lgap +LIBGAP_BUILD_RPATH = +LIBGAP_INSTALL_RPATH = + +ifneq (,$(findstring cygwin,$(host_os))) + LIBGAP_BUILD_LDFLAGS = -L$(abs_builddir) -lgap else -INSTALL_NAME_TOOL = @echo > /dev/null + LIBGAP_BUILD_RPATH = -Wl,-rpath,$(abs_builddir) + LIBGAP_INSTALL_RPATH = -Wl,-rpath,$(libdir) endif libgap: libgap$(SHLIB_EXT) $(LIBGAP_FULL) @@ -488,7 +501,7 @@ libgap: libgap$(SHLIB_EXT) $(LIBGAP_FULL) # Linking rule and dependencies for libgap $(LIBGAP_FULL): $(OBJS) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) -o $@ $(LINK_SHLIB_FLAGS) $(GAP_LDFLAGS) -Wl,-rpath,$(abs_builddir) $(OBJS) $(GAP_LIBS) + $(QUIET_LINK)$(LINK) -o $@ $(LINK_SHLIB_FLAGS) $(GAP_LDFLAGS) $(OBJS) $(GAP_LIBS) ifneq (,$(findstring cygwin,$(host_os))) @@ -510,7 +523,7 @@ bin/$(GAPARCH)/gap.dll: libgap$(SHLIB_EXT) # build rule for the main gap executable gap$(EXEEXT): build/obj/src/main.c.o libgap$(SHLIB_EXT) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) -Wl,--export-all-symbols $< $(GAP_LIBS) -L${abs_builddir} -lgap -o $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) -Wl,--export-all-symbols $< $(GAP_LIBS) $(LIBGAP_BUILD_RPATH) $(LIBGAP_BUILD_LDFLAGS) -o $@ @( if which peflags > /dev/null ; then peflags --cygwin-heap=2048 gap$(EXEEXT) ; fi ) else @@ -522,7 +535,7 @@ libgap$(SHLIB_EXT): $(LIBGAP_FULL) # build rule for the main gap executable gap$(EXEEXT): build/obj/src/main.c.o libgap$(SHLIB_EXT) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(GAP_LIBS) -Wl,-rpath,$(abs_builddir) -L${abs_builddir} -lgap -o $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(GAP_LIBS) $(LIBGAP_BUILD_RPATH) $(LIBGAP_BUILD_LDFLAGS) -o $@ # generate a special main.c which sets SYS_DEFAULT_PATHS and then includes # regular main.c; this is used to build the `gap-install` binary @@ -532,8 +545,7 @@ build/main.c: sysinfo.gap # build rule for the gap executable used by the `install-bin` target build/gap-install: build/obj/build/main.c.o libgap$(SHLIB_EXT) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $(GAP_INSTALL_EXTRAFLAGS) -Wl,-rpath,$(libdir) $< $(GAP_LIBS) -L${abs_builddir} -lgap -o $@ - $(INSTALL_NAME_TOOL) -change $(LIBGAP_FULL) $(libdir)/$(LIBGAP_FULL) $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $< $(GAP_LIBS) $(LIBGAP_INSTALL_RPATH) $(LIBGAP_BUILD_LDFLAGS) -o $@ endif @@ -1019,7 +1031,7 @@ build-testlibgap: ${LIBGAPTESTS} # run a test in tst/testlibgap tst/testlibgap/%: build/obj/tst/testlibgap/%.c.o build/obj/tst/testlibgap/common.c.o libgap$(SHLIB_EXT) - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) -Wl,-rpath,$(abs_builddir) $^ $(GAP_LIBS) -o $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $(LIBGAP_BUILD_RPATH) $^ $(GAP_LIBS) -o $@ clean: clean-testlibgap clean-testlibgap: @@ -1050,7 +1062,7 @@ testpkgconfigbuild: install-libgap install-headers $(eval com := "tst/testlibgap/common") $(CC) -c $(v).c -o $(v).o $(PKG_REPORTED_CFLAGS) $(CC) -c $(com).c -o $(com).o $(PKG_REPORTED_CFLAGS) - $(QUIET_LINK)$(LINK) $(v).o -o $(v) $(com).o $(PKG_REPORTED_LDFLAGS) -Wl,-rpath,$(abs_builddir) + $(QUIET_LINK)$(LINK) $(v).o -o $(v) $(com).o $(PKG_REPORTED_LDFLAGS) $(LIBGAP_INSTALL_RPATH) $(v) -A -l $(top_srcdir) -q -T --nointeract >$(v).out && \ diff $(top_srcdir)/$(v).expect $(v).out @@ -1061,7 +1073,7 @@ build-testkernel: ${KERNELTESTS} # run a test in tst/testkernel tst/testkernel/%: build/obj/tst/testkernel/%.c.o libgap$(SHLIB_EXT) - $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) -Wl,-rpath,$(abs_builddir) $^ $(GAP_LIBS) -o $@ + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) $(LIBGAP_BUILD_RPATH) $^ $(GAP_LIBS) -o $@ clean: clean-testkernel clean-testkernel: diff --git a/dev/ci.sh b/dev/ci.sh index e2c4698521..f6c9fd6394 100755 --- a/dev/ci.sh +++ b/dev/ci.sh @@ -319,10 +319,6 @@ GAPInput # HACK: symlink packages so we can start GAP ln -s $SRCDIR/pkg $GAPPREFIX/share/gap/pkg - # ensure the dynamic linker finds the install libgap in our custom prefix - export LD_LIBRARY_PATH="$GAPPREFIX/lib" - export DYLD_LIBRARY_PATH="$GAPPREFIX/lib" - # test building and loading package kernel extension testmockpkg "$GAPPREFIX/bin/gap" "$GAPPREFIX/lib/gap" "$SRCDIR/tst/mockpkg" From d757e62d1e9d4b36907895d97321608e0f72432a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 11 May 2026 23:48:52 +0200 Subject: [PATCH 6/6] Don't use prefix-map command line arguments --- Makefile.rules | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Makefile.rules b/Makefile.rules index 0c55cce38b..f8720986a7 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -212,13 +212,6 @@ SYSINFO_CPPFLAGS += -I$(abs_srcdir)/src/extra GAP_CPPFLAGS += $(GAP_DEFINES) SYSINFO_CPPFLAGS += $(GAP_DEFINES) -# Normalize __FILE__ expansions so installed binaries do not embed absolute -# source or build paths from out-of-tree builds. -GAP_CPPFLAGS += -fmacro-prefix-map=$(abs_srcdir)/= -GAP_CPPFLAGS += -fmacro-prefix-map=$(abs_builddir)/= -GAP_CPPFLAGS += -ffile-prefix-map=$(abs_srcdir)/= -GAP_CPPFLAGS += -ffile-prefix-map=$(abs_builddir)/= - # Add flags for dependencies GAP_CPPFLAGS += $(GMP_CPPFLAGS) GAP_CPPFLAGS += $(ZLIB_CPPFLAGS)