If compiling a driver for static inclusion via --enable-static-drivers you
+ have to define STATIC_ERLANG_DRIVER before the DRIVER_INIT declaration.
Do not declare the driver_entry const. This since the emulator needs to
modify the handle, and the handle2
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 <
Date: Mon, 19 Aug 2013 11:56:01 +0200
Subject: erts: Document --enable-static-nif/driver
---
HOWTO/INSTALL.md | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md
index fa1b9d2e89..9ea50ce86c 100644
--- a/HOWTO/INSTALL.md
+++ b/HOWTO/INSTALL.md
@@ -296,6 +296,18 @@ Some of the available `configure` options are:
you can build using a fallback implementation based on mutexes or spinlocks.
Performance of the SMP runtime system will however suffer immensely without
an implementation for native atomic memory accesses.
+* `--enable-static-{nifs,drivers}` - To allow usage of nifs and drivers on OSs
+ that do not support dynamic linking of libraries it is possible to statically
+ link nifs and drivers with the main Erlang VM binary. This is done by passing
+ a comma seperated list to the archives that you want to statically link. e.g.
+ `--enable-static-nifs=/home/$USER/my_nif.a`. The path has to be absolute and the
+ name of the archive has to be the same as the module, i.e. `my_nif` in the
+ example above. This is also true for drivers, but then it is the driver name
+ that has to be the same as the filename. You also have to define
+ `STATIC_ERLANG_{NIF,DRIVER}` when compiling the .o files for the nif/driver.
+ If your nif/driver depends on some other dynamic library, you now have to link
+ that to the Erlang VM binary. This is easily achived by passing `LIBS=-llibname`
+ to configure.
If you or your system has special requirements please read the `Makefile` for
additional configuration information.
--
cgit v1.2.3