You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Ralf S. Engelschall" <rs...@engelschall.com> on 1998/05/12 15:01:24 UTC

[PATCH] (for 1.3.1-dev) Link DSO modules against possible libraries from $(LIBS)

[for 1.3.1-dev]

Link DSO modules against possible libraries from $(LIBS)
========================================================

Currently we have the following entry in our dso.html document:

| Because DSO modules cannot be linked against other DSO-based libraries (ld
| -lfoo) on all platforms (for instance a.out-based platforms usually don't
| provide this functionality while ELF-based platforms do) you cannot use the
| DSO mechanism for all types of modules. Or in other words, modules compiled as
| DSO files are restricted to only use symbols from the Apache core, from the C
| library (libc) and all other dynamic or static libraries used by the Apache
| core, or from static library archives (libfoo.a) containing position
| independend code. The only chance to use other code is to either make sure the
| Apache core itself already contains a reference to it or loading the code
| yourself via dlopen().

The important part here is: "cannot be linked .... on all platforms".  But
there _are_ platform which support linking DSO files agains other DSO files.
And even on platforms where this is not possible is it possible to at least
link against libraries containing PIC code.

So, the idea is this: In the configuration process we determine the variable
LDFLAGS and LIBS. They hold -L and -l options for linking executables.  We
parse these options and separate them into three classes: OBJ, PIC and DSO.
And then we re-assemble a LIBS_SHLIB variable from only the options in classes
PIC and DSO. This variable is then used on the build command for mod_xxx.so.

This way we provide the maximum we can provide. Sure, on some platforms the
user has to chance. But this shouldn't mean he becomes no chance on other
platforms where there _is_ a chance. So this patch is a first step for more
support.

FUTURE: As a second step I currently thinking about an emulation of ld.so
inside Apache for mod_xxx.so, i.e. when mod_xxx.so cannot be linked against a
libfoo.so we do the following: We load the needed functions from libfoo
manually for mod_xxx. Together with some preprocessor tricks and a dispatch
table we can accomplish mostly the same effect as -lfoo.

Greetings,
                                       Ralf S. Engelschall
                                       rse@engelschall.com
                                       www.engelschall.com

diff -u -N -r --exclude=.#* --exclude=Entries* --exclude Makefile /e/apache/SRC/apache-1.3/src/Configure apache-1.3-dso/src/Configure
--- /e/apache/SRC/apache-1.3/src/Configure	Tue May 12 14:28:51 1998
+++ apache-1.3-dso/src/Configure	Tue May 12 14:41:09 1998
@@ -793,6 +793,7 @@
     DEF_SHARED_CORE=no
     SHLIB_SUFFIX_DEPTH=all
     SHLIB_EXPORT_FILES=no
+    SHLIB_LIB_LINKING_POSSIBLE=no
     case "$PLAT" in
         *-linux1)
             CFLAGS_SHLIB="-fpic"
@@ -1561,6 +1562,19 @@
 fi
 
 ####################################################################
+## Determine libraries which can be used for DSO linking
+##
+LIBS_SHLIB=''
+if [ "x$using_shlib" = "x1" ] ; then
+    if [ "x$SHLIB_LIB_LINKING_POSSIBLE" = "xyes" ] ; then
+        extra_ldflags="`grep EXTRA_LDFLAGS= Makefile.config`"
+        extra_libs="`grep EXTRA_LIBS= Makefile.config`"
+        eval "`./helpers/slo $LDFLAGS $LIBS $extra_ldflags $extra_libs`"
+        LIBS_SHLIB="$SLO_DIRS_PIC $SLO_LIBS_PIC $SLO_DIRS_DSO $SLO_LIBS_DSO"
+    fi
+fi
+
+####################################################################
 ## Continue building Makefile.config.
 ##
 echo "CFLAGS1=$CFLAGS">> Makefile.config
