Создание цели из найденных каталогов - PullRequest
2 голосов
/ 16 января 2020

Я хочу создать отдельные исполняемые файлы для каждого каталога с именем «test» в моем проекте. Каталог тестов имеет такую ​​структуру: test.mk

test (dir)
|__test.mk
|__testRun.c
|__testRun.h

test.mk содержит зависимости для спецификаций c test, testRun.c - это сам тест.

Таким образом, иерархия выглядит следующим образом :

ROOT
|__Makefile
|__Module1 (dir)
  |__some files
  |__test (dir)
|__Module2 (dir)
   |__some files
   |__test (dir)
|__Module3 (dir)
   |__some files
   |__test (dir)
|__outdir  (dir)
   |__test1 (exec)
   |__test2 (exec)
   |__test3 (exec)

Я хочу запустить один Makefile в root родительском каталоге. Я хочу, чтобы он выполнял поиск по всем test каталогам и создавал тестовые исполняемые файлы в outdirectory. Пока у меня есть это:

Makefile

CFLAGS =    -I$(DIRTEST) -I$(DIRTEST)/..
OUTDIR=     ./outdirectory
DIRTEST =   $(shell find -type d -not -path "$(OUTDIR)/*" -name "test" -prune )

Я не знаю, как создать правило, которое создает целевой исполняемый файл из источников и заголовков из отдельных каталогов. Я искал решение для подобной проблемы, но пока не повезло.

Примечание: я не хочу использовать рекурсивный make. test.mk выглядит, например, так:

SRCTEST = module1/test/testRun.c \
          module1/module1.c
CFLAGS += -Imodule1

Ответы [ 2 ]

0 голосов
/ 16 января 2020

Ваши примеры недостаточно ясны, чтобы мы могли на них ответить.

С одной стороны, не ясно, как имя исполняемого файла теста связано с именем модуля. Действительно ли так, что модули заканчиваются номером, а сгенерированная тестовая программа также должна заканчиваться тем же номером (Module1 -> test1)? Или есть какие-то другие отношения? Похоже, что в файле test.mk нет никакой переменной, содержащей имя теста, так как вычисляется имя теста? каждый test.mk файл. В make нет «области видимости», которая позволит вам сказать «этот экземпляр CFLAGS используется только для этого включенного make-файла». Каждый раз, когда вы добавляете другой файл test.mk, он будет перезаписывать предыдущие настройки.

Это CAN будет выполнено: вам нужно будет использовать комбинацию define переменных для хранения правила определения, затем eval для оценки правил.

Предположим, что вы добавили в test.mk новую переменную, которая определила имя теста, и вы также квалифицировали свои переменные с этим именем; тогда ваша жизнь станет намного проще:

Module1/test/test.mk будет содержать:

TESTNAME = test1
test1_SRCTEST = module1/test/testRun.c \
                module1/module1.c
test1_CFLAGS = -Imodule1

Теперь в вашем основном make-файле вы создадите переменную, содержащую правило, которое вы хотите определить:

define MAKETEST
include $T
$$(OUTDIR)/$$(TESTNAME): $$(OUTDIR)/% : $$($$(TESTNAME)_SRCTEST)
        $$(CC) $$(CPPFLAGS) $$(CFLAGS) $$($$*_CFLAGS) -o $$@ $$^
endef

$(foreach T,$(DIRTEST),$(eval $(MAKETEST)))

Обратите внимание, это не проверено.

0 голосов
/ 16 января 2020

Вы можете использовать bash файлы сценариев для создания переменных, если вы избегаете рекурсивной сборки.

cat module1/test/test.sh 
export SRCTEST="module1/test/testRun.c 
    module1/module1.c"
export CFLAGS="$CFLAGS -Imodule1"

cat module2/test/test.sh 
export SRCTEST="module2/test/testRun.c
          module2/module2.c"
export CFLAGS="$CFLAGS -Imodule2"

Тогда ваш Makefile может выглядеть так:

test1:
    source module1/test/test.sh && gcc -o $@ $$CFLAGS $$SRCTEST
test2:
    source module2/test/test.sh && gcc -o $@ $$CFLAGS $$SRCTEST

Также вы можете сделать что-то с include инструкцией. Переопределения можно избежать, проверив цель сборки, но это не очень хороший способ.

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