Browse Source

Modernize the protobuffs plugin

Loïc Hoguin 6 years ago
parent
commit
7a514c6a37
5 changed files with 110 additions and 19 deletions
  1. 1 3
      build.config
  2. 4 2
      core/erlc.mk
  3. 3 3
      plugins/erlydtl.mk
  4. 24 11
      plugins/protobuffs.mk
  5. 78 0
      test/plugin_protobuffs.mk

+ 1 - 3
build.config

@@ -10,9 +10,6 @@ index/*
 core/index
 core/deps
 
-# Plugins that must run before Erlang code gets compiled.
-plugins/protobuffs
-
 # Core modules, continued.
 core/erlc
 core/docs
@@ -32,6 +29,7 @@ plugins/erlydtl
 plugins/escript
 plugins/eunit
 plugins/proper
+plugins/protobuffs
 plugins/relx
 plugins/shell
 plugins/sphinx

+ 4 - 2
core/erlc.mk

@@ -247,8 +247,10 @@ define makedep.erl
 	end,
 	[begin
 		Mod = list_to_atom(filename:basename(F, ".erl")),
-		{ok, Fd} = file:open(F, [read]),
-		MakeDepend(MakeDepend, Fd, Mod,0)
+		case file:open(F, [read]) of
+			{ok, Fd} -> MakeDepend(MakeDepend, Fd, Mod,0);
+			{error, enoent} -> ok
+		end
 	end || F <- ErlFiles],
 	Depend = sofs:to_external(sofs:relation_to_family(sofs:relation(ets:tab2list(E)))),
 	CompileFirst = [X || X <- lists:reverse(digraph_utils:topsort(G)), [] =/= digraph:in_neighbours(G, X)],

+ 3 - 3
plugins/erlydtl.mk

@@ -27,11 +27,11 @@ BEAM_FILES += $(addsuffix .beam,$(addprefix ebin/,$(DTL_MODULES)))
 ifneq ($(words $(DTL_FILES)),0)
 # Rebuild templates when the Makefile changes.
 $(ERLANG_MK_TMP)/last-makefile-change-erlydtl: $(MAKEFILE_LIST)
-	@mkdir -p $(ERLANG_MK_TMP)
-	@if test -f $@; then \
+	$(verbose) mkdir -p $(ERLANG_MK_TMP)
+	$(verbose) if test -f $@; then \
 		touch $(DTL_FILES); \
 	fi
-	@touch $@
+	$(verbose) touch $@
 
 ebin/$(PROJECT).app:: $(ERLANG_MK_TMP)/last-makefile-change-erlydtl
 endif

+ 24 - 11
plugins/protobuffs.mk

@@ -8,23 +8,36 @@ proto_verbose = $(proto_verbose_$(V))
 
 # Core targets.
 
-define compile_proto
-	$(verbose) mkdir -p ebin/ include/
-	$(proto_verbose) $(call erlang,$(call compile_proto.erl,$(1)))
-	$(proto_verbose) erlc +debug_info -o ebin/ ebin/*.erl
-	$(verbose) rm ebin/*.erl
-endef
+ifneq ($(wildcard src/),)
+PROTO_FILES := $(filter %.proto,$(ALL_SRC_FILES))
+ERL_FILES += $(addprefix src/,$(patsubst %.proto,%_pb.erl,$(notdir $(PROTO_FILES))))
+
+ifeq ($(words $(PROTO_FILES)),0)
+$(ERLANG_MK_TMP)/last-makefile-change-protobuffs:
+	$(verbose) :
+else
+# Rebuild proto files when the Makefile changes.
+# We exclude $(PROJECT).d to avoid a circular dependency.
+$(ERLANG_MK_TMP)/last-makefile-change-protobuffs: $(filter-out $(PROJECT).d,$(MAKEFILE_LIST))
+	$(verbose) mkdir -p $(ERLANG_MK_TMP)
+	$(verbose) if test -f $@; then \
+		touch $(PROTO_FILES); \
+	fi
+	$(verbose) touch $@
+
+$(PROJECT).d:: $(ERLANG_MK_TMP)/last-makefile-change-protobuffs
+endif
 
 define compile_proto.erl
 	[begin
 		protobuffs_compile:generate_source(F,
 			[{output_include_dir, "./include"},
-				{output_src_dir, "./ebin"}])
-	end || F <- string:tokens("$(1)", " ")],
+				{output_src_dir, "./src"}])
+	end || F <- string:tokens("$1", " ")],
 	halt().
 endef
 
-ifneq ($(wildcard src/),)
-ebin/$(PROJECT).app:: $(sort $(call core_find,src/,*.proto))
-	$(if $(strip $?),$(call compile_proto,$?))
+$(PROJECT).d:: $(PROTO_FILES)
+	$(verbose) mkdir -p ebin/ include/
+	$(if $(strip $?),$(proto_verbose) $(call erlang,$(call compile_proto.erl,$?)))
 endif

+ 78 - 0
test/plugin_protobuffs.mk

@@ -0,0 +1,78 @@
+# Protocol buffers plugin.
+
+PROTOBUFFS_TARGETS = $(call list_targets,protobuffs)
+
+.PHONY: protobuffs $(PROTOBUFFS_TARGETS)
+
+protobuffs: $(PROTOBUFFS_TARGETS)
+
+PROTOBUFFS_URL = https://raw.githubusercontent.com/basho/erlang_protobuffs/master/test/erlang_protobuffs_SUITE_data
+
+protobuffs-compile: build clean
+
+	$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 "Add protobuffs to the list of dependencies"
+	$t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = protobuffs\n"}' $(APP)/Makefile
+
+	$i "Download two proto files"
+	$t mkdir $(APP)/src/proto/
+	$t curl -s -o $(APP)/src/proto/empty.proto $(PROTOBUFFS_URL)/proto/empty.proto
+	$t curl -s -o $(APP)/src/proto/simple.proto $(PROTOBUFFS_URL)/proto/simple.proto
+
+	$i "Build the application"
+	$t $(MAKE) -C $(APP) $v
+
+	$i "Check that an Erlang module was generated and compiled"
+	$t test -f $(APP)/src/empty_pb.erl
+	$t test -f $(APP)/src/simple_pb.erl
+	$t test -f $(APP)/include/empty_pb.hrl
+	$t test -f $(APP)/include/simple_pb.hrl
+	$t test -f $(APP)/ebin/empty_pb.beam
+	$t test -f $(APP)/ebin/simple_pb.beam
+
+	$i "Check that the generated modules are included in .app file"
+	$t $(ERL) -pa $(APP)/ebin/ -eval " \
+		ok = application:load($(APP)), \
+		{ok, [empty_pb, simple_pb]} = application:get_key($(APP), modules), \
+		halt()"
+
+protobuffs-makefile-change: build clean
+
+	$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 "Add protobuffs to the list of dependencies"
+	$t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = protobuffs\n"}' $(APP)/Makefile
+
+	$i "Download two proto files"
+	$t mkdir $(APP)/src/proto/
+	$t curl -s -o $(APP)/src/proto/empty.proto $(PROTOBUFFS_URL)/proto/empty.proto
+	$t curl -s -o $(APP)/src/proto/simple.proto $(PROTOBUFFS_URL)/proto/simple.proto
+
+	$i "Build the application"
+	$t $(MAKE) -C $(APP) $v
+
+	$i "Touch the Makefile; check that all files get rebuilt"
+	$t printf "%s\n" \
+		$(APP)/ebin/empty_pb.beam \
+		$(APP)/ebin/simple_pb.beam \
+		$(APP)/ebin/$(APP).app \
+		$(APP)/include/empty_pb.hrl \
+		$(APP)/include/simple_pb.hrl \
+		$(APP)/src/empty_pb.erl \
+		$(APP)/src/proto/simple.proto \
+		$(APP)/src/proto/empty.proto \
+		$(APP)/src/simple_pb.erl \
+		$(APP)/$(APP).d | sort > $(APP)/EXPECT
+	$t $(SLEEP)
+	$t touch $(APP)/Makefile
+	$t $(SLEEP)
+	$t $(MAKE) -C $(APP) $v
+	$t find $(APP) -type f -newer $(APP)/Makefile -not -path "$(APP)/.erlang.mk/*" | sort | diff $(APP)/EXPECT -
+	$t rm $(APP)/EXPECT