From 3f47d163af06c1aaf03aa38a296f25f27c91e5ce Mon Sep 17 00:00:00 2001 From: Francois-Rene Rideau Date: Wed, 21 Dec 2016 12:03:07 -0500 Subject: [PATCH] New feature sb-linkable-runtime Add the new feature sb-linkable-runtime, that depends on sb-dynamic-core, the sbcl build will create a file sbcl.o or libsbcl.a that you can link with additional other object files and libraries to deliver your applications as a single executable (after combining with a core file) that contains whatever statically linked C libraries you need as extensions. CFFI-toolchain and Bazel will be know how to use this features. Support this feature on Linux, macOS and Windows, on x86 and x86-64. Dump the parameters to compile C code and link it into a file sbcl.mk. This new file will be included even if sb-linkable-runtime isn't present, so CFFI and other software will not have to guess with what compiler and what options to build dynamically linkable extensions. Note that without a sb-linkable-runtime, SBCL can still dlopen the C code, but then you need at least two files to deliver an application with non-Lisp code, and that doesn't work if the code is provided as a *.a or *.o file (not a *.so) compiled without -fPIC. Fix https://bugs.launchpad.net/sbcl/+bug/1500628 better than the previous attempt, which was reverted in commit a61d893a7fbe80905e9e056cc37c47d476074c36. --- .gitignore | 2 ++ install.sh | 4 ++++ make-config.sh | 1 + src/cold/shared.lisp | 6 ++++++ src/runtime/Config.ppc-darwin | 5 +++++ src/runtime/Config.x86-64-darwin | 6 +++++- src/runtime/Config.x86-64-linux | 5 +++++ src/runtime/Config.x86-64-win32 | 11 ++++++++-- src/runtime/Config.x86-darwin | 4 ++++ src/runtime/Config.x86-linux | 6 ++++++ src/runtime/Config.x86-win32 | 11 +++++++++- src/runtime/GNUmakefile | 44 ++++++++++++++++++++++++++++++++-------- 12 files changed, 92 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 56ca003..1eea734 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.d *.dSYM *.o +*.a *.fasl *.FASL *.lisp-temp @@ -26,6 +27,7 @@ src/runtime/openbsd-sigcontext.h src/runtime/sbcl src/runtime/sbcl.exe src/runtime/sbcl.h +src/runtime/sbcl.mk src/runtime/sbcl.nm src/runtime/target-arch-os.h src/runtime/target-arch.h diff --git a/install.sh b/install.sh index d135fa0..dc737e6 100755 --- a/install.sh +++ b/install.sh @@ -66,6 +66,10 @@ test -f "$BUILD_ROOT$SBCL_HOME"/sbcl.core && \ cp src/runtime/$RUNTIME "$BUILD_ROOT$INSTALL_ROOT"/bin/ cp output/sbcl.core "$BUILD_ROOT$SBCL_HOME"/sbcl.core +cp src/runtime/sbcl.mk "$BUILD_ROOT$SBCL_HOME"/sbcl.mk +for i in $(grep '^LIBSBCL=' src/runtime/sbcl.mk | cut -d= -f2-) ; do + cp "src/runtime/$i" "$BUILD_ROOT$SBCL_HOME/$i" +done # installing contrib diff --git a/make-config.sh b/make-config.sh index ff35f6b..383056c 100755 --- a/make-config.sh +++ b/make-config.sh @@ -463,6 +463,7 @@ fi original_dir=`pwd` cd ./src/runtime/ rm -f Config target-arch-os.h target-arch.h target-os.h target-lispregs.h +rm -f sbcl.mk sbcl.o libsbcl.a # KLUDGE: these two logically belong in the previous section # ("architecture-dependent"); it seems silly to enforce this in terms # of the shell script, though. -- CSR, 2002-02-03 diff --git a/src/cold/shared.lisp b/src/cold/shared.lisp index a382d90..172d96e 100644 --- a/src/cold/shared.lisp +++ b/src/cold/shared.lisp @@ -211,6 +211,12 @@ ;; updated to take the additional indirection into account. ;; Let's avoid this unusual combination. ":SB-DYNAMIC-CORE requires :LINKAGE-TABLE and :SB-THREAD") + ("(and sb-linkable-runtime (not sb-dynamic-core))" + ":SB-LINKABLE-RUNTIME requires :SB-DYNAMIC-CORE") + ("(and sb-linkable-runtime (not (or x86 x86-64)))" + ":SB-LINKABLE-RUNTIME not supported on selected architecture") + ("(and sb-linkable-runtime (not (or darwin linux win32)))" + ":SB-LINKABLE-RUNTIME not supported on selected operating system") ("(and sb-eval sb-fasteval)" ;; It sorta kinda works to have both, but there should be no need, ;; and it's not really supported. diff --git a/src/runtime/Config.ppc-darwin b/src/runtime/Config.ppc-darwin index 8b08336..e9a9c1d 100644 --- a/src/runtime/Config.ppc-darwin +++ b/src/runtime/Config.ppc-darwin @@ -32,6 +32,11 @@ else GC_SRC = cheneygc.c endif +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = libsbcl.a + USE_LIBSBCL = -Wl,-force_load libsbcl.a +endif + .PHONY: after-grovel-headers # Nothing to do. diff --git a/src/runtime/Config.x86-64-darwin b/src/runtime/Config.x86-64-darwin index 6f1a664..f160f70 100644 --- a/src/runtime/Config.x86-64-darwin +++ b/src/runtime/Config.x86-64-darwin @@ -44,13 +44,17 @@ endif ifndef LISP_FEATURE_SB_DYNAMIC_CORE LINKFLAGS +=-Wl,-no_pie endif +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = libsbcl.a + USE_LIBSBCL = -Wl,-force_load libsbcl.a +endif ASSEM_SRC = x86-64-assem.S ldso-stubs.S ARCH_SRC = x86-64-arch.c LINKFLAGS += -arch x86_64 -dynamic -twolevel_namespace -bind_at_load -pagezero_size 0x100000 -CFLAGS += -arch x86_64 -fno-omit-frame-pointer -pagezero_size 0x100000 +CFLAGS += -arch x86_64 -fno-omit-frame-pointer ifdef LISP_FEATURE_IMMOBILE_SPACE GC_SRC = gencgc.c marknsweepgc.c diff --git a/src/runtime/Config.x86-64-linux b/src/runtime/Config.x86-64-linux index 6ab3418..5784185 100644 --- a/src/runtime/Config.x86-64-linux +++ b/src/runtime/Config.x86-64-linux @@ -50,6 +50,11 @@ else GC_SRC = gencgc.c endif +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = sbcl.o + USE_LIBSBCL = sbcl.o +endif + # Nothing to do for after-grovel-headers. .PHONY: after-grovel-headers after-grovel-headers: diff --git a/src/runtime/Config.x86-64-win32 b/src/runtime/Config.x86-64-win32 index 4d3027d..ee2079b 100644 --- a/src/runtime/Config.x86-64-win32 +++ b/src/runtime/Config.x86-64-win32 @@ -14,6 +14,11 @@ ARCH_SRC = x86-64-arch.c OS_SRC = win32-os.c x86-64-win32-os.c os-common.c pthreads_win32.c +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = libsbcl.a + USE_LIBSBCL = -Wl,--whole-archive libsbcl.a -Wl,--no-whole-archive +endif + # The "--Wl,--export-dynamic" flags are here to help people # experimenting with callbacks from C to SBCL, by allowing linkage to # SBCL src/runtime/*.c symbols from C. Work on this is good, but it's @@ -26,8 +31,10 @@ OS_SRC = win32-os.c x86-64-win32-os.c os-common.c pthreads_win32.c # (You *are* encouraged to design and implement a coherent stable # interface, though.:-| As far as I (WHN 2002-05-19) know, no one is # working on one and it would be a nice thing to have.) -LINKFLAGS = -Wl,-export-all-symbols -Wl,mswin64.def -Wl,mswin.def - +LINKFLAGS = -Wl,-export-all-symbols +LIBSBCL += mswin64.def mswin.def +USE_LIBSBCL += -Wl,mswin64.def -Wl,mswin.def +__LDFLAGS__ = OS_LIBS = -l ws2_32 -ladvapi32 ifdef LISP_FEATURE_SB_CORE_COMPRESSION diff --git a/src/runtime/Config.x86-darwin b/src/runtime/Config.x86-darwin index aa85349..c56ad1d 100644 --- a/src/runtime/Config.x86-darwin +++ b/src/runtime/Config.x86-darwin @@ -37,6 +37,10 @@ endif ifndef LISP_FEATURE_SB_DYNAMIC_CORE LINKFLAGS +=-Wl,-no_pie endif +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = libsbcl.a + USE_LIBSBCL = -Wl,-force_load libsbcl.a +endif ASSEM_SRC = x86-assem.S ldso-stubs.S ARCH_SRC = x86-arch.c diff --git a/src/runtime/Config.x86-linux b/src/runtime/Config.x86-linux index 6f12bc4..a7847b4 100644 --- a/src/runtime/Config.x86-linux +++ b/src/runtime/Config.x86-linux @@ -29,6 +29,8 @@ OS_SRC = linux-os.c x86-linux-os.c # working on one and it would be a nice thing to have.) LINKFLAGS += -Wl,--export-dynamic -m32 OS_LIBS = -ldl +__LDFLAGS__ = -m elf_i386 + ifdef LISP_FEATURE_LARGEFILE CFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 @@ -41,6 +43,10 @@ endif ifdef LISP_FEATURE_SB_CORE_COMPRESSION OS_LIBS += -lz endif +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = sbcl.o + USE_LIBSBCL = sbcl.o +endif GC_SRC = gencgc.c diff --git a/src/runtime/Config.x86-win32 b/src/runtime/Config.x86-win32 index f3d8695..9140f3b 100644 --- a/src/runtime/Config.x86-win32 +++ b/src/runtime/Config.x86-win32 @@ -16,6 +16,11 @@ ARCH_SRC = x86-arch.c OS_SRC = win32-os.c x86-win32-os.c os-common.c pthreads_win32.c +ifdef LISP_FEATURE_SB_LINKABLE_RUNTIME + LIBSBCL = libsbcl.a + USE_LIBSBCL = -Wl,--whole-archive libsbcl.a -Wl,--no-whole-archive +endif + # The "--Wl,--export-dynamic" flags are here to help people # experimenting with callbacks from C to SBCL, by allowing linkage to # SBCL src/runtime/*.c symbols from C. Work on this is good, but it's @@ -28,7 +33,11 @@ OS_SRC = win32-os.c x86-win32-os.c os-common.c pthreads_win32.c # (You *are* encouraged to design and implement a coherent stable # interface, though.:-| As far as I (WHN 2002-05-19) know, no one is # working on one and it would be a nice thing to have.) -LINKFLAGS = -Wl,-export-all-symbols -Wl,mswin.def +LINKFLAGS = -Wl,-export-all-symbols +LIBSBCL += mswin64.def mswin.def +USE_LIBSBCL += -Wl,mswin64.def -Wl,mswin.def +__LDFLAGS__ = + OS_LIBS = -l ws2_32 -ladvapi32 ifdef LISP_FEATURE_SB_CORE_COMPRESSION OS_LIBS += -lz diff --git a/src/runtime/GNUmakefile b/src/runtime/GNUmakefile index 444ae9d..80f8193 100644 --- a/src/runtime/GNUmakefile +++ b/src/runtime/GNUmakefile @@ -21,6 +21,12 @@ LINKFLAGS = -g NM = nm -gp DEPEND_FLAGS = -MM GREP = grep +LD = ld + +# By default, don't make and use a library, just use the object files. +LIBSBCL = $(OBJS) +USE_LIBSBCL = $(OBJS) +__LDFLAGS__ = include ../../output/prefix.def @@ -44,11 +50,7 @@ ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e no-pie),) CFLAGS += -fno-pie LINKFLAGS += -no-pie LDFLAGS += -no-pie -endif -ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e -nopie),) -CFLAGS += -fno-pie -LINKFLAGS += -nopie -LDFLAGS += -nopie +__LDFLAGS__ += -no-pie endif COMMON_SRC = alloc.c backtrace.c breakpoint.c coreparse.c dynbind.c \ @@ -66,10 +68,34 @@ OBJS = $(C_SRC:.c=.o) $(ASSEM_SRC:.S=.o) LIBS = ${OS_LIBS} -lm -targets: $(TARGET) sbcl.nm - -$(TARGET): $(OBJS) - $(CC) ${LINKFLAGS} -o $@ $^ $(LIBS) +targets: $(TARGET) $(OBJTARGET) sbcl.nm sbcl.mk + +$(TARGET): $(LIBSBCL) + $(CC) ${LINKFLAGS} -o $@ $(USE_LIBSBCL) $(LIBS) + +# ld -r -o sbcl.o works on Linux, but not on other platforms. +# On macOS, it fails to keep debug sections. +# On mingw64, it leads to an executable that cannot be executed. +sbcl.o: $(OBJS) + $(LD) $(__LDFLAGS__) -r -o $@ $^ + +libsbcl.a: $(OBJS) + rm -f $@ ; ar rcs $@ $^ + +sbcl.mk: + ( echo 'CC=$(CC)' ; \ + echo 'LD=$(LD)' ; \ + echo 'CFLAGS=$(CFLAGS)' ; \ + echo 'ASFLAGS=$(ASFLAGS)' ; \ + echo 'LINKFLAGS=$(LINKFLAGS)' ; \ + echo 'LDFLAGS=$(LDFLAGS)' ; \ + echo '__LDFLAGS__=$(__LDFLAGS__)' ; \ + echo 'LIBS=$(LIBS)' ; \ + if [ -n '$(LISP_FEATURE_SB_LINKABLE_RUNTIME)' ] ; then \ + echo 'LIBSBCL=$(LIBSBCL)' ; \ + echo 'USE_LIBSBCL=$(USE_LIBSBCL)' ; \ + fi ; \ + : ) > $@ sbcl.nm: $(TARGET) $(NM) $(TARGET) | $(GREP) -v " [FUw] " > ,$@ -- 2.7.4