@@ -1569,6 +1583,7 @@
 echo "INCLUDES0=-I\$(OSDIR) -I\$(INCDIR)">> Makefile.config
 echo "INCLUDES1=$INCLUDES">> Makefile.config
 echo "LIBS1=$LIBS">> Makefile.config
+echo "LIBS_SHLIB=$LIBS_SHLIB">> Makefile.config
 echo "LDFLAGS1=$LDFLAGS">> Makefile.config
 echo "MFLAGS_STATIC=$MFLAGS_STATIC">> Makefile.config
 echo "REGLIB=$REGLIB">> Makefile.config
@@ -1737,7 +1752,7 @@
 
 .c.so:
 	$(CC) -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $< && mv $*.o $*.lo
-	$(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $*.lo
+	$(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $*.lo $(LIBS_SHLIB)
 
 clean:
 	rm -f $(LIB) $(OBJS) $(SHLIBS) $(OBJS_PIC)
diff -u -N -r --exclude=.#* --exclude=Entries* --exclude Makefile /e/apache/SRC/apache-1.3/src/helpers/slo apache-1.3-dso/src/helpers/slo
--- /e/apache/SRC/apache-1.3/src/helpers/slo	Thu Jan  1 01:00:00 1970
+++ apache-1.3-dso/src/helpers/slo	Tue May 12 14:35:06 1998
@@ -0,0 +1,174 @@
+#!/bin/sh
+##
+##  SLO -- separate linker library options by class
+##  Copyright (c) 1998 Ralf S. Engelschall, All Rights Reserved. 
+##
+
+DIFS=' 	
+'
+
+#   
+#   parse out -L and -l options from command line
+#
+DIRS=''
+LIBS=''
+ARGV=''
+optprev=""
+OIFS="$IFS" IFS="$DIFS"
+for opt
+do
+    #   concatenate with previous option if exists
+    if [ ".$optprev" != . ]; then
+        opt="${optprev}${opt}";
+        optprev=''
+    fi
+    #   remember options for arg when used stand-alone
+    if [ ".$opt" = ".-L" -o ".$opt" = ".-l" ]; then
+        optprev="$opt"
+        continue;
+    fi
+	#   split argument into option plus option argument
+    arg="`echo $opt | cut -c3-`"
+    opt="`echo $opt | cut -c1-2`"
+    #   store into containers
+    case $opt in
+        -L) DIRS="$DIRS:$arg" ;;
+        -l) LIBS="$LIBS:$arg" ;;
+         *) ARGV="$ARGV $opt" ;;
+    esac
+done
+IFS="$OIFS"
+
+#
+#   set linker default directories
+#
+DIR_DEFAULT='/lib:/usr/lib'
+if [ ".$LD_LIBRARY_PATH" != . ]; then
+    DIRS_DEFAULT="$DIR_DEFAULT:$LD_LIBRARY_PATH"
+fi
+
+#
+#   sort options by class
+#
+DIRS_OBJ=''
+LIBS_OBJ=''
+DIRS_PIC=''
+LIBS_PIC=''
+DIRS_DSO=''
+LIBS_DSO=''
+
+#    for each library...
+OIFS="$IFS" IFS=':'
+for lib in $LIBS; do
+    [ ".$lib" = . ] && continue
+
+    found='no'
+    found_indefdir='no'
+    found_type=''
+    found_dir=''
+
+    #    for each directory...
+    OIFS2="$IFS" IFS=":$DIFS"
+    for dir in ${DIRS} switch-to-defdirs ${DIRS_DEFAULT}; do
+        [ ".$dir" = . ] && continue
+        [ ".$dir" = .switch-to-defdirs ] && found_indefdir=yes
+        [ ! -d $dir ] && continue
+
+        #    search the file
+        OIFS3="$IFS" IFS="$DIFS"
+        for file in '' `cd $dir && ls lib${lib}.* 2>/dev/null`; do
+             [ ".$file" = . ] && continue
+             case $file in
+                 *.so|*.so.[0-9]*|*.sl|*.sl.[0-9]* )
+                      found=yes;
+                      found_type=DSO; 
+                      break 
+                      ;;
+                 *.lo|*.la )
+                      found=yes;
+                      found_type=PIC 
+                      ;;
+                 *.a )
+                      if [ ".$found_type" = . ]; then
+                          found=yes
+                          found_type=OBJ 
+                      fi
+                      ;;
+             esac
+        done
+        IFS="$OIFS3"
+        if [ ".$found" = .yes ]; then
+            found_dir="$dir"
+            break
+        fi
+    done
+    IFS="$OIFS2"
+
+    if [ ".$found" = .yes ]; then
+        if [ ".$found_indefdir" != .yes ]; then
+            eval "dirlist=\"\${DIRS_${found_type}}:\""
+            if [ ".`echo \"$dirlist\" | fgrep :$found_dir:`" = . ]; then
+                eval "DIRS_${found_type}=\"\$DIRS_${found_type}:${found_dir}\""
+            fi
+            eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
+        else
+            eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
+        fi
+    else
+        LIBS_OBJ="$LIBS_OBJ:$lib"
+        #dirlist="`echo $DIRS $DIRS_DEFAULT | sed -e 's/:/ /g'`"
+        #echo "splitlibs:Warning: library \"$lib\" not found in any of the following dirs:" 2>&1
+        #echo "splitlibs:Warning: $dirlist" 1>&1
+    fi
+done
+IFS="$OIFS"
+
+#
+#   also pass-through unused dirs even if its useless
+#
+OIFS="$IFS" IFS=':'
+for dir in $DIRS; do
+    dirlist="${DIRS_OBJ}:${DIRS_PIC}:${DIRS_DSO}:"
+    if [ ".`echo \"$dirlist\" | fgrep :$dir:`" = . ]; then
+        DIRS_OBJ="$DIRS_OBJ:$dir"
+    fi
+done
+IFS="$OIFS"
+
+#
+#   reassemble the options but seperated by type
+#
+OIFS="$IFS" IFS="$DIFS"
+for type in OBJ PIC DSO; do
+    OIFS2="$IFS" IFS=':'
+    eval "libs=\"\$LIBS_${type}\""
+    opts=''
+    for lib in $libs; do
+        [ ".$lib" = . ] && continue
+        opts="$opts -l$lib"
+    done
+    eval "LIBS_${type}=\"$opts\""
+
+    eval "dirs=\"\$DIRS_${type}\""
+    opts=''
+    for dir in $dirs; do
+        [ ".$dir" = . ] && continue
+        opts="$opts -L$dir"
+    done
+    eval "DIRS_${type}=\"$opts\""
+    IFS="$OIFS2"
+done
+IFS="$OIFS"
+
+#
+#   give back results
+#
+OIFS="$IFS" IFS="$DIFS"
+for var in ARGV DIRS_OBJ LIBS_OBJ DIRS_PIC LIBS_PIC DIRS_DSO LIBS_DSO; do
+    eval "val=\"\$${var}\""
+    val="`echo $val | sed -e 's/^ *//'`"
+    echo "SLO_${var}=\"${val}\""
+done
+IFS="$OIFS"
+
+##EOF##
Binary files /e/apache/SRC/apache-1.3/src/modules/example/mod_example.so and apache-1.3-dso/src/modules/example/mod_example.so differ
Binary files /e/apache/SRC/apache-1.3/src/modules/experimental/mod_mmap_static.so and apache-1.3-dso/src/modules/experimental/mod_mmap_static.so differ
diff -u -N -r --exclude=.#* --exclude=Entries* --exclude Makefile /e/apache/SRC/apache-1.3/src/modules/proxy/Makefile.tmpl apache-1.3-dso/src/modules/proxy/Makefile.tmpl
--- /e/apache/SRC/apache-1.3/src/modules/proxy/Makefile.tmpl	Tue May 12 14:28:53 1998
+++ apache-1.3-dso/src/modules/proxy/Makefile.tmpl	Tue May 12 14:33:55 1998
@@ -19,7 +19,7 @@
 
 libproxy.so: $(OBJS_PIC)
 	rm -f $@
