2009-12-12 91 views
2

我有以下的Makefile建立我的二郎项目:如何在Makefile输出中将两个不同的源目录输出到一个bin目录?

.SUFFIXES: .erl .beam .yrl 

ERL_SRC := $(wildcard src/*.erl) 
ERL_OBJ := $(patsubst src/%.erl,ebin/%.beam,${ERL_SRC}) 

all: main 

main: ${ERL_OBJ} 

ebin/%.beam: src/%.erl 
     erlc +debug_info -W -o ebin $< 

clean: 
     rm -fr ebin/*.beam 

我试图更新这也是建立我eunit测试,在测试/ eunit文件夹,并具有输出到同一个文件夹EBIN作为在src像这样:

.SUFFIXES: .erl .beam .yrl 

ERL_SRC := $(wildcard src/*.erl) 
ERL_OBJ := $(patsubst src/%.erl,ebin/%.beam,${ERL_SRC}) 
EUNIT_SRC := $(wildcard test/eunit/*.erl) 
EUNIT_OBJ := $(patsubst test/eunit/%.erl,ebin/%.beam,${EUNIT_SRC}) 

all: main 

main: ${ERL_OBJ} 

ebin/%.beam: src/%.erl test/eunit/%.erl 
     erlc +debug_info -W -o ebin $< 

clean: 
     rm -fr ebin/*.beam 

eunit: ${EUNIT_OBJ} 

test: main eunit 

制作主要工作正常,但如果我尝试使测试失败:

make: *** No rule to make target `ebin/data_eunit.beam', needed by `eunit'. Stop. 

测试模块data_eunit.erl位于测试/ eunit。这个问题似乎与ebin /%beam目标有关。如果我将src /%。erl与test/eunit /%。erl交换,那么我可以构建测试,但不是src。我如何从两个源文件夹构建并将输出转到一个输出文件夹?

+0

我肯定新的使用使/ Makefile文件。我试图研究一个解决方案,但我正在努力寻找解决方案。 – 2009-12-12 18:56:34

回答

5

您可以使用VPATH/VPATH在Makefile

.SUFFIXES: .erl .beam .yrl 

# use vpath to tell make where to search for %.erl files 
vpath %.erl src eunit 
# or use VPATH to tell make where to search for any prerequisite 
# VPATH=src:eunit  

ERL_OBJ = $(patsubst src/%.erl,ebin/%.beam, $(wildcard src/*erl)) 
ERL_OBJ += $(patsubst eunit/%.erl,ebin/%.beam, $(wildcard eunit/*erl)) 

all: main 

main: ${ERL_OBJ} 

ebin/%.beam: %.erl 
    erlc +debug_info -W -o ebin $< 

clean: 
    rm -fr ebin/*.beam 
+0

现在这就是我正在寻找的。非常感谢,它像一个魅力。 – 2009-12-17 21:11:36

0

您应该制作另一个将该树编译为ebin的目标,使其依赖于原始构建目标。

2

这不会真的回答你的问题,但我不喜欢有污染我的ebin /测试代码的风险。所以这是我如何安排我的顶层的Makefile:

all: 
    (cd src && erl -make) 

test: 
    (cd test && erl -make && \ 
     erl -noinput -eval 'eunit:test({dir, "."}, [verbose]), init:stop()') 

然后我把下列src/Emakefile

{['*'], 
[{outdir,"../ebin"}]}. 

而进入test/Emakefile我把

{['../src/*'], 
[debug_info, {d, 'TEST'}]}. 
{['*'], 
[debug_info, {d, 'TEST'}]}. 

所以,如果我跑make all然后src/*。erl被编译到ebin /中,但是如果我运行make test,我将src/*。erl和test/*。erl编译到test /中,并在那里运行所有的beam文件试验。

当编译宏被启用,因此,如果用的ifdef为eunit引导装置包围该单元测试是禁用的测试表明:

-ifdef(TEST). 
test_code_() -> ... 
-endif. 

它的设置,我是相当满意。

+0

我正在寻找类似的东西,但更喜欢所有的束文件在ebin中结束 - 不要混合与erl文件混合的束文件。 – 2009-12-13 02:11:50

+0

这是微不足道的完成。 – Christian 2009-12-13 10:33:49

4

也许你应该大大简化你的构建。我的二郎构建系统只是调用erl -make与Emakefile看起来像这样:

{"src/*", [debug_info, {outdir, "ebin"}, {i, "include"}]}. 

你可以,当然,有一个以上的SRC LOC更多,只是混合测试和常规代码 - 你已经在ebin中混合它们。不要让自己比自己更难。

+0

我不介意在同一个ebin目录下编译输出,但更喜欢将应用程序和测试源代码分开。 – 2009-12-13 18:08:05

+0

现在天螺纹钢(https://github.com/basho/rebar)是Erlang应用程序的方式。 – 2012-01-25 21:35:24

0

这是做什么我想:

.SUFFIXES: .erl .beam .yrl 

ERL_SRC := $(wildcard src/*.erl) 
ERL_OBJ := $(patsubst src/%.erl,ebin/%.beam,${ERL_SRC}) 
EUNIT_SRC := $(wildcard test/eunit/*.erl) 
EUNIT_OBJ := $(patsubst test/eunit/%.erl,ebin/%.beam,${EUNIT_SRC}) 

all: main 

main: ${ERL_OBJ} 

${ERL_OBJ}: ${ERL_SRC} 
     erlc +debug_info -W -o ebin $< 

clean: 
     rm -fr ebin/*.beam 

${EUNIT_OBJ}: ${EUNIT_SRC} 
     erlc +debug_info -W -o ebin $< 

eunit: ${EUNIT_OBJ} 

test: main eunit 

任何其他办法可以改善吗?也许可以将$ {ERL_OBJ}和$ {EUNIT_OBJ}中的类似编译行移动到一个变量中。

0

而不是 “EBIN /%束:。SRC /%的ERL测试/ eunit /%的ERL” 你有尝试过:

%.beam:%。ERL

+0

这不起作用,因为我的Makefile与源或输出不在同一个目录中。我有 ./Makefile ./src ./test/eunit – 2009-12-14 11:59:45