[gs-cvs] rev 7910 - trunk/gs/src

till at ghostscript.com till at ghostscript.com
Tue May 8 09:26:20 PDT 2007


Author: till
Date: 2007-05-08 09:26:19 -0700 (Tue, 08 May 2007)
New Revision: 7910

Modified:
   trunk/gs/src/Makefile.in
   trunk/gs/src/devs.mak
   trunk/gs/src/gconf.c
   trunk/gs/src/gdevl256.c
   trunk/gs/src/gdevvglb.c
   trunk/gs/src/gdevxalt.c
   trunk/gs/src/gp_unix.c
   trunk/gs/src/gs.mak
   trunk/gs/src/lib.mak
   trunk/gs/src/unix-aux.mak
   trunk/gs/src/unix-gcc.mak
   trunk/gs/src/unixinst.mak
Log:
Modularization of the X11 output devices into dynamic libraries

DETAILS:

This patch allows to compile Ghostscript in a way that the X11 screen
display output devices can be seperated into a dynamically linkable
library, so that these devices can be put in a separate binary package
in Linux distributions. This way the distributions can be installed
with GhostScript and without the X libraries, which is important for
headless print servers.

This feature is only available for Unix with GCC (selected by the
Makefile).

Ghostscript will be compiled without built-in X11 support and with an
extra X11.so file containing the X11 support. One can install
Ghostscript with or without X11.so then, it will always work. It
detects the presence of X11.so automatically and makes the X11 output
devises available if X11.so is present (see "gs -h").

Small disadvantage: With modularized X11 support the "x11" device will
not stay the default one. "bbox" will be the default then. Use "gs
-sDEVICE=x11 ..." then.

This patch is used since mid 2001 in ESP Ghostscript and has never
caused any problems or bugs related to the modularization.

EXPECTED DIFFERENCES:

None (in the non-interactive automated regression tests)



Modified: trunk/gs/src/Makefile.in
===================================================================
--- trunk/gs/src/Makefile.in	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/Makefile.in	2007-05-08 16:26:19 UTC (rev 7910)
@@ -59,6 +59,7 @@
 datadir = @datadir@
 gsdir = $(datadir)/ghostscript
 gsdatadir = $(gsdir)/$(GS_DOT_VERSION)
+gssharedir = $(prefix)/lib/ghostscript/$(GS_DOT_VERSION)
 
 docdir=$(gsdatadir)/doc
 exdir=$(gsdatadir)/examples
@@ -245,7 +246,7 @@
 # We don't include -ansi, because this gets in the way of the platform-
 #   specific stuff that <math.h> typically needs; nevertheless, we expect
 #   gcc to accept ANSI-style function prototypes and function definitions.
-XCFLAGS=
+XCFLAGS=-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\"$(gssharedir)\"
 
 # defines from autoconf; note that we don't use these at present.
 ACDEFS=@DEFS@
@@ -270,7 +271,7 @@
 # Solaris may need -lnsl -lsocket -lposix4.
 # (Libraries required by individual drivers are handled automatically.)
 
-EXTRALIBS=
+EXTRALIBS=-rdynamic -ldl
 
 # Define the standard libraries to search at the end of linking.
 # Most platforms require -lpthread for the POSIX threads library;
@@ -384,7 +385,8 @@
 # devs.mak and contrib.mak for the list of available devices.
 
 #DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
-DEVICE_DEVS=$(DISPLAY_DEV) @X11DEVS@
+#DEVICE_DEVS=$(DISPLAY_DEV) @X11DEVS@
+DEVICE_DEVS=
 
 DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)bmp32b.dev
 DEVICE_DEVS2=#$(DD)gdevjbig2.dev $(DD)gdevjpx.dev #$(DD)rinkj.dev
@@ -410,6 +412,9 @@
 DEVICE_DEVS20=$(DD)cljet5.dev $(DD)cljet5c.dev
 DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev
 
+# Shared library target to build.
+GS_SHARED_OBJS=$(GLOBJDIR)/X11.so
+
 # ---------------------------- End of options --------------------------- #
 
 # Define the name of the partial makefile that specifies options --
@@ -430,6 +435,7 @@
 # These are the specific warnings we have to turn off to compile those
 # specific few files that need this.  We may turn off others in the future.
 CC_NO_WARN=$(CC_)
