Чи можу я компілювати всі .cpp-файли у src / to .o в obj /, а потім посилання на бінарні в ./?


116

Мій каталог проектів виглядає приблизно так:

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

Що я хотів би зробити з мого файлу, це скласти всі .cppфайли в /srcпапці до .oфайлів у /objпапці, а потім пов'язати всі .oфайли у /objвихідний бінарний файл у папці верхнього рівня /project.

У мене поруч немає досвіду роботи з Makefiles, і я не дуже впевнений, що шукати для цього.

Також це "хороший" спосіб зробити це чи є більш стандартний підхід до того, що я намагаюся зробити?



6
@aaa: Я здогадуюсь, що ОП хоче рішення, яке не вимагає чітко перелічити кожен вихідний файл.
Каскабель

7
Я не хочу вказувати кожен вихідний файл, який у мене є, і я намагався прочитати це посібник раніше, але мені здається, це неорганізовано і важко зрозуміти. Я дізнаюся набагато краще на фактичному прикладі, який робить те, що я очікую, і це добре пояснює, а не сухі технічні посібники.
Остін Гайд

добре. Але зробити документацію відмінно з хорошими прикладами (це не пробний технічний посібник). ви шукаєте правила шаблону: gnu.org/software/make/manual/make.html#Pattern-Rules
Anycorn

11
Це трохи більше схоже на те, що я хочу. Хоча, IMHO, посібник з виробництва трохи сухий, оскільки видається більш орієнтованим на розробників, які перебувають на проміжному рівні з make, а за його межами - дуже великим і глибоким. Можливо, занадто багато.
Остін Гайд

Відповіді:


180

Makefile частина питання

Це досить просто, якщо вам не потрібно узагальнювати спробувати щось на зразок коду нижче (але замініть відступ місця на вкладки поблизу g ++)

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

Автоматична генерація графіка залежності

Функція "must" для більшості систем make. За допомогою GCC в можна зробити за один прохід як побічний ефект компіляції, додавши -MMDпрапор до CXXFLAGSта -include $(OBJ_FILES:.o=.d) в кінці тіла makefile:

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

І як хлопці вже згадували, завжди майте посібник із створення GNU , це дуже корисно.


11
Ах, ти мене секунди бив. Але я пропоную OBJ_FILES = $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES)).
Бета

1
Мені довелося змінити це, щоб воно працювало: $<повинно бути $^за правилом main.exe, і я думаю, що є помилка друку obj/%.o: src/%cpp.

1
@bobah Вам не вистачає знака "." у ваших об'єктах правило для cpp
regomodo

1
спеціальні змінні, ймовірно, варто пояснити, оскільки вони є специфічними для makefile і їх важко шукати: gnu.org/software/make/manual/html_node/Automatic-Variables.html
Blake

2
Я знаю, що це старе питання, але я трохи змінив, відповідно до свого проекту, але він не працює. Ось мій makefile: pastebin.com/4CksG9Wc Я отримую в консолі:make: *** No rule to make target '/main.o', needed by 'bin/main'. Pare.
Mateus Felipe

5

Підстановка також працює для мене, але я хотів би дати додаткову примітку для тих, хто використовує змінні каталогів. Завжди використовуйте косу рису для дерева папок (не зворотну косу рису), інакше вона не вдасться:

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)

ти мав на увазі нахил вперед? Ваш приклад показує, що традиційно вважається косою косою рискою. Зокрема, ті, хто "схиляється праворуч", вважаються "вперед", а ліві вважаються "назад"
Еван Теран

Так, ви маєте рацію, я маю на увазі лише "косою". Я оновив публікацію.
xesf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.