Как скомпилировать исходные объекты в другой каталог, а затем собрать исполняемый файл? - PullRequest
0 голосов
/ 12 мая 2019

Добрый день. Я нахожусь в каталоге, где находится Makefile и папки src и bin. Как я могу скомпилировать объектные файлы в папку bin, а затем создать исполняемый файл?

Я прочитал некоторые инструкции и добавил $ (BIN) перед% .o, но это не помогло, объектные файлы появляются в папке с makefile. Где проблема?

CC = arm-linux-gnueabihf-gcc
CXX = arm-linux-gnueabihf-g++
CPPFLAGS = -I .
CFLAGS =-g -std=gnu99 -O1 -Wall
CXXFLAGS = -g -std=gnu++11 -O1 -Wall
LDFLAGS = -lrt -lpthread
SRCDIR = src
BIN = bin
SOURCES = $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.c)*
...
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
#$(warning OBJECTS=$(OBJECTS))
ifeq ($(filter %.cpp,$(SOURCES)),)
LINKER = $(CC)
LDFLAGS += $(CFLAGS) $(CPPFLAGS)
else
LINKER = $(CXX)
LDFLAGS += $(CXXFLAGS) $(CPPFLAGS)
endif
$(BIN)/%.o:%.c
    $(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
    $(CXX) $(CXXFLAGS) -c $<
all: $(TARGET_EXE)
$(TARGET_EXE): $(OBJECTS)
    $(LINKER) $(LDFLAGS) -L. $^ -o $@
.PHONY : dep all run copy-executable debug
dep: depend
depend: $(SOURCES) *.h
    echo '# autogenerat`enter code here`ed dependencies' > depend
ifneq ($(filter %.c,$(SOURCES)),)
    $(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
      >> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
      >> depend
endif
clean:
    rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) connect.gdb depend
...

1 Ответ

0 голосов
/ 12 мая 2019

Мне не ясно, как этот make-файл может работать так же, как и он, учитывая, что вы не сказали ему, где найти исходные файлы (если вы не сделали этого в одном из разделов elised).

В этих правилах:

$(BIN)/%.o:%.c
    $(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
    $(CXX) $(CXXFLAGS) -c $<

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

$(BIN)/%.o:%.c
    $(CC) $(CFLAGS) -c $< -o $@
$(BIN)/%.o:%.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

Как только у вас есть объектные файлы, где вы хотите их (bin/), вы должны убедиться, что правило связывания:

$(TARGET_EXE):$(OBJECTS)
    $(LINKER) $(LDFLAGS) -L. $^ -o $@

может найти их. Лучший способ сделать это - убедиться, что OBJECTS содержит правильные пути к объектным файлам. Я не уверен, как вам посоветовать это сделать, поскольку, судя по вашему make-файлу, эта переменная может не содержать того, что вы думаете.

EDIT:

Давайте рассмотрим это поэтапно. Предположим, у нас есть исходный файл, src/foo.c. То, что мы хотим, это:

src/foo.c -> bin/foo.o
bin/foo.o   -> foo

Это требует двух правил, которые мы можем написать так:

$(BIN)/%.o: src/%.c
    $(CC) $(CFLAGS) -c $< -o $@

$(TARGET_EXE): bin/foo.o
    $(LINKER) $(LDFLAGS) -L. $^ -o $@

На самом деле у нас много исходных файлов, некоторые из которых являются файлами C ++. Поэтому у нас должно быть правило для них:

$(BIN)/%.o: src/%.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

и составьте более длинный список объектов:

OBJECTS := bin/foo.o bin/bar.o bin/baz.o bin/quartz.o...
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $@

(Смешивание C и C ++ мне кажется вредным, но не берите в голову.)

А как нам построить этот список объектов? Мы должны начать со списка источников, которые wildcard может произвести:

SRC := src
C_SOURCES := $(wildcard $(SRC/*.c)
# this is src/foo.c src/bar.c

SRC := src
CPP_SOURCES := $(wildcard $(SRC/*.cpp)
# this is src/baz.cpp src/quartz.cpp

и затем преобразовать их в имена файлов объектов, которые мы на самом деле хотим:

BIN := bin
OBJECTS := $(patsubst $(SRC)/%.cpp,$(BIN)/%.o, $(CPP_SOURCES))
OBJECTS += $(patsubst $(SRC)/%.c,$(BIN)/%.o, $(C_SOURCES))
# this is bin/foo.o bin/bar.o bin/baz.o bin/quartz.o

Это должно дать вам желаемый эффект, и если вы поймете его, вы поймете, почему ваш старый make-файл этого не сделал.

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