+CC_SHARED=$(CC_) -fPIC -shared
 
 # ---------------- End of platform-specific section ---------------- #
 

Modified: trunk/gs/src/devs.mak
===================================================================
--- trunk/gs/src/devs.mak	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/devs.mak	2007-05-08 16:26:19 UTC (rev 7910)
@@ -412,7 +412,7 @@
 	$(ADDMOD) $(DD)lvga256 -lib vga vgagl
 
 $(GLOBJ)gdevl256.$(OBJ) : $(GLSRC)gdevl256.c $(GDEV) $(memory__h)
-	$(GLCC) $(GLO_)gdevl256.$(OBJ) $(C_) $(GLSRC)gdevl256.c
+	$(GLCCSHARED) $(GLO_)gdevl256.$(OBJ) $(C_) $(GLSRC)gdevl256.c
 
 vgalib_=$(GLOBJ)gdevvglb.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
 $(DD)vgalib.dev : $(DEVS_MAK) $(vgalib_)
@@ -420,8 +420,19 @@
 	$(ADDMOD) $(DD)vgalib -lib vga
 
 $(GLOBJ)gdevvglb.$(OBJ) : $(GLSRC)gdevvglb.c $(GDEV) $(gdevpccm_h) $(gsparam_h)
-	$(GLCC) $(GLO_)gdevvglb.$(OBJ) $(C_) $(GLSRC)gdevvglb.c
+	$(GLCCSHARED) $(GLO_)gdevvglb.$(OBJ) $(C_) $(GLSRC)gdevvglb.c
 
+### Shared library object supporting vgalib.
+### NON PORTABLE, ONLY UNIX WITH GCC SUPPORT
+
+$(GLOBJ)lvga256.so: $(lvga256_)
+	$(CCLD) -shared -Wl,'-solvga256.so' $(lvga256_) -lvga -lvgagl
+	mv lvga256.so $(GLOBJ)lvga256.so
+
+$(GLOBJ)vgalib.so: $(vgalib_)
+	$(CCLD) -shared -Wl,'-sovgalib.so' $(vgalib_) -lvga -lvgagl
+	mv vgalib.so $(GLOBJ)vgalib.so
+
 ### -------------------------- The X11 device -------------------------- ###
 
 # Please note that Aladdin Enterprises does not support Ghostview.
@@ -450,14 +461,14 @@
 $(GLOBJ)gdevx.$(OBJ) : $(GLSRC)gdevx.c $(GDEVX) $(math__h) $(memory__h)\
  $(gscoord_h) $(gsdevice_h) $(gsiparm2_h) $(gsmatrix_h) $(gsparam_h)\
  $(gxdevmem_h) $(gxgetbit_h) $(gxiparam_h) $(gxpath_h)
-	$(GLCC) $(XINCLUDE) $(GLO_)gdevx.$(OBJ) $(C_) $(GLSRC)gdevx.c
+	$(GLCCSHARED) $(XINCLUDE) $(GLO_)gdevx.$(OBJ) $(C_) $(GLSRC)gdevx.c
 
 $(GLOBJ)gdevxcmp.$(OBJ) : $(GLSRC)gdevxcmp.c $(GDEVX) $(math__h)
 	$(GLCC) $(XINCLUDE) $(GLO_)gdevxcmp.$(OBJ) $(C_) $(GLSRC)gdevxcmp.c
 
 $(GLOBJ)gdevxini.$(OBJ) : $(GLSRC)gdevxini.c $(GDEVX) $(memory__h)\
  $(gserrors_h) $(gsparamx_h) $(gxdevmem_h) $(gdevbbox_h)
-	$(GLCC) $(XINCLUDE) $(GLO_)gdevxini.$(OBJ) $(C_) $(GLSRC)gdevxini.c
+	$(GLCCSHARED) $(XINCLUDE) $(GLO_)gdevxini.$(OBJ) $(C_) $(GLSRC)gdevxini.c
 
 # We have to compile gdevxres without warnings, because there is a
 # const/non-const cast required by the X headers that we can't work around.
@@ -467,7 +478,7 @@
 
 $(GLOBJ)gdevxxf.$(OBJ) : $(GLSRC)gdevxxf.c $(GDEVX) $(math__h) $(memory__h)\
  $(gsstruct_h) $(gsutil_h) $(gxxfont_h)
