2009-12-12 4 views
2

J'ai le Makefile suivant pour construire mon projet Erlang:Comment créer deux répertoires sources différents dans une sortie Makefile dans un répertoire 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 

Je suis en train de mettre à jour ce aussi construire mes tests eunit dans le test/dossier eunit et que la sortie va dans le même dossier de ebin que src comme ceci:

.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 

faire principaux fonctionne très bien, mais si je tente make test échoue avec:

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

le module de test data_eunit.erl est situé dans test/eunit. Le problème semble être avec la cible ebin /%. Si j'échange src /%. Erl avec test/eunit /%. Erl alors je peux construire les tests mais pas le src. Comment puis-je faire une construction à partir de deux dossiers source et avoir la sortie aller à un dossier de sortie?

+0

Je suis vraiment nouveau à l'utilisation de make/Makefile. J'ai essayé de trouver une solution mais j'ai du mal à trouver une solution. –

Répondre

5

Vous pouvez utiliser le vpath/VPATH dans votre 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

Maintenant c'est ce que je cherchais. Merci beaucoup, ça fonctionne comme un charme. –

0

Vous devez créer une autre cible qui compile cet arbre dans ebin, en fonction de la cible de construction d'origine.

2

Cela ne répondra pas vraiment à votre question, mais je n'aime pas risquer de polluer mon ebin/avec du code activé par les tests. Voilà donc comment organiser mon Makefile de premier niveau:

all: 
    (cd src && erl -make) 

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

Puis-je mettre ce qui suit dans src/Emakefile:

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

Et en test/Emakefile je mets

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

Donc, si je lance make all alors src/*. erl est compilé dans ebin /, mais si je lance make test, je compile src/*. erl et test/*. erl en test/et j'exécute tous les fichiers de faisceaux avec l'unité tests.

Lors de la compilation des tests la macro TEST est activé afin que tests unitaires sont désactivées si entouré de ifdefs comme le guide eunit suggèrent:

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

Son une configuration que je suis tout à fait satisfait.

+0

Je suis à la recherche de quelque chose de similaire mais préfère tous les fichiers de poutre pour finir dans ebin - ne pas attiser les fichiers faisceau mélangés avec des fichiers erl. –

+0

C'est trivialement accompli. – Christian

4

Peut-être que vous devriez grandement simplifier votre construction. Mes systèmes de construction de Erlang invoquent simplement erl -make avec un Emakefile qui ressemble à ceci:

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

Vous pouvez, bien entendu, plus d'un src loc, mais il suffit de mélanger les tests et le code régulier - vous êtes déjà les mélanger dans ebin. Ne le rends pas plus difficile pour toi que ce qu'il doit être.

+0

Cela ne me dérange pas la sortie de compilation dans le même répertoire ebin mais préfère que l'application et le code source du test soient séparés. –

+0

Maintenant rebars jours (https://github.com/basho/rebar) est le chemin à parcourir pour les applications Erlang. –

0

Ce fait ce que je veux:

.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 

Toute autre façon que je peux améliorer cela? Peut-être déplacer des lignes de compilation similaires dans $ {ERL_OBJ} et $ {EUNIT_OBJ} à une variable.

0

Au lieu de "ebin /% faisceau:... Src /% Test ERL/eunit /% ERL" Avez-vous essayé juste:

% .beam:%.ERL

+0

Cela ne fonctionne pas car mon Makefile n'est pas dans le même répertoire que la source ou la sortie. J'ai ./Makefile ./src ./test/eunit –

Questions connexes