aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/configure.in6
-rw-r--r--erts/doc/src/driver_entry.xml2
-rw-r--r--erts/emulator/Makefile.in42
-rw-r--r--erts/emulator/beam/erl_driver.h14
-rwxr-xr-xerts/emulator/beam/global.h1
-rw-r--r--erts/emulator/beam/io.c1
-rwxr-xr-xerts/emulator/utils/make_driver_tab42
7 files changed, 89 insertions, 19 deletions
diff --git a/erts/configure.in b/erts/configure.in
index 3b4417d10e..4e60b27ee9 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -425,6 +425,12 @@ AS_HELP_STRING([--enable-static-nifs], [link nifs statically. If yes then all ni
STATIC_NIFS=no)
AC_SUBST(STATIC_NIFS)
+AC_ARG_ENABLE(static-drivers,
+AS_HELP_STRING([--enable-static-drivers], [comma seperated list of linked-in drivers to link statically with the main binary. The list should contain the absolute path to a .a archive for each driver that is to be statically linked. The name of the .a archive has to be the same as the name of the driver.]),
+ STATIC_DRIVERS="$enableval",
+ STATIC_DRIVERS=no)
+AC_SUBST(STATIC_DRIVERS)
+
dnl ----------------------------------------------------------------------
dnl Checks for programs.
dnl ----------------------------------------------------------------------
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
index 69a4dea466..48dfcb09b1 100644
--- a/erts/doc/src/driver_entry.xml
+++ b/erts/doc/src/driver_entry.xml
@@ -110,6 +110,8 @@
<p>When the driver has passed the <c>driver_entry</c> over to
the emulator, the driver is <em>not</em> allowed to modify the
<c>driver_entry</c>.</p>
+ <p>If compiling a driver for static inclusion via --enable-static-drivers you
+ have to define STATIC_ERLANG_DRIVER before the DRIVER_INIT declaration.</p>
<note>
<p>Do <em>not</em> declare the <c>driver_entry</c> <c>const</c>. This since the emulator needs to
modify the <c>handle</c>, and the <c>handle2</c>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index db5642b9c3..048e92baad 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -136,18 +136,27 @@ endif
endif
endif
+comma:=,
+space:=
+space+=
+
STATIC_NIFS=@STATIC_NIFS@
ifneq ($(STATIC_NIFS),no)
ifeq ($(STATIC_NIFS),yes)
STATIC_NIFS=$(ERL_TOP)/lib/asn1/priv/lib/$(TARGET)/asn1rt_nif.a \
$(ERL_TOP)/lib/crypto/priv/lib/$(TARGET)/crypto$(TYPEMARKER).a
endif
-comma:=,
-space:=
-space+=
STATIC_NIFS:=$(subst $(comma),$(space),$(STATIC_NIFS))
endif
+STATIC_DRIVERS=@STATIC_DRIVERS@
+ifneq ($(STATIC_DRIVERS),no)
+ifeq ($(STATIC_DRIVERS),yes)
+STATIC_DRIVERS=
+endif
+STATIC_DRIVERS:=$(subst $(comma),$(space),$(STATIC_DRIVERS))
+endif
+
#
# NOTE: When adding a new type update ERL_BUILD_TYPE_MARKER in sys/unix/sys.c
@@ -571,7 +580,7 @@ GENERATE += $(TARGET)/erl_version.h
# driver table
$(TTF_DIR)/driver_tab.c: Makefile.in utils/make_driver_tab
- $(gen_verbose)LANG=C $(PERL) utils/make_driver_tab -o $@ $(STATIC_NIF_LIBS) $(DRV_OBJS)
+ $(gen_verbose)LANG=C $(PERL) utils/make_driver_tab -o $@ -nifs $(STATIC_NIF_LIBS) -drivers $(DRV_OBJS) $(STATIC_DRIVER_LIBS)
GENERATE += $(TTF_DIR)/driver_tab.c
@@ -813,14 +822,25 @@ endif
ifneq ($(STATIC_NIFS),no)
STATIC_NIF_LIBS = $(STATIC_NIFS)
DEPLIBS += $(STATIC_NIF_LIBS)
-
-$(STATIC_NIF_LIBS):
- $(MAKE) BUILD_STATIC_LIBS=1 TYPE=$(TYPE) -C $(ERL_TOP)/lib/ static_lib
-
+COMPILE_STATIC_LIBS = yes
else
STATIC_NIF_LIBS=
endif
+ifneq ($(STATIC_DRIVERS),no)
+STATIC_DRIVER_LIBS = $(STATIC_DRIVERS)
+DEPLIBS += $(STATIC_DRIVER_LIBS)
+COMPILE_STATIC_LIBS = yes
+else
+STATIC_DRIVER_LIBS=
+endif
+
+ifeq ($(COMPILE_STATIC_LIBS),yes)
+
+$(STATIC_NIF_LIBS) $(STATIC_DRIVER_LIBS):
+ $(MAKE) BUILD_STATIC_LIBS=1 TYPE=$(TYPE) -C $(ERL_TOP)/lib/ static_lib
+endif
+
ifeq ($(ERTS_ENABLE_KERNEL_POLL),yes)
OS_OBJS += $(OBJDIR)/erl_poll.kp.o \
$(OBJDIR)/erl_check_io.kp.o \
@@ -965,12 +985,14 @@ ifeq ($(TARGET), win32)
# Only the basic erlang to begin with eh?
$(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS)
$(ld_verbose)$(PURIFY) $(LD) -dll -def:sys/$(ERLANG_OSTYPE)/erl.def -implib:$(BINDIR)/erl_dll.lib -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \
- $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) $(STATIC_NIF_LIBS) $(LIBS)
+ $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) $(STATIC_NIF_LIBS) \
+ $(STATIC_DRIVER_LIBS) $(LIBS)
else
$(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS)
+ echo $(DEPLIBS)
$(ld_verbose)$(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \
$(HIPEBEAMLDFLAGS) $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) \
- $(STATIC_NIF_LIBS) $(LIBS)
+ $(STATIC_NIF_LIBS) $(STATIC_DRIVER_LIBS) $(LIBS)
endif
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index e280563de1..f43f5a766e 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -365,17 +365,23 @@ typedef struct erl_drv_entry {
* It must initialize a ErlDrvEntry structure and return a pointer to it.
*/
+#ifdef STATIC_ERLANG_DRIVER
+# define ERLANG_DRIVER_NAME(NAME) NAME ## _driver_init
+#else
+# define ERLANG_DRIVER_NAME(NAME) driver_init
+#endif
+
/* For windows dynamic drivers */
#ifndef ERL_DRIVER_TYPES_ONLY
#if defined(__WIN32__)
# define DRIVER_INIT(DRIVER_NAME) \
- __declspec(dllexport) ErlDrvEntry* driver_init(void); \
- __declspec(dllexport) ErlDrvEntry* driver_init(void)
+ __declspec(dllexport) ErlDrvEntry* ERLANG_DRIVER_NAME(DRIVER_NAME)(void); \
+ __declspec(dllexport) ErlDrvEntry* ERLANG_DRIVER_NAME(DRIVER_NAME)(void)
#else
# define DRIVER_INIT(DRIVER_NAME) \
- ErlDrvEntry* driver_init(void); \
- ErlDrvEntry* driver_init(void)
+ ErlDrvEntry* ERLANG_DRIVER_NAME(DRIVER_NAME)(void); \
+ ErlDrvEntry* ERLANG_DRIVER_NAME(DRIVER_NAME)(void)
#endif
#define ERL_DRV_BUSY_MSGQ_DISABLED (~((ErlDrvSizeT) 0))
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 2acc86cf42..ef34f5b221 100755
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -856,6 +856,7 @@ void erts_lcnt_enable_io_lock_count(int enable);
typedef void *(*ErtsStaticNifInitFPtr)(void);
ErtsStaticNifInitFPtr erts_static_nif_get_nif_init(const char *name);
int erts_is_static_nif(void *handle);
+void erts_init_static_drivers(void);
/* erl_drv_thread.c */
void erl_drv_thr_init(void);
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index c1e66b59af..fb39c18d9d 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -2765,6 +2765,7 @@ void erts_init_io(int port_tab_size,
init_driver(&fd_driver, &fd_driver_entry, NULL);
init_driver(&vanilla_driver, &vanilla_driver_entry, NULL);
init_driver(&spawn_driver, &spawn_driver_entry, NULL);
+ erts_init_static_drivers();
for (dp = driver_tab; *dp != NULL; dp++)
erts_add_driver_entry(*dp, NULL, 1);
diff --git a/erts/emulator/utils/make_driver_tab b/erts/emulator/utils/make_driver_tab
index 06928a3a4a..3eedef21a7 100755
--- a/erts/emulator/utils/make_driver_tab
+++ b/erts/emulator/utils/make_driver_tab
@@ -28,8 +28,10 @@ use File::Basename;
my $file = "";
my $nif = "";
-my @drivers = ();
+my @emu_drivers = ();
+my @static_drivers = ();
my @nifs = ();
+my $mode = 1;
while (@ARGV) {
my $d = shift;
@@ -37,15 +39,28 @@ while (@ARGV) {
$file = shift or die("-o requires argument");
next;
}
+ if ( $d =~ /^-nifs$/ ) {
+ $mode = 2;
+ next;
+ }
+ if ( $d =~ /^-drivers$/ ) {
+ $mode = 1;
+ next;
+ }
if ( $d =~ /^.*\.a$/ ) {
$d = basename $d;
$d =~ s/\.a$//; # strip .a
- push(@nifs, $d);
+ if ($mode == 1) {
+ push(@static_drivers, $d);
+ }
+ if ($mode == 2) {
+ push(@nifs, $d);
+ }
next;
}
$d = basename $d;
$d =~ s/drv(\..*|)$//; # strip drv.* or just drv
- push(@drivers, $d);
+ push(@emu_drivers, $d);
}
# Did we want output to a file?
@@ -64,19 +79,36 @@ print <<EOF;
EOF
# "extern" declarations
-foreach (@drivers) {
+foreach (@emu_drivers) {
print "extern ErlDrvEntry ${_}driver_entry;\n";
}
+foreach (@static_drivers) {
+ print "ErlDrvEntry *${_}_driver_init(void);\n";
+}
+
# The array itself
print "\nErlDrvEntry *driver_tab[DRIVER_TAB_SIZE] =\n{\n";
-foreach (@drivers) {
+foreach (@emu_drivers) {
print " &${_}driver_entry,\n";
}
+foreach (@static_drivers) {
+ print " NULL, /* ${_} */\n";
+}
print " NULL\n};\n";
+print "void erts_init_static_drivers() {\n";
+
+my $index = 0;
+foreach (@static_drivers) {
+ print " driver_tab[".(scalar @emu_drivers+$index)."] = ${_}_driver_init();\n";
+ $index++;
+}
+
+print "}\n";
+
print <<EOF;
typedef struct ErtsStaticNifEntry_ {