aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/guide/installation.asciidoc7
-rw-r--r--doc/src/guide/ports.asciidoc16
-rw-r--r--plugins/c_src.mk47
-rw-r--r--test/plugin_c_src.mk12
4 files changed, 68 insertions, 14 deletions
diff --git a/doc/src/guide/installation.asciidoc b/doc/src/guide/installation.asciidoc
index f03dafa..a271e2d 100644
--- a/doc/src/guide/installation.asciidoc
+++ b/doc/src/guide/installation.asciidoc
@@ -95,6 +95,13 @@ to find all packages related to GCC:
[source,bash]
$ pacman -Ss gcc
+If you are going to compile C/C++ code, you will need to
+install this package, as Erlang.mk cannot use the normal
+"gcc" package:
+
+[source,bash]
+$ pacman -S mingw-w64-x86_64-gcc
+
You can also run commands under the MSYS2 environment from
the Windows command line or batch files. This command will
install GNU Make and Git:
diff --git a/doc/src/guide/ports.asciidoc b/doc/src/guide/ports.asciidoc
index b436c13..efe4ff7 100644
--- a/doc/src/guide/ports.asciidoc
+++ b/doc/src/guide/ports.asciidoc
@@ -64,9 +64,19 @@ before including Erlang.mk:
[source,make]
C_SRC_TYPE = executable
-The generated file will be saved to '$(C_SRC_OUTPUT)'. It
-defaults to '$(CURDIR)/priv/$(PROJECT).so', the filename
-adequately fitting a Unix shared library.
+The generated file name varies depending on the type of project
+you have (shared library or executable) and on the platform you
+build the project on.
+
+For shared libraries, the generated file name will be
+'$(C_SRC_OUTPUT)$(C_SRC_SHARED_EXTENSION)', with the default
+being '$(CURDIR)/priv/$(PROJECT)' followed by the extension:
+`.dll` on Windows, `.so` everywhere else.
+
+For executables, the generated file name is
+'$(C_SRC_OUTPUT)$(C_SRC_EXECUTABLE_EXTENSION)', with the same
+default except for the extension: `.exe` on Windows, and otherwise
+nothing.
Erlang.mk sets appropriate compile and linker flags by default.
These flags vary depending on the platform, and can of course
diff --git a/plugins/c_src.mk b/plugins/c_src.mk
index e5d6e51..87fd32f 100644
--- a/plugins/c_src.mk
+++ b/plugins/c_src.mk
@@ -7,12 +7,32 @@
C_SRC_DIR ?= $(CURDIR)/c_src
C_SRC_ENV ?= $(C_SRC_DIR)/env.mk
-C_SRC_OUTPUT ?= $(CURDIR)/priv/$(PROJECT).so
+C_SRC_OUTPUT ?= $(CURDIR)/priv/$(PROJECT)
C_SRC_TYPE ?= shared
# System type and C compiler/flags.
-ifeq ($(PLATFORM),darwin)
+ifeq ($(PLATFORM),msys2)
+ C_SRC_OUTPUT_EXECUTABLE_EXTENSION ?= .exe
+ C_SRC_OUTPUT_SHARED_EXTENSION ?= .dll
+else
+ C_SRC_OUTPUT_EXECUTABLE_EXTENSION ?=
+ C_SRC_OUTPUT_SHARED_EXTENSION ?= .so
+endif
+
+ifeq ($(C_SRC_TYPE),shared)
+ C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_SHARED_EXTENSION)
+else
+ C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION)
+endif
+
+ifeq ($(PLATFORM),msys2)
+# We hardcode the compiler used on MSYS2. The default CC=cc does
+# not produce working code. The "gcc" MSYS2 package also doesn't.
+ CC = /mingw64/bin/gcc
+ CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
+ CXXFLAGS ?= -O3 -finline-functions -Wall
+else ifeq ($(PLATFORM),darwin)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -arch x86_64 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -arch x86_64 -finline-functions -Wall
@@ -27,10 +47,15 @@ else ifeq ($(PLATFORM),linux)
CXXFLAGS ?= -O3 -finline-functions -Wall
endif
-CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
-CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
+ifneq ($(PLATFORM),msys2)
+ CFLAGS += -fPIC
+ CXXFLAGS += -fPIC
+endif
+
+CFLAGS += -I"$(ERTS_INCLUDE_DIR)" -I"$(ERL_INTERFACE_INCLUDE_DIR)"
+CXXFLAGS += -I"$(ERTS_INCLUDE_DIR)" -I"$(ERL_INTERFACE_INCLUDE_DIR)"
-LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lerl_interface -lei
+LDLIBS += -L"$(ERL_INTERFACE_LIB_DIR)" -lerl_interface -lei
# Verbosity.
@@ -67,15 +92,15 @@ OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c
COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c
-app:: $(C_SRC_ENV) $(C_SRC_OUTPUT)
+app:: $(C_SRC_ENV) $(C_SRC_OUTPUT_FILE)
-test-build:: $(C_SRC_ENV) $(C_SRC_OUTPUT)
+test-build:: $(C_SRC_ENV) $(C_SRC_OUTPUT_FILE)
-$(C_SRC_OUTPUT): $(OBJECTS)
+$(C_SRC_OUTPUT_FILE): $(OBJECTS)
$(verbose) mkdir -p priv/
$(link_verbose) $(CC) $(OBJECTS) \
$(LDFLAGS) $(if $(filter $(C_SRC_TYPE),shared),-shared) $(LDLIBS) \
- -o $(C_SRC_OUTPUT)
+ -o $(C_SRC_OUTPUT_FILE)
%.o: %.c
$(COMPILE_C) $(OUTPUT_OPTION) $<
@@ -92,13 +117,13 @@ $(C_SRC_OUTPUT): $(OBJECTS)
clean:: clean-c_src
clean-c_src:
- $(gen_verbose) rm -f $(C_SRC_OUTPUT) $(OBJECTS)
+ $(gen_verbose) rm -f $(C_SRC_OUTPUT_FILE) $(OBJECTS)
endif
ifneq ($(wildcard $(C_SRC_DIR)),)
$(C_SRC_ENV):
- $(verbose) $(ERL) -eval "file:write_file(\"$(C_SRC_ENV)\", \
+ $(verbose) $(ERL) -eval "file:write_file(\"$(call core_native_path,$(C_SRC_ENV))\", \
io_lib:format( \
\"ERTS_INCLUDE_DIR ?= ~s/erts-~s/include/~n\" \
\"ERL_INTERFACE_INCLUDE_DIR ?= ~s~n\" \
diff --git a/test/plugin_c_src.mk b/test/plugin_c_src.mk
index ffce3d8..ac9c2a0 100644
--- a/test/plugin_c_src.mk
+++ b/test/plugin_c_src.mk
@@ -34,7 +34,11 @@ c-src-nif: build clean-c-src-nif
$t test -f $(APP)/c_src/env.mk
$t test -f $(APP)/ebin/$(APP).app
$t test -f $(APP)/ebin/$(APP).beam
+ifeq ($(PLATFORM),msys2)
+ $t test -f $(APP)/priv/$(APP).dll
+else
$t test -f $(APP)/priv/$(APP).so
+endif
$i "Check that the application was compiled correctly"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
@@ -55,7 +59,11 @@ c-src-nif: build clean-c-src-nif
$t test -f $(APP)/c_src/env.mk
$t test -f $(APP)/ebin/$(APP).app
$t test -f $(APP)/ebin/$(APP).beam
+ifeq ($(PLATFORM),msys2)
+ $t test -f $(APP)/priv/$(APP).dll
+else
$t test -f $(APP)/priv/$(APP).so
+endif
$i "Check that the application was compiled correctly"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
@@ -75,7 +83,11 @@ c-src-nif: build clean-c-src-nif
$t test ! -e $(APP)/c_src/$(APP).o
$t test ! -e $(APP)/ebin/$(APP).app
$t test ! -e $(APP)/ebin/$(APP).beam
+ifeq ($(PLATFORM),msys2)
+ $t test ! -e $(APP)/priv/$(APP).dll
+else
$t test ! -e $(APP)/priv/$(APP).so
+endif
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v