-	$(GLCC) $(XINCLUDE) $(GLO_)gdevxxf.$(OBJ) $(C_) $(GLSRC)gdevxxf.c
+	$(GLCCSHARED) $(XINCLUDE) $(GLO_)gdevxxf.$(OBJ) $(C_) $(GLSRC)gdevxxf.c
 
 # Alternate X11-based devices to help debug other drivers.
 # x11alpha pretends to have 4 bits of alpha channel.
@@ -517,8 +528,15 @@
 
 $(GLOBJ)gdevxalt.$(OBJ) : $(GLSRC)gdevxalt.c $(GDEVX) $(math__h) $(memory__h)\
  $(gsdevice_h) $(gsparam_h) $(gsstruct_h)
-	$(GLCC) $(XINCLUDE) $(GLO_)gdevxalt.$(OBJ) $(C_) $(GLSRC)gdevxalt.c
+	$(GLCCSHARED) $(XINCLUDE) $(GLO_)gdevxalt.$(OBJ) $(C_) $(GLSRC)gdevxalt.c
 
+### Shared library object supporting X11.
+### NON PORTABLE, ONLY UNIX WITH GCC SUPPORT
+
+$(GLOBJ)X11.so: $(x11alt_) $(x11_)
+	$(CCLD) -shared -Wl,'-soX11.so' $(x11alt_) $(x11_) -L/usr/X11R6/lib -lXt -lSM -lICE -lXext -lX11 $(XLIBDIRS)
+	mv X11.so $(GLOBJ)X11.so
+
 ###### --------------- Memory-buffered printer devices --------------- ######
 
 ### ---------------- Practical Automation label printers ---------------- ###

Modified: trunk/gs/src/gconf.c
===================================================================
--- trunk/gs/src/gconf.c	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/gconf.c	2007-05-08 16:26:19 UTC (rev 7910)
@@ -88,7 +88,8 @@
 /* Set up the device table. */
 #define device_(dev) (const gx_device *)&dev,
 #define device2_(dev) &dev,
-private const gx_device *const gx_device_list[] = {
+private gx_device *gx_device_list[1024] = {
+  /* as shared library are adding drivers here, so removed constness */
 #include "gconf.h"
 	 0
 };
@@ -169,9 +170,29 @@
 gs_lib_device_list(const gx_device * const **plist,
 		   gs_memory_struct_type_t ** pst)
 {
+    int i;
+
     if (plist != 0)
 	*plist = gx_device_list;
     if (pst != 0)
 	*pst = NULL;
-    return countof(gx_device_list) - 1;
+
+    for (i = 0; i < countof(gx_device_list) - 1; ++i)
+      if (!gx_device_list[i])
+	break;
+    return i;
 }
+
+#ifdef GS_DEVS_SHARED
+void
+gs_lib_register_device(const gx_device *dev)
+{
+  int i;
+
+  for (i = 0; i < countof(gx_device_list) - 1; ++i)
+    if (!gx_device_list[i]) {
+      gx_device_list[i] = dev;
+      return;
+    }
+}
+#endif

Modified: trunk/gs/src/gdevl256.c
===================================================================
--- trunk/gs/src/gdevl256.c	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/gdevl256.c	2007-05-08 16:26:19 UTC (rev 7910)
@@ -301,3 +301,12 @@
     gl_line(x0, y0, x1, y1, color);
     return 0;
 }
+
+#ifdef GS_DEVS_SHARED
+extern void gs_lib_register_device(const gx_device *dev);
+void
+gs_shared_init(void)
+{
+  gs_lib_register_device(&gs_lvga256_device);
+}
+#endif

Modified: trunk/gs/src/gdevvglb.c
===================================================================
--- trunk/gs/src/gdevvglb.c	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/gdevvglb.c	2007-05-08 16:26:19 UTC (rev 7910)
@@ -368,3 +368,12 @@
     }
     return 0;
 }
+
+#ifdef GS_DEVS_SHARED
+extern void gs_lib_register_device(const gx_device *dev);
+void
+gs_shared_init(void)
+{
+  gs_lib_register_device(&gs_vgalib_device);
+}
+#endif

Modified: trunk/gs/src/gdevxalt.c
===================================================================
--- trunk/gs/src/gdevxalt.c	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/gdevxalt.c	2007-05-08 16:26:19 UTC (rev 7910)
@@ -25,6 +25,7 @@
 #include "gdevx.h"
 
 extern const gx_device_X gs_x11_device;
