diff options
-rw-r--r-- | doc/src/guide/installation.asciidoc | 7 | ||||
-rw-r--r-- | doc/src/guide/ports.asciidoc | 16 | ||||
-rw-r--r-- | plugins/c_src.mk | 47 | ||||
-rw-r--r-- | test/plugin_c_src.mk | 12 |
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 |