Создание файлов с исходными файлами в разных каталогах



У меня есть проект, где структура каталогов, как это:



                         $projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/


Как я должен написать файл makefile, который будет частично / src (или где бы то ни было), который может частично дополнять/связывать исходные файлы c/c++?/ src ?



могу ли я сделать что-то вроде
-Я$projectroot/часть1/Ница-я$projectroot/часть1/МКП-я$projectroot/часть2/ГРЦ ...



Если это сработает, есть ли более простой способ сделать это. Я видел проекты, где есть makefile в каждом из соответствующая часть? папки. [в этом посте я использовал знак вопроса, как в синтаксисе bash]

615   9  

9 ответов:

традиционный способ-это Makefile в каждом из подкаталогов (part1,part2 и т. д.) позволяет строить их самостоятельно. Далее, есть Makefile в корневом каталоге проекта, который строит все. "Корень"Makefile будет выглядеть примерно так:

all:
    +$(MAKE) -C part1
    +$(MAKE) -C part2
    +$(MAKE) -C part3

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

Я предлагаю взглянуть на GNU сделать ручной раздел 5.7; это очень полезно.

Если у вас есть код в одном подкаталоге, зависящий от кода в другом подкаталоге, вам, вероятно, лучше использовать один файл makefile на верхнем уровне.

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

ссылка выше, кажется, нет достижимый. Тот же документ доступен здесь:

опция VPATH может пригодиться, которая говорит, какие каталоги искать в исходном коде. Однако вам все равно понадобится опция-I для каждого пути включения. Пример:

CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src

OutputExecutable: part1api.o part2api.o part3api.o

это автоматически найдет соответствующий partXapi.cpp файлы в любом из указанных каталогов VPATH и скомпилировать их. Однако это более полезно, когда ваш каталог src разбит на подкаталоги. Для того, что вы описываете, как говорили другие, вам, вероятно, лучше с a сделайте файл для каждой части, особенно если каждая часть может стоять отдельно.

вы можете добавить правила в корневой файл Makefile, чтобы скомпилировать необходимые файлы cpp в других каталогах. Пример Makefile ниже должен быть хорошим началом в получении вас туда, где вы хотите быть.

CC=g++
TARGET=cppTest
OTHERDIR=../../someotherpath/in/project/src

SOURCE = cppTest.cpp
SOURCE = $(OTHERDIR)/file.cpp

## End sources definition
INCLUDE = -I./ $(AN_INCLUDE_DIR)  
INCLUDE = -I.$(OTHERDIR)/../inc
## end more includes

VPATH=$(OTHERDIR)
OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o))) 

## Fix dependency destination to be ../.dep relative to the src dir
DEPENDS=$(join $(addsuffix ../.dep/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.d)))

## Default rule executed
all: $(TARGET)
        @true

## Clean Rule
clean:
        @-rm -f $(TARGET) $(OBJ) $(DEPENDS)


## Rule for making the actual target
$(TARGET): $(OBJ)
        @echo "============="
        @echo "Linking the target $@"
        @echo "============="
        @$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
        @echo -- Link finished --

## Generic compilation rule
%.o : %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo "Compiling $<"
        @$(CC) $(CFLAGS) -c $< -o $@


## Rules for object files from cpp files
## Object file for each file is put in obj directory
## one level up from the actual source directory.
../obj/%.o : %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo "Compiling $<"
        @$(CC) $(CFLAGS) -c $< -o $@

# Rule for "other directory"  You will need one per "other" dir
$(OTHERDIR)/../obj/%.o : %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo "Compiling $<"
        @$(CC) $(CFLAGS) -c $< -o $@

## Make dependancy rules
../.dep/%.d: %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo Building dependencies file for $*.o
        @$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > $@'

## Dependency rule for "other" directory
$(OTHERDIR)/../.dep/%.d: %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo Building dependencies file for $*.o
        @$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > $@'

## Include the dependency files
-include $(DEPENDS)

если источники распространяются во многих папках, и имеет смысл иметь отдельные файлы Makefile, то, как предлагалось ранее, рекурсивный make-хороший подход, но для небольших проектов мне проще перечислить все исходные файлы в Makefile С их относительным путем к Makefile такой:

# common sources
COMMON_SRC := ./main.cpp \
              ../src1/somefile.cpp \
              ../src1/somefile2.cpp \
              ../src2/somefile3.cpp \

затем я могу установить VPATH таким образом:

VPATH := ../src1:../src2

затем я строю объекты:

COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(ARCH)$(DEBUG).o, $(notdir $(COMMON_SRC)))
правила все просто:
# the "common" object files
$(ObjDir)/%$(ARCH)$(DEBUG).o : %.cpp Makefile
    @echo creating $@ ...
    $(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<

и построение вывода еще проще:

# This will make the cbsdk shared library
$(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS)
    @echo building output ...
    $(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)

можно сделать VPATH поколение автоматизирован:

VPATH := $(dir $(COMMON_SRC))

или используя тот факт, что sort удаляет дубликаты (хотя это не важно):

VPATH := $(sort  $(dir $(COMMON_SRC)))

Я думаю, что лучше указать, что использование Make (рекурсивное или нет) - это то, чего обычно вы можете избежать, потому что по сравнению с сегодняшними инструментами трудно учиться, поддерживать и масштабировать.

Это замечательный инструмент, но его прямое использование должно считаться устаревшим в 2010+.

Если, конечно, вы не работаете в специальной среде, т. е. с устаревшим проектом и т. д.

используйте IDE, CMake или, если вы крепко вырезаны сердцевина, то Autotools.

(отредактировано из-за downvotes, ty Honza для указания)

сообщение RC было очень полезно. Я никогда не думал об использовании функции $(dir$@), но он сделал именно то, что мне нужно было сделать.

в parentDir, есть куча каталогов с исходными файлами в них: dirA, dirB, dirC. Различные файлы зависят от объектных файлов в других каталогах, поэтому я хотел иметь возможность сделать один файл из одного каталога и заставить его сделать эту зависимость, вызвав файл makefile, связанный с этой зависимостью.

по сути, я сделал Makefile в parentDir, который имел (среди многих других вещей) общее правило, подобное RC:

%.o : %.cpp
        @mkdir -p $(dir $@)
        @echo "============="
        @echo "Compiling $<"
        @$(CC) $(CFLAGS) -c $< -o $@

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

всякий раз, когда мне нужно создать файл, я использовал (по сути) это правило рекурсивно сделать все зависимости. Отлично!

Примечание: есть утилита под названием "makepp", которая, кажется, делает эту самую задачу еще более интуитивно, но ради переносимости и не в зависимости от другого инструмента, я решил сделать это таким образом.

надеюсь, что это помогает!

рекурсивное использование Make

all:
    +$(MAKE) -C part1
    +$(MAKE) -C part2
    +$(MAKE) -C part3

Это позволяет для make разделить на задания и использовать несколько ядер

Я предлагаю использовать autotools:

//## разместить созданные объектные файлы (.o) в тот же каталог, что и их исходные файлы, чтобы избежать коллизий при использовании нерекурсивного make.

AUTOMAKE_OPTIONS = subdir-objects

просто включаю его в Makefile.am С другими довольно простыми вещами.

здесь учебник.

Comments

    Ничего не найдено.