R – How to make two different source directories in a Makefile output to one bin directory

erlangmakefile

I have the following Makefile to build my erlang project:

.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

I'm trying to update this to also build my eunit tests in the test/eunit folder and have the output go to the same ebin folder as the src like this:

.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

Making main works fine, but if I try make test it fails with:

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

The test module data_eunit.erl is located in test/eunit. The problem seems to be with the ebin/%.beam target. If I swap src/%.erl with test/eunit/%.erl then I can build the tests but not the src. How can I do a build from two source folders and have the output go to one output folder?

Best Answer

You can use the vpath/VPATH in your 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
Related Topic