diff options
-rw-r--r-- | build.config | 2 | ||||
-rw-r--r-- | core/core.mk | 9 | ||||
-rw-r--r-- | core/deps.mk | 4 | ||||
-rw-r--r-- | core/erlc.mk | 6 | ||||
-rw-r--r-- | doc/src/guide/app.asciidoc | 28 | ||||
-rw-r--r-- | doc/src/guide/getting_started.asciidoc | 19 | ||||
-rw-r--r-- | doc/src/guide/ports.asciidoc | 2 | ||||
-rw-r--r-- | plugins/bootstrap.mk | 6 | ||||
-rw-r--r-- | plugins/c_src.mk | 4 | ||||
-rw-r--r-- | plugins/relx.mk | 4 | ||||
-rw-r--r-- | test/Makefile | 1 | ||||
-rw-r--r-- | test/core_upgrade.mk | 34 | ||||
-rw-r--r-- | test/plugin_bootstrap.mk | 63 |
13 files changed, 144 insertions, 38 deletions
diff --git a/build.config b/build.config index 674035e..fed0626 100644 --- a/build.config +++ b/build.config @@ -10,6 +10,7 @@ core/index core/deps # Plugins that must run before Erlang code gets compiled. +plugins/erlydtl plugins/protobuffs # Core modules, continued. @@ -28,7 +29,6 @@ plugins/ct plugins/dialyzer plugins/edoc plugins/elvis -plugins/erlydtl plugins/escript plugins/eunit plugins/relx diff --git a/core/core.mk b/core/core.mk index 3f9883b..81d9f7e 100644 --- a/core/core.mk +++ b/core/core.mk @@ -78,13 +78,11 @@ endif # Core targets. -.NOTPARALLEL: - all:: deps app rel # Noop to avoid a Make warning when there's nothing to do. rel:: - $(verbose) echo -n + $(verbose) : check:: clean app tests @@ -194,8 +192,11 @@ ERLANG_MK_BUILD_DIR ?= .erlang.mk.build erlang-mk: git clone $(ERLANG_MK_REPO) $(ERLANG_MK_BUILD_DIR) +ifdef ERLANG_MK_COMMIT + cd $(ERLANG_MK_BUILD_DIR) && git checkout $(ERLANG_MK_COMMIT) +endif if [ -f $(ERLANG_MK_BUILD_CONFIG) ]; then cp $(ERLANG_MK_BUILD_CONFIG) $(ERLANG_MK_BUILD_DIR)/build.config; fi - cd $(ERLANG_MK_BUILD_DIR) && $(if $(ERLANG_MK_COMMIT),git checkout $(ERLANG_MK_COMMIT) &&) $(MAKE) + $(MAKE) -C $(ERLANG_MK_BUILD_DIR) cp $(ERLANG_MK_BUILD_DIR)/erlang.mk ./erlang.mk rm -rf $(ERLANG_MK_BUILD_DIR) diff --git a/core/deps.mk b/core/deps.mk index 501bd45..b70d445 100644 --- a/core/deps.mk +++ b/core/deps.mk @@ -63,7 +63,7 @@ endif $(verbose) mkdir -p $(ERLANG_MK_TMP) $(verbose) for dep in $(ALL_DEPS_DIRS) ; do \ if grep -qs ^$$dep$$ $(ERLANG_MK_TMP)/deps.log; then \ - echo -n; \ + :; \ else \ echo $$dep >> $(ERLANG_MK_TMP)/deps.log; \ if [ -f $$dep/GNUmakefile ] || [ -f $$dep/makefile ] || [ -f $$dep/Makefile ]; then \ @@ -128,7 +128,7 @@ define dep_autopatch_erlang_mk endef else define dep_autopatch_erlang_mk - echo -n + : endef endif diff --git a/core/erlc.mk b/core/erlc.mk index c0aeb41..1b94644 100644 --- a/core/erlc.mk +++ b/core/erlc.mk @@ -52,10 +52,10 @@ ifneq ($(wildcard src/),) # Targets. ifeq ($(wildcard ebin/test),) -app:: $(PROJECT).d +app:: deps $(PROJECT).d $(verbose) $(MAKE) --no-print-directory app-build else -app:: clean $(PROJECT).d +app:: clean deps $(PROJECT).d $(verbose) $(MAKE) --no-print-directory app-build endif @@ -85,7 +85,7 @@ endef endif app-build: ebin/$(PROJECT).app - $(verbose) echo -n + $(verbose) : # Source files. diff --git a/doc/src/guide/app.asciidoc b/doc/src/guide/app.asciidoc index 1320577..b2854de 100644 --- a/doc/src/guide/app.asciidoc +++ b/doc/src/guide/app.asciidoc @@ -46,13 +46,18 @@ up generating releases. ==== Application -You can build your application specifically, without -looking at handling dependencies or generating a release, -by running the following command: +You can build your application and dependencies without +generating a release by running the following command: [source,bash] $ make app +To build your application without touching dependencies +at all, you can use the `SKIP_DEPS` variable: + +[source,bash] +$ make app SKIP_DEPS=1 + This command is very useful if you have a lot of dependencies and develop on a machine with slow file access, like the Raspberry Pi and many other embedded devices. @@ -76,22 +81,21 @@ in the next chapter. ==== Release -You can generate the release, skipping the steps for building -the application and dependencies, by running the following -command: +It is not possible to build the release without at least +building the application itself, unless of course if there's +no application to begin with. + +To generate the release, `make` will generally suffice with +a normal Erlang.mk. A separate target is however available, +and will take care of building the release, after building +the application and all dependencies: [source,bash] $ make rel -This command can be useful if nothing changed except the -release configuration files. - Consult the link:relx.asciidoc[Releases] chapter for more information about what releases are and how they are generated. -Note that this command may fail if a required dependency -is missing. - === Application resource file When building your application, Erlang.mk will generate the diff --git a/doc/src/guide/getting_started.asciidoc b/doc/src/guide/getting_started.asciidoc index 34280d1..71ec0cb 100644 --- a/doc/src/guide/getting_started.asciidoc +++ b/doc/src/guide/getting_started.asciidoc @@ -183,6 +183,25 @@ Eshell V7.0 (abort with ^G) Simple as that! +=== Using spaces instead of tabs + +Erlang.mk defaults to tabs when creating files from templates. +This is in part because of a personal preference, and in part +because it is much easier to convert tabs to spaces than the +opposite. + +Use the `SP` variable if you prefer spaces. Set it to the number +of spaces per indentation level you want. + +For example, if you prefer two spaces per indentation level: + +[source,bash] +$ make -f erlang.mk bootstrap SP=2 + +When you bootstrap the project initially, the variable automatically +gets added to the Makefile, so you only need to provide it when +you get started. + === Using templates It is no secret that Erlang's OTP behaviors tend to have some diff --git a/doc/src/guide/ports.asciidoc b/doc/src/guide/ports.asciidoc index b4527fb..b436c13 100644 --- a/doc/src/guide/ports.asciidoc +++ b/doc/src/guide/ports.asciidoc @@ -35,8 +35,6 @@ It contains a few variable definitions for the environment used for the build: `ERL_INTERFACE_LIB_DIR`:: Path to the Erl_Interface static libraries. -// @todo We should remove this file on clean, not distclean. - === Using a custom Makefile Erlang.mk will automatically run `make` if it detects a Makefile diff --git a/plugins/bootstrap.mk b/plugins/bootstrap.mk index dbd115f..464d8fe 100644 --- a/plugins/bootstrap.mk +++ b/plugins/bootstrap.mk @@ -344,7 +344,7 @@ endef # Plugin-specific targets. define render_template - $(verbose) echo "$${_$(1)}" > $(2) + $(verbose) printf -- '$(subst $(newline),\n,$(subst %,%%,$(subst ','\'',$(subst $(tab),$(WS),$(call $(1))))))\n' > $(2) endef ifndef WS @@ -355,10 +355,6 @@ WS = $(tab) endif endif -$(foreach template,$(filter bs_% tpl_%,$(.VARIABLES)), \ - $(eval _$(template) = $$(subst $$(tab),$$(WS),$$($(template)))) \ - $(eval export _$(template))) - bootstrap: ifneq ($(wildcard src/),) $(error Error: src/ directory already exists) diff --git a/plugins/c_src.mk b/plugins/c_src.mk index 5cfdeef..e5d6e51 100644 --- a/plugins/c_src.mk +++ b/plugins/c_src.mk @@ -192,10 +192,6 @@ hello(_) -> erlang:nif_error({not_loaded, ?MODULE}). endef -$(foreach template,bs_c_nif bs_erl_nif, \ - $(eval _$(template) = $$(subst $$(tab),$$(WS),$$($(template)))) \ - $(eval export _$(template))) - new-nif: ifneq ($(wildcard $(C_SRC_DIR)/$n.c),) $(error Error: $(C_SRC_DIR)/$n.c already exists) diff --git a/plugins/relx.mk b/plugins/relx.mk index 5aa6196..a27992d 100644 --- a/plugins/relx.mk +++ b/plugins/relx.mk @@ -22,7 +22,7 @@ endif ifeq ($(IS_DEP),) ifneq ($(wildcard $(RELX_CONFIG)),) -rel:: distclean-relx-rel relx-rel +rel:: relx-rel endif endif @@ -34,7 +34,7 @@ $(RELX): $(gen_verbose) $(call core_http_get,$(RELX),$(RELX_URL)) $(verbose) chmod +x $(RELX) -relx-rel: $(RELX) rel-deps +relx-rel: $(RELX) rel-deps app $(verbose) $(RELX) -c $(RELX_CONFIG) $(RELX_OPTS) distclean-relx-rel: diff --git a/test/Makefile b/test/Makefile index 8e4d3cc..870f4dc 100644 --- a/test/Makefile +++ b/test/Makefile @@ -61,6 +61,7 @@ OTP_MASTER = https://raw.githubusercontent.com/erlang/otp/master # V=1: Show test commands. # V=2: Also show normal Erlang.mk output. # V=3: Also show verbose Erlang.mk output. +# V=4: Also show a trace of each command after expansion. V ?= 0 diff --git a/test/core_upgrade.mk b/test/core_upgrade.mk index c4a8725..60adaab 100644 --- a/test/core_upgrade.mk +++ b/test/core_upgrade.mk @@ -1,6 +1,6 @@ # Core: Erlang.mk upgrade. -CORE_UPGRADE_CASES = custom-build-dir custom-config custom-repo no-config renamed-config +CORE_UPGRADE_CASES = conflicting-configs custom-build-dir custom-config custom-repo no-config renamed-config CORE_UPGRADE_TARGETS = $(addprefix core-upgrade-,$(CORE_UPGRADE_CASES)) CORE_UPGRADE_CLEAN_TARGETS = $(addprefix clean-,$(CORE_UPGRADE_TARGETS)) @@ -13,6 +13,35 @@ $(CORE_UPGRADE_CLEAN_TARGETS): core-upgrade: $(CORE_UPGRADE_TARGETS) +core-upgrade-conflicting-configs: build clean-core-upgrade-conflicting-configs + + $i "Bootstrap a new OTP library named $(APP)" + $t mkdir $(APP)/ + $t cp ../erlang.mk $(APP)/ + $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v + + $i "Fork erlang.mk locally and modify it" + $t git clone -q https://github.com/ninenines/erlang.mk $(APP)/alt-erlangmk-repo + $t echo core/core > $(APP)/alt-erlangmk-repo/build.config + $t (cd $(APP)/alt-erlangmk-repo && \ + git checkout -q -b test-modified-build.config && \ + git config user.email "[email protected]" && \ + git config user.name "test suite" && \ + git commit -q -a -m 'Modify build.config' && \ + git checkout master) + + $i "Point application to an alternate erlang.mk repository" + $t perl -ni.bak -e 'print;if ($$.==1) {print "ERLANG_MK_REPO = file://$(abspath $(APP)/alt-erlangmk-repo)\nERLANG_MK_COMMIT = test-modified-build.config\n"}' $(APP)/Makefile + + $i "Create a custom build.config file without plugins" + $t echo "core/*" > $(APP)/build.config + + $i "Upgrade Erlang.mk" + $t $(MAKE) -C $(APP) erlang-mk $v + + $i "Check that the bootstrap plugin is gone" + $t ! $(MAKE) -C $(APP) list-templates $v + core-upgrade-custom-build-dir: build clean-core-upgrade-custom-build-dir $i "Bootstrap a new OTP library named $(APP)" @@ -69,7 +98,8 @@ core-upgrade-custom-repo: build clean-core-upgrade-custom-repo git checkout -q -b test-copyright && \ git config user.email "[email protected]" && \ git config user.name "test suite" && \ - git commit -q -a -m 'Add Testsuite copyright') + git commit -q -a -m 'Add Testsuite copyright' && \ + git checkout master) $i "Point application to an alternate erlang.mk repository" $t perl -ni.bak -e 'print;if ($$.==1) {print "ERLANG_MK_REPO = file://$(abspath $(APP)/alt-erlangmk-repo)\nERLANG_MK_COMMIT = test-copyright\n"}' $(APP)/Makefile diff --git a/test/plugin_bootstrap.mk b/test/plugin_bootstrap.mk index 16bfb58..47a81d1 100644 --- a/test/plugin_bootstrap.mk +++ b/test/plugin_bootstrap.mk @@ -1,6 +1,6 @@ # Bootstrap plugin. -BOOTSTRAP_CASES = app lib rel templates +BOOTSTRAP_CASES = app lib rel sp tab templates BOOTSTRAP_TARGETS = $(addprefix bootstrap-,$(BOOTSTRAP_CASES)) BOOTSTRAP_CLEAN_TARGETS = $(addprefix clean-,$(BOOTSTRAP_TARGETS)) @@ -116,6 +116,67 @@ endif $i "Check that there's no erl_crash.dump file" $t test ! -f $(APP)/_rel/$(APP)_release/erl_crash.dump +bootstrap-sp: build clean-bootstrap-sp + + $i "Bootstrap a new OTP application named $(APP)" + $t mkdir $(APP)/ + $t cp ../erlang.mk $(APP)/ + $t $(MAKE) -C $(APP) -f erlang.mk bootstrap SP=2 $v + + $i "Check that all bootstrapped files exist" + $t test -f $(APP)/Makefile +ifdef LEGACY + $t test -f $(APP)/src/$(APP).app.src +endif + $t test -f $(APP)/src/$(APP)_app.erl + $t test -f $(APP)/src/$(APP)_sup.erl + + $i "Check that bootstrapped files have no tabs" +ifdef LEGACY + $t test -z "`awk -F "\t" 'NF > 1' $(APP)/src/$(APP).app.src`" +endif + $t test -z "`awk -F "\t" 'NF > 1' $(APP)/src/$(APP)_app.erl`" + $t test -z "`awk -F "\t" 'NF > 1' $(APP)/src/$(APP)_sup.erl`" + +# Everything looks OK, but let's compile the application to make sure. + $i "Build the application" + $t $(MAKE) -C $(APP) $v + + $i "Check that all compiled files exist" + $t test -f $(APP)/ebin/$(APP).app + $t test -f $(APP)/ebin/$(APP)_app.beam + $t test -f $(APP)/ebin/$(APP)_sup.beam + + $i "Check that the application was compiled correctly" + $t $(ERL) -pa $(APP)/ebin/ -eval " \ + ok = application:start($(APP)), \ + {ok, [$(APP)_app, $(APP)_sup]} = application:get_key($(APP), modules), \ + {module, $(APP)_app} = code:load_file($(APP)_app), \ + {module, $(APP)_sup} = code:load_file($(APP)_sup), \ + halt()" + +bootstrap-tab: build clean-bootstrap-tab + + $i "Bootstrap a new OTP application named $(APP)" + $t mkdir $(APP)/ + $t cp ../erlang.mk $(APP)/ + $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v + + $i "Check that all bootstrapped files exist" + $t test -f $(APP)/Makefile +ifdef LEGACY + $t test -f $(APP)/src/$(APP).app.src +endif + $t test -f $(APP)/src/$(APP)_app.erl + $t test -f $(APP)/src/$(APP)_sup.erl + + $i "Check that bootstrapped files have tabs" +ifdef LEGACY + $t test "`awk -F "\t" 'NF > 1' $(APP)/src/$(APP).app.src`" +endif + $t test "`awk -F "\t" 'NF > 1' $(APP)/src/$(APP)_app.erl`" + $t test "`awk -F "\t" 'NF > 1' $(APP)/src/$(APP)_sup.erl`" + bootstrap-templates: build clean-bootstrap-templates $i "Bootstrap a new OTP library named $(APP)" |