Использование Makefiles во вложенных каталогах - PullRequest
0 голосов
/ 07 февраля 2019

Проект, над которым я работаю, связан с несколькими архитектурами.Код разделен на специфичные для архитектуры и общие модули (которые могут совместно использоваться архитектурами).

Я планирую организовать код следующим образом:

TOP
|
|---- Makefile
|
|---- src (arch independent)
|---- inc (arch independent)
|
|----arch1 (arch specific)
     |---- src 
     |---- inc 
     |---- Makefile
|----arch2 (arch specific)
     |---- src
     |---- src
     |---- Makefile

Проект для конкретной арки будетскомпилирован Makefile в каталоге arch.Этот make-файл включает Makefile на верхнем уровне.

Идея заключалась в том, что в конкретном make-файле arch будет весь код src из каталога arch, а Makefile верхнего уровня определяет переменную, которая является просто путемкаталог верхнего уровня, так что специфичный для arch Makefile может включать в себя код из папки src на верхнем уровне.

Однако при включении Makefile верхнего уровня определяется определенная переменная пути (с помощью команды shell pwd)на уровне директории, специфичной для архива.

Как я могу решить эту проблему?Это лучший способ сделать это?

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

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Чем занимается ваш make-файл верхнего уровня?- Я имею в виду, вы можете запустить make на нем автономно?Если нет, то все, что вы на самом деле извлекаете из этого, это список исходных файлов и местоположений заголовков - было бы проще просто указать их в common_make.mk или что-то, что содержит только:

SOURCES += ../src/test1.c
SOURCES += ../src/test2.c
SOURCES += ../src/test3.c
INC += ../inc

затемоба ваших файла нижнего уровня содержат этот очень простой «фрагмент» make-файла, и вам не нужно беспокоиться о путях.

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

arch1/
   |--src
   |--inc
   |--common (repo)
       |--inc
       |--src 

arch2/
   |--src
   |--inc
   |--common (repo)
       |--inc
       |--src 

Итак, у меня есть два отдельных репо с общим суб-репо.Если вы хотите связать два проекта archx вместе, вы можете добавить их в супер-репо с его собственным make-файлом, который просто делает:

make -C arch1
make -C arch2
0 голосов
/ 07 февраля 2019

Я вижу два варианта для вас

Общий шаблон make-файла для archX / directory *

# ./Makefile.template
ARCH_DIR        := $(PWD)
TOP_DIR         := $(ARCH_DIR)/..
BUILD_DIR       := $(TOP_DIR)/build

# non-architecture specific source code
NOARCH_SRC_DIR  := $(TOP_DIR)/src
NOARCH_INC_DIR  := $(TOP_DIR)/inc

# non-architecture specific source code
ARCH_SRC_DIR    := $(ARCH_DIR)/src
ARCH_INC_DIR    := $(ARCH_DIR)/inc

# other stuff...
CFLAGS          := -I$(ARCH_INC_DIR) -I$(NOARCH_INC_DIR)

# directory specific variables, e.g. XXX_SRCS
include $(NOARCH_SRC_DIR)/Makefile.include
include $(ARCH_SRC_DIR)/Makefile.include

# generate object file lists
NOARCH_OBJS     := $(NOARCH_SRCS:%.c=$(BUILD_DIR)/%.o)
ARCH_OBJS       := $(ARCH_SRCS:%.c=$(BUILD_DIR)/%.o)

# add paths to source files
NOARCH_SRCS     := $(addprefix $(NOARCH_SRC_DIR)/, $(NOARCH_SRC_DIR))
ARCH_SRCS       := $(addprefix $(ARCH_SRC_DIR)/,   $(ARCH_SRC_DIR))

# target-specific pattern rules for C files
$(NOARCH_OBJS): %.o: $(NOARCH_SRC_DIR)/%.c | $(BUILD_DIR)
      $(CC) $(CFLAGS) -o $@ -c $<

$(ARCH_OBJS): %.o: $(ARCH_SRC_DIR)/%.c | $(BUILD_DIR)
      $(CC) $(CFLAGS) -o $@ -c $<

... and so ...

ArchX / make-файл directory

# archX/Makefile
# common stuff
include $(PWD)/../Makefile.template

# arch specific targets follow here...

Теперь вы уже можете запуститьсборка с использованием

 $ make -C arch1

Каталог верхнего уровня Makefile

 # ./Makefile
 ifndef ARCH
 $(error you must specifiy ARCH=)
 endif

 # forward all targets to arch directory
 %:
      $(MAKE) -C $(ARCH) $(MAKECMDGOAL)

Теперь вы можете запустить сборку с использованием

 $ make ARCH=arch1

Лично я бы не стал писать на верхнем уровнеmakefile вообще и используйте только первый подход.


ИМХО вам следует избегать таких вещей, как $(shell).Но, может быть, это только мое личное мнение, возьмите это с крошкой соли ...

...