-	$(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $(OBJS_PIC)
+	$(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $(OBJS_PIC) $(LIBS_SHLIB)
 
 .SUFFIXES: .o .lo
 
Binary files /e/apache/SRC/apache-1.3/src/modules/standard/mod_auth_db.so and apache-1.3-dso/src/modules/standard/mod_auth_db.so differ
Binary files /e/apache/SRC/apache-1.3/src/modules/standard/mod_log_agent.so and apache-1.3-dso/src/modules/standard/mod_log_agent.so differ
Binary files /e/apache/SRC/apache-1.3/src/modules/standard/mod_log_referer.so and apache-1.3-dso/src/modules/standard/mod_log_referer.so differ
diff -u -N -r --exclude=.#* --exclude=Entries* --exclude Makefile /e/apache/SRC/apache-1.3/src/support/Makefile.tmpl apache-1.3-dso/src/support/Makefile.tmpl
--- /e/apache/SRC/apache-1.3/src/support/Makefile.tmpl	Tue May 12 14:28:55 1998
+++ apache-1.3-dso/src/support/Makefile.tmpl	Tue May 12 14:35:43 1998
@@ -31,10 +31,11 @@
 apxs: apxs.pl
 	sed <apxs.pl >apxs \
 	    -e 's%@CC@%$(CC)%g' \
-	    -e 's%@LD_SHLIB@%$(LD_SHLIB)%g' \
 	    -e 's%@CFLAGS@%$(CFLAGS)%g' \
 	    -e 's%@CFLAGS_SHLIB@%$(CFLAGS_SHLIB)%g' \
-	    -e 's%@LDFLAGS_SHLIB@%$(LDFLAGS_SHLIB)%g' && chmod a+x apxs
+	    -e 's%@LD_SHLIB@%$(LD_SHLIB)%g' \
+	    -e 's%@LDFLAGS_SHLIB@%$(LDFLAGS_SHLIB)%g' \
+	    -e 's%@LIBS_SHLIB@%$(LIBS_SHLIB)%g' && chmod a+x apxs
 
 suexec: suexec.o
 	$(CC) $(CFLAGS) suexec.o -o suexec $(LDFLAGS) $(LIBS)
diff -u -N -r --exclude=.#* --exclude=Entries* --exclude Makefile /e/apache/SRC/apache-1.3/src/support/apxs.pl apache-1.3-dso/src/support/apxs.pl
--- /e/apache/SRC/apache-1.3/src/support/apxs.pl	Tue May 12 14:28:55 1998
+++ apache-1.3-dso/src/support/apxs.pl	Tue May 12 14:37:20 1998
@@ -73,6 +73,7 @@
 my $CFG_CFLAGS_SHLIB  = '@CFLAGS_SHLIB@';  # substituted via Makefile.tmpl
 my $CFG_LD_SHLIB      = '@LD_SHLIB@';      # substituted via Makefile.tmpl
 my $CFG_LDFLAGS_SHLIB = '@LDFLAGS_SHLIB@'; # substituted via Makefile.tmpl 
+my $CFG_LIBS_SHLIB    = '@LIBS_SHLIB@';    # substituted via Makefile.tmpl 
 my $CFG_PREFIX        = '@prefix@';        # substituted via APACI install
 my $CFG_SBINDIR       = '@sbindir@';       # substituted via APACI install
 my $CFG_INCLUDEDIR    = '@includedir@';    # substituted via APACI install
@@ -352,6 +353,7 @@
         $opt .= " -l$opt_l";
     }
     $cmd .= $opt;
+    $cmd .= " $CFG_LIBS_SHLIB";
     push(@cmds, $cmd);
 
     #   execute the commands