+extern const gx_device_X gs_x11alpha_device;
 
 /*
  * Define a forwarding device with a cache for the first 16 colors,
@@ -842,3 +843,20 @@
     rgb[2] = ((color >> 11) & 0x3ff) * gx_max_color_value / 0x3ff;
     return -1;
 }
+
+#ifdef GS_DEVS_SHARED
+extern void gs_lib_register_device(const gx_device *dev);
+void
+gs_shared_init(void)
+{
+  gs_lib_register_device(&gs_x11_device);
+  gs_lib_register_device(&gs_x11alpha_device);
+  gs_lib_register_device(&gs_x11cmyk_device);
+  gs_lib_register_device(&gs_x11cmyk2_device);
+  gs_lib_register_device(&gs_x11cmyk4_device);
+  gs_lib_register_device(&gs_x11cmyk8_device);
+  gs_lib_register_device(&gs_x11gray2_device);
+  gs_lib_register_device(&gs_x11gray4_device);
+  gs_lib_register_device(&gs_x11mono_device);
+}
+#endif

Modified: trunk/gs/src/gp_unix.c
===================================================================
--- trunk/gs/src/gp_unix.c	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/gp_unix.c	2007-05-08 16:26:19 UTC (rev 7910)
@@ -36,11 +36,56 @@
 extern char *getenv(const char *);
 #endif
 
+#ifdef GS_DEVS_SHARED
+#ifndef GS_DEVS_SHARED_DIR
+#  define GS_DEVS_SHARED_DIR "/usr/lib/ghostscript/8.16"
+#endif
+/*
+ * use shared library for drivers, always load them when starting, this
+ * avoid too many modifications, and since it is supported only under linux
+ * and applied as a patch (preferable).
+ */
+#include <sys/types.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <string.h>
+
+void
+gp_init(void)
+{
+  DIR*           dir = NULL;
+  struct dirent* dirent;
+  char           buff[1024];
+  char*          pbuff;
+  void*          handle;
+  void           (*gs_shared_init)(void);
+
+  strncpy(buff, GS_DEVS_SHARED_DIR, sizeof(buff) - 2);
+  pbuff = buff + strlen(buff);
+  *pbuff++ = '/'; *pbuff = '\0';
+
+  dir = opendir(GS_DEVS_SHARED_DIR);
+  if (dir == 0) return;
+
+  while ((dirent = readdir(dir)) != 0) {
+    strncpy(pbuff, dirent->d_name, sizeof(buff) - (pbuff - buff) - 1);
+    if ((handle = dlopen(buff, RTLD_NOW)) != 0) {
+      if ((gs_shared_init = dlsym(handle, "gs_shared_init")) != 0) {
+	(*gs_shared_init)();
+      } else {
+      }
+    }
+  }
+
+  closedir(dir);
+}
+#else
 /* Do platform-dependent initialization. */
 void
 gp_init(void)
 {
 }
+#endif
 
 /* Do platform-dependent cleanup. */
 void

Modified: trunk/gs/src/gs.mak
===================================================================
--- trunk/gs/src/gs.mak	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/gs.mak	2007-05-08 16:26:19 UTC (rev 7910)
@@ -258,7 +258,8 @@
 gconfigf_h=$(GLGENDIR)$(D)gconfxc.h
 gconfigd_h=$(GLGENDIR)$(D)gconfigd.h
 
-all default : $(GS_XE)
+all default : $(GS_XE) $(GS_SHARED_OBJS)
+	$(RM) _temp_*
 	$(NO_OP)
 
 # the distclean and maintainer-clean targets (if any)
@@ -271,6 +272,7 @@
 clean : mostlyclean
 	$(RM_) $(GSGEN)arch.h
 	$(RM_) $(GS_XE)
+	$(RM_) $(GS_SHARED_OBJS)
 
 #****** FOLLOWING IS WRONG, NEEDS TO BE PER-SUBSYSTEM ******
 mostlyclean : config-clean

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/lib.mak	2007-05-08 16:26:19 UTC (rev 7910)
@@ -33,9 +33,9 @@
 GLJASCC=$(CC_) $(I_)$(JPXI_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_)
 GLLDFJB2CC=$(CC_) $(I_)$(LDF_JB2I_) $(II)$(GLI_)$(_I) $(JB2CF_) $(GLF_)
 GLLWFJPXCC=$(CC_) $(I_)$(LWF_JPXI_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_)
+GLCCSHARED=$(CC_SHARED) $(I_)$(GLI_)$(_I) $(GLF_)
 # All top-level makefiles define GLD.
 #GLD=$(GLGEN)
-
 # Define the name of this makefile.
 LIB_MAK=$(GLSRC)lib.mak
 

Modified: trunk/gs/src/unix-aux.mak
===================================================================
--- trunk/gs/src/unix-aux.mak	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/unix-aux.mak	2007-05-08 16:26:19 UTC (rev 7910)
@@ -83,7 +83,7 @@
  $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsutil.$(OBJ)
 
 $(MKROMFS_XE): $(GLSRC)mkromfs.c $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS)
-	$(CCAUX) $(GENOPT) $(CFLAGS_DEBUG) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE) $(MKROMFS_OBJS) -lm
+	$(CCAUX) $(GENOPT) $(CFLAGS_DEBUG) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE) $(MKROMFS_OBJS) -lm $(LDFLAGS) $(EXTRALIBS)
 
 # Query the environment to construct gconfig_.h.
 # The "else true;" is required because Ultrix's implementation of sh -e

Modified: trunk/gs/src/unix-gcc.mak
===================================================================
--- trunk/gs/src/unix-gcc.mak	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/unix-gcc.mak	2007-05-08 16:26:19 UTC (rev 7910)
@@ -235,7 +235,7 @@
 # We don't include -ansi, because this gets in the way of the platform-
 #   specific stuff that <math.h> typically needs; nevertheless, we expect
 #   gcc to accept ANSI-style function prototypes and function definitions.
-XCFLAGS=
+XCFLAGS=-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\"$(gssharedir)\"
 
 CFLAGS=$(CFLAGS_STANDARD) $(GCFLAGS) $(XCFLAGS)
 
@@ -257,7 +257,7 @@
 # Solaris may need -lnsl -lsocket -lposix4.
 # (Libraries required by individual drivers are handled automatically.)
 
-EXTRALIBS=
+EXTRALIBS=-rdynamic -ldl
 
 # Define the standard libraries to search at the end of linking.
 # Most platforms require -lpthread for the POSIX threads library;
@@ -412,6 +412,10 @@
 DEVICE_DEVS20=$(DD)cljet5.dev $(DD)cljet5c.dev
 DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev
 
+# Shared library target to build.
+GS_SHARED_OBJS=$(GLOBJDIR)/X11.so $(GLOBJDIR)/lvga256.so $(GLOBJDIR)/vgalib.so
+#GS_SHARED_OBJS=$(GLOBJDIR)/X11.so
+
 # ---------------------------- End of options --------------------------- #
 
 # Define the name of the partial makefile that specifies options --
@@ -434,6 +438,7 @@
 # These are the specific warnings we have to turn off to compile those
 # specific few files that need this.  We may turn off others in the future.
 CC_NO_WARN=$(CC_) -Wno-cast-qual -Wno-traditional
+CC_SHARED=$(CC_) -fPIC -shared
 
 # ---------------- End of platform-specific section ---------------- #
 

Modified: trunk/gs/src/unixinst.mak
===================================================================
--- trunk/gs/src/unixinst.mak	2007-05-07 21:53:44 UTC (rev 7909)
+++ trunk/gs/src/unixinst.mak	2007-05-08 16:26:19 UTC (rev 7910)
@@ -15,7 +15,7 @@
 # containing the `install' targets.
 # This is the very last part of the makefile for these configurations.
 
-install: install-exec install-scripts install-data
+install: install-exec install-scripts install-data install-shared
 
 # The sh -c in the rules below is required because Ultrix's implementation
 # of sh -e terminates execution of a command if any error occurs, even if
@@ -169,3 +169,9 @@
 ridt91.eps ;\
 	do $(INSTALL_DATA) $(PSEXDIR)/$$f $(DESTDIR)$(exdir) ;\
 	done
+
+install-shared: $(GS_SHARED_OBJS)
+	-mkdir -p $(gssharedir)
+	$(SH) -c 'for obj in $(GS_SHARED_OBJS); do \
+	    $(INSTALL_PROGRAM) $$obj $(gssharedir)/; done'
+



More information about the gs-cvs mailing list