отдельные сборки в отдельных каталогах - PullRequest
0 голосов
/ 03 сентября 2011

Я уверен, что это совершенно нормальная вещь, но я не могу понять, как заставить make сделать это.

У меня есть компилятор, который генерирует зависимости make обычной формы:

M/A.o : M/A.hs
M/B.o : M/A.o

Поэтому я пишу правило для компиляции% .hs в% .o, добавляю правило для связывания двоичного файла, включаю файл зависимостей, и все хорошо.Но я хочу иметь несколько бинарных целей с разными флагами.Например, я хочу собрать / протестировать с помощью -DTESTING и построить / профиль с помощью -prof.Поэтому мне нужно хранить файлы .o в отдельном дереве, где они будут компилироваться со специальными флагами.

Простой способ, которым я могу придумать, - это иметь зависимости, которые выглядят примерно так:

build/test/M/A.o : M/A.hs
build/test/M/B.o : build/test/M/A.o

build/profile/M/A.o : M/A.hs
... etc.

И затем правила так, что% .hs для сборки / test /%. O компилируется с -DTESTING и т. Д. Я думаю, что это будет работать, но это неуклюже, означает предварительную обработку файла deps, чтобы добавить все эти сборки /независимо от префикса и преумножения его размера на сколько угодно типов.

VPATH, похоже, предназначен для такого рода вещей, и моя идея заключалась в том, чтобы я мог установить флаги VPATH и компилятора в зависимости от цели, и это почти работает, но:

%.o: %.hs
    @mkdir -p build/M
    cp $< build/$@

VPATH = build

main: M/A.o M/B.o
    cat $^ >$@

M/A.o : M/A.hs
M/B.o : M/B.hs

Первый раз, когда главная цель хочет запустить 'cat M / Ao M / Bo> main', что, кажется, противоречит документации GNU Make, в которой написано, что $ ^включите каталог VPATH, в котором была найдена зависимость.Любопытно, что если я удаляю «main» и делаю снова, на этот раз он использует правильный путь.Это GNU make, 3.81.

Что здесь происходит?Есть ли лучший способ построить с разными флагами?VPATH кажется неуклюжим инструментом, наверняка есть лучший способ?

Ответы [ 2 ]

1 голос
/ 03 сентября 2011

Make работает правильно.Он пытается cat M/A.o M/B.o >main в первый раз, потому что не может найти необходимые предварительные условия, но знает правило для M/A.o' and M / Bo (<em>not</em> build / M / Ao 'и build/M/B.o) и ожидает, что эточто будет производить правило.Если вы удалите main и повторите попытку, он найдет build/M/A.o' and build / M / Bo` через VPATH.

Давайте изменим этот make-файл поэтапно.Сначала мы изменим VPATH так, чтобы он мог найти .hs файлы (Make хорош в использовании вещей там для создания вещей здесь , а не наоборот, и это то, что VPATHхорошо) и немного изменим правила:

build/%.o: %.hs
    cp $< $@

VPATH = M

main: build/A.o build/B.o
    cat $^ > $@

Теперь для разных каталогов объектов.

build/test/%.o build/project/%.o: %.hs
    cp $< $@

VPATH = M

test: build/test/A.o build/test/B.o
    cat $^ > $@

project: build/project/A.o build/project/B.o
    cat $^ > $@

Затем мы упростим эти два последних правила, чтобы было легче добавить большеобъектные файлы и двоичные цели:

OBJECTS = A.o B.o

test: $(addprefix build/test/,$(OBJECTS))
project: $(addprefix build/project/,$(OBJECTS))

test project:
    cat $^ > $@

Теперь для различных флагов компилятора:

build/test/%.o: FLAGS += test_flags
build/project/%.o: FLAGS += proj_flags

build/test/%.o build/project/%.o: %.hs
    @echo building $@ from $^ using flags $(FLAGS)
    cp $< $@

Наконец, зависимости.Это немного сложно.Предположим, вы хотите, чтобы зависимость B.o : A.hs применялась ко всем имеющимся у вас объектам.Это один из подходов:

OBJECT_PATHS = build/test/ build/project/

# The following is from the included file generated by the compiler
$(addsuffix B.o,$(OBJECT_PATHS)) : A.hs

Чтобы сгенерировать такие строки, я бы направил необработанные строки (например, B.o: A.hs) через sed 's/\(.*\):\(.*\)/\1:\2/' и заметил бы, что если вы хотите поместить это в make-файлкоманда, не забудьте удвоить знаки $, чтобы сохранить их для оболочки.

Я знаю, что это много, чтобы поглотить.Делайте это по одному шагу за раз и дайте нам знать, как это работает.

0 голосов
/ 29 сентября 2011

Если вы до сих пор не решили свою проблему или испытываете дальнейшие проблемы, лучше всего дайте шанс autotools (automake и autoconf).Они быстро создадут вам Makefile, который поддерживает более настраиваемые и гибкие сборки из дерева.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...