сделать файл с подкаталогами источника - PullRequest
8 голосов
/ 11 марта 2011

Мой последний проект на C ++, и я использую GNU Make. Структура каталога проекта выглядит следующим образом:

project
|-src
  |-subdir1
  |-subdir2 (containing tests)
|-doc
|-bin

Я хотел бы иметь возможность вызывать make в каталоге верхнего уровня (т.е. нужен make-файл в каталоге проекта), чтобы скомпилировать все исходные файлы в обоих подкаталогах "src" и поместить полученные двоичные файлы в каталог "bin" ,

Каков наилучший подход для этого? Было бы также неплохо, если бы мне не нужно было добавлять правило make для каждого исходного файла, а просто иметь одно для всех файлов .cc и .h в каталогах.

Ответы [ 3 ]

14 голосов
/ 11 марта 2011

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

project
|-src
  |-subdir1
  |-subdir2 (containing tests)
|-doc
|-bin

Вы можете попробовать что-то вроде этого:

#This finds all your cc files and places then into SRC. It's equivalent would be
# SRC = src/main.cc src/folder1/func1.cc src/folder1/func2.cc src/folder2/func3.cc

SRC = $(shell find . -name *.cc)

#This tells Make that somewhere below, you are going to convert all your source into 
#objects, so this is like:
# OBJ =  src/main.o src/folder1/func1.o src/folder1/func2.o src/folder2/func3.o

OBJ = $(SRC:%.cc=%.o)

#Tells make your binary is called artifact_name_here and it should be in bin/
BIN = bin/artifact_name_here

# all is the target (you would run make all from the command line). 'all' is dependent
# on $(BIN)
all: $(BIN)

#$(BIN) is dependent on objects
$(BIN): $(OBJ)
    g++ <link options etc>

#each object file is dependent on its source file, and whenever make needs to create
# an object file, to follow this rule:
%.o: %.cc
    g++ -c $< -o $@
3 голосов
/ 11 марта 2011

Используйте один make run для сборки (я не фанат рекурсивного make).Не используйте $(shell), так как это снижает производительность.Поместите сборочные продукты во временный каталог.

Эскиз:

subdir1-srcs := $(addprefix subdir1/,1.cc 2.cc 3.cc)
subdir1-objs := ${subdir1-srcs:subdir1/%.cc=subdir1/obj/%.o)
bin/prog1: ${subdir1-objs} ; gcc $^ -o $@
${subdir1-objs}: subdir1/obj/%.o: subdir1/%.cc # Static pattern rules rule
    gcc -c $< -o $@
${subdir1-objs}: subdir1/obj/.mkdir # Need to create folder before compiling
subdir1/obj/.mkdir:
    mkdir -p ${@D}
    touch $@

Вы видите здесь плиту котла?Несколько функций вместе с $(eval) должны позволять вам писать:

$(call build,bin/prog1,subdir1,1.cc 2.cc 3.cc)
$(call build,bin/prog2,subdir2,a.cc b.cc c.cc d.cc)

, причем эти цели автоматически добавляются как зависимости от фальшивых all и прекрасно -j совместимых (просто наберите make -j5 all длястроить).

0 голосов
/ 11 марта 2011

Вам нужно будет создать подкаталог внутри каталогов и использовать команды для вывода скомпилированных файлов g ++ в нужные вам каталоги.(Используйте переменные make-файла и т.д. ...)

Здесь вы найдете хорошее введение в рекурсивные файлы Makefile

Makefile, позволяющий использовать некоторые общие правила, такие как:

%.o:%.cpp
    gcc blahblahblah

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

Если вы также создадите Google Makefile, вы найдете множество инструкций по этому вопросу.

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