Компиляция и связывание подпапок с использованием разных Makefile - PullRequest
0 голосов
/ 02 января 2019

У меня клиент-серверное приложение на C. На сервере есть собственная папка dserver, такая же для клиента dclient. Используя оба файла, содержащие служебные функции, я создал еще один каталог на том же уровне, что и ранее, с именем common.

Моя идея состоит в том, чтобы создать каждую Makefile в каждой подпапке (одну в dserver, одну в dclient и другую в common), а затем одну Makefile в главном каталоге, которая будет запускать другую Makefiles который выглядит так:

all:
    +$(MAKE) -C common
    +$(MAKE) -C dserver
    +$(MAKE) -C dclient

Первая проблема заключается в том, что common/Makefile не должен создавать исполняемый файл, а должен создавать только объектные файлы, которые понадобятся для создания исполняемого файла для клиента и для сервера. В моем случае это:

CXX = gcc

SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR=$(SOURCEDIR)/obj

OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))

# ADD MORE WARNINGS!
WARNING := -Wall -Wextra

$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
    $(CXX) $(WARNING) -MMD -MP -c $< -o $@

$(OBJDIR):
    mkdir -p $(OBJDIR)

Моя проблема в том, что он создает каталог объектов, заданный OBJDIR, но не объектные файлы *.o: как это должно быть?

Во-вторых, на клиенте и сервере Makefile s Я должен включить путь к файлам в common, а затем ссылаться на объектные файлы в результате компиляции common для создания исполняемых файлов. Взяв, например, dserver/Makefile, я добавил строку INC_PATH = -I../common/ и назвал ее в компиляции как $(CXX) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@. Однако в коде мне пришлось сделать #include "../common/utilities.h".

Есть ли способ включить путь в Makefile, чтобы в коде он мог просто выполнить: #include "utilities.h"?

А также, предположим, что common имеет свой собственный объектный каталог, содержащий объектные файлы, необходимые как клиенту, так и серверу, например, сборку, например, исполняемый файл сервера, ссылающийся на объектные файлы как в каталоге common, так и на другие. конкретный и содержится в каталоге server?

dserver/Makefile - это что-то вроде (и dclient/Makefile имеет такую ​​же структуру):

CXX = gcc

INC_PATH = -I../common/

SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR=./obj

OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))

# ADD MORE WARNINGS!
WARNING := -Wall -Wextra

# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean

# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: server

clean:
    $(RM) $(OBJECTS) $(DEPENDS) server

# Linking the executable from the object files
# $^   # "src.c src.h" (all prerequisites)
../server: $(OBJECTS)
    $(CXX) $(WARNING) $(INC_PATH) $^ -o $@
    #$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $@ $(LIBS)

-include $(DEPENDS)

$(OBJDIR):
    mkdir -p $(OBJDIR)

$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
    $(CXX) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@

1 Ответ

0 голосов
/ 02 января 2019

Вы не указываете никаких правил для создания объектов в своем "общем" Makefile - это единственное правило, которое у вас есть.

$(OBJDIR):
    mkdir -p $(OBJDIR)

Вы хотите поставить перед этим правило, чтобы все могли создавать объекты, может быть, что-то вроде:

all: $(OBJDIR) $(OBJECTS)

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

Включение заголовочных файлов из "common" в другие ваши каталоги должно работать нормально, используя -I../common/.

Использование объектов из «общих» должно быть просто добавлением их в список объектов, то есть:

COMMON_OBJECTS=../common/obj/utilities.o

../server: $(OBJECTS) $(COMMON_OBJECTS)

Или встроив их в библиотеку, чтобы вам не нужно было знать, какие существуют объектные файлы.

Также стоит отметить, что $(CXX) - это переменная, используемая для хранения компилятора C ++ - для сборки с компилятором C, который вы хотите использовать $(CC) и $(CFLAGS).

...