diff options
author | Matthias Radestock <matthias@lshift.net> | 2010-01-29 15:04:07 +0000 |
---|---|---|
committer | Matthias Radestock <matthias@lshift.net> | 2010-01-29 15:04:07 +0000 |
commit | c48aec6cfdcdbf0c61182d442ea6c064e75e81d7 (patch) | |
tree | 839f288735882bb7cd0c99359925bc80779f1af9 | |
parent | e90ccbba252da857b3d7da5dd932dc3e4a12d356 (diff) | |
download | rabbitmq-server-c48aec6cfdcdbf0c61182d442ea6c064e75e81d7.tar.gz |
automatic, and accurate, make dependencies
...taking into account includes and behaviours
This code was originally committed as part of bug21673
-rw-r--r-- | .hgignore | 1 | ||||
-rw-r--r-- | Makefile | 23 | ||||
-rw-r--r-- | generate_deps | 52 |
3 files changed, 67 insertions, 9 deletions
@@ -4,6 +4,7 @@ syntax: glob *.swp *.patch erl_crash.dump +deps.mk syntax: regexp ^cover/ @@ -6,12 +6,14 @@ RABBITMQ_SERVER_START_ARGS ?= RABBITMQ_MNESIA_DIR ?= $(TMPDIR)/rabbitmq-$(RABBITMQ_NODENAME)-mnesia RABBITMQ_LOG_BASE ?= $(TMPDIR) +DEPS_FILE=deps.mk SOURCE_DIR=src EBIN_DIR=ebin INCLUDE_DIR=include -SOURCES=$(wildcard $(SOURCE_DIR)/*.erl) -BEAM_TARGETS=$(EBIN_DIR)/rabbit_framing.beam $(patsubst $(SOURCE_DIR)/%.erl, $(EBIN_DIR)/%.beam, $(SOURCES)) -TARGETS=$(EBIN_DIR)/rabbit.app $(BEAM_TARGETS) +INCLUDES=$(wildcard $(INCLUDE_DIR)/*.hrl) $(INCLUDE_DIR)/rabbit_framing.hrl +SOURCES=$(wildcard $(SOURCE_DIR)/*.erl) $(SOURCE_DIR)/rabbit_framing.erl +BEAM_TARGETS=$(patsubst $(SOURCE_DIR)/%.erl, $(EBIN_DIR)/%.beam, $(SOURCES)) +TARGETS=$(EBIN_DIR)/rabbit.app $(INCLUDE_DIR)/rabbit_framing.hrl $(BEAM_TARGETS) WEB_URL=http://stage.rabbitmq.com/ MANPAGES=$(patsubst %.pod, %.gz, $(wildcard docs/*.[0-9].pod)) @@ -56,15 +58,15 @@ ERL_CALL=erl_call -sname $(RABBITMQ_NODENAME) -e ERL_EBIN=erl -noinput -pa $(EBIN_DIR) -all: $(TARGETS) +all: $(DEPS_FILE) $(TARGETS) + +$(DEPS_FILE): $(SOURCES) $(INCLUDES) + escript generate_deps $(INCLUDE_DIR) $(SOURCE_DIR) \$$\(EBIN_DIR\) $(DEPS_FILE) $(EBIN_DIR)/rabbit.app: $(EBIN_DIR)/rabbit_app.in $(BEAM_TARGETS) generate_app escript generate_app $(EBIN_DIR) $@ < $< -$(EBIN_DIR)/gen_server2.beam: $(SOURCE_DIR)/gen_server2.erl - erlc $(ERLC_OPTS) $< - -$(EBIN_DIR)/%.beam: $(SOURCE_DIR)/%.erl $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit.hrl $(EBIN_DIR)/gen_server2.beam +$(EBIN_DIR)/%.beam: $(SOURCE_DIR)/%.erl erlc $(ERLC_OPTS) -pa $(EBIN_DIR) $< # ERLC_EMULATOR="erl -smp" erlc $(ERLC_OPTS) -pa $(EBIN_DIR) $< @@ -100,6 +102,7 @@ clean: rm -f $(INCLUDE_DIR)/rabbit_framing.hrl $(SOURCE_DIR)/rabbit_framing.erl codegen.pyc rm -f docs/*.[0-9].gz rm -f $(RABBIT_PLT) + rm -f $(DEPS_FILE) cleandb: rm -rf $(RABBITMQ_MNESIA_DIR)/* @@ -170,7 +173,7 @@ srcdist: distclean sed -i.save 's/%%VSN%%/$(VERSION)/' $(TARGET_SRC_DIR)/ebin/rabbit_app.in && rm -f $(TARGET_SRC_DIR)/ebin/rabbit_app.in.save cp -r $(AMQP_CODEGEN_DIR)/* $(TARGET_SRC_DIR)/codegen/ - cp codegen.py Makefile generate_app calculate-relative $(TARGET_SRC_DIR) + cp codegen.py Makefile generate_app generate_deps calculate-relative $(TARGET_SRC_DIR) cp -r scripts $(TARGET_SRC_DIR) cp -r docs $(TARGET_SRC_DIR) @@ -220,3 +223,5 @@ install: all docs_all install_dirs install_dirs: mkdir -p $(SBIN_DIR) mkdir -p $(TARGET_DIR)/sbin + +-include $(DEPS_FILE) diff --git a/generate_deps b/generate_deps new file mode 100644 index 00000000..916006d1 --- /dev/null +++ b/generate_deps @@ -0,0 +1,52 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +-mode(compile). + +main([IncludeDir, ErlDir, EbinDir, TargetFile]) -> + ErlDirContents = filelib:wildcard("*.erl", ErlDir), + ErlFiles = [filename:join(ErlDir, FileName) || FileName <- ErlDirContents], + Modules = sets:from_list( + [list_to_atom(filename:basename(FileName, ".erl")) || + FileName <- ErlDirContents]), + Headers = sets:from_list( + [filename:join(IncludeDir, FileName) || + FileName <- filelib:wildcard("*.hrl", IncludeDir)]), + Deps = lists:foldl( + fun (Path, Deps1) -> + dict:store(Path, detect_deps(IncludeDir, EbinDir, + Modules, Headers, Path), + Deps1) + end, dict:new(), ErlFiles), + {ok, Hdl} = file:open(TargetFile, [write, delayed_write]), + dict:fold( + fun (_Path, [], ok) -> + ok; + (Path, Dep, ok) -> + Module = filename:basename(Path, ".erl"), + ok = file:write(Hdl, [EbinDir, "/", Module, ".beam:"]), + ok = sets:fold(fun (E, ok) -> file:write(Hdl, [" ", E]) end, + ok, Dep), + file:write(Hdl, [" ", ErlDir, "/", Module, ".erl\n"]) + end, ok, Deps), + ok = file:write(Hdl, [TargetFile, ": ", escript:script_name(), "\n"]), + ok = file:sync(Hdl), + ok = file:close(Hdl). + +detect_deps(IncludeDir, EbinDir, Modules, Headers, Path) -> + {ok, Forms} = epp:parse_file(Path, [IncludeDir], [{use_specs, true}]), + lists:foldl( + fun ({attribute, _LineNumber, behaviour, Behaviour}, Deps) -> + case sets:is_element(Behaviour, Modules) of + true -> sets:add_element( + [EbinDir, "/", atom_to_list(Behaviour), ".beam"], + Deps); + false -> Deps + end; + ({attribute, _LineNumber, file, {FileName, _LineNumber1}}, Deps) -> + case sets:is_element(FileName, Headers) of + true -> sets:add_element(FileName, Deps); + false -> Deps + end; + (_Form, Deps) -> + Deps + end, sets:new(), Forms). |