минимальный файл сборки c++ для linux

Я ищу простой рекомендуемый «минимальный» make-файл С++ для Linux, который будет использовать g++ для компиляции и связывания одного файла и h-файла. В идеале make-файл не будет содержать даже имен физических файлов, а будет иметь только преобразование .cpp в .o. Как лучше всего сгенерировать такой make-файл, не погружаясь в ужасы autoconf?

Текущий каталог содержит, например

t.cpp t.h

и я хочу создать make-файл для этого. Я попробовал autoconf, но предположил, что .h — это gcc, а не g++. Да, хотя я и не новичок, я заново изучаю лучшие подходы к управлению проектами многолетней давности и, следовательно, ищу автоматизированные способы создания и поддержки make-файлов для небольших проектов.


person RichieHH    schedule 13.11.2008    source источник
comment
Make отлично подходит для простых проектов (и для игры). Но поддерживать большой проект становится трудно правильно (вы можете легко схитрить, но правильно трудно). Используйте такие инструменты, как scons, для создания make-файла.   -  person Martin York    schedule 13.11.2008
comment
сконы красиво смотрятся. Конечно проще, чем Autoconf.   -  person RichieHH    schedule 14.11.2008
comment
OMake великолепен и берет верх, когда make показывает свои пределы.   -  person bltxd    schedule 14.11.2008


Ответы (11)


Если это один файл, вы можете ввести

make t

И он будет вызывать

g++ t.cpp -o t

Для этого даже не требуется Makefile в каталоге, хотя он запутается, если у вас есть t.cpp, t.c, t.java и т. д. и т. д.

Также настоящий Makefile:

SOURCES := t.cpp
# Objs are all the sources, with .cpp replaced by .o
OBJS := $(SOURCES:.cpp=.o)

all: t

# Compile the binary 't' by calling the compiler with cflags, lflags, and any libs (if defined) and the list of objects.
t: $(OBJS)
    $(CC) $(CFLAGS) -o t $(OBJS) $(LFLAGS) $(LIBS)

# Get a .o from a .cpp by calling compiler with cflags and includes (if defined)
.cpp.o:
    $(CC) $(CFLAGS) $(INCLUDES) -c $<
person hazzen    schedule 13.11.2008
comment
это также не создает никаких зависимостей. - person David Nehme; 13.11.2008
comment
Этот make-файл почти (но не совсем) эквивалентен всем : t и позволяет встроенным правилам действовать... - person Steve Jessop; 14.11.2008
comment
Но почему у вас есть особое правило для t: ? Это как бы противоречит правилу cpp.o. - person RichieHH; 14.11.2008
comment
Правило t создает из файлов .o двоичный файл, вызывая компоновщик. Если бы у меня было четыре источника [abcd].cpp и двоичный файл с именем t, правило связало бы все четыре сгенерированных объекта в один исполняемый файл. - person hazzen; 14.11.2008
comment
Вы должны использовать CXX и CXXFLAGS для файлов C++, а не CC и CFLAGS. Источник: неявные переменные GNU make. Обратите внимание, что CPPFLAGS относятся к препроцессору C, который применяется как к C, так и к C++. - person Daniel Stevens; 26.11.2018

Вот общий make-файл из моего каталога фрагментов кода:

SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)
BINS=$(SOURCES:.cpp=)

CFLAGS+=-MMD
CXXFLAGS+=-MMD

all: $(BINS)

.PHONY: clean

clean:
    $(RM) $(OBJECTS) $(DEPS) $(BINS)

-include $(DEPS)

Пока у вас есть один источник .cpp, создающий один двоичный файл, вам больше ничего не нужно. Я использовал его только с GNU make, а при генерации зависимостей используется синтаксис gcc (также поддерживаемый icc). Если вы используете компиляторы SUN, вам нужно изменить "-MMD" на "-xMMD". Кроме того, убедитесь, что табуляция в начале строки после clean: не заменяется пробелами, когда вы вставляете этот код, иначе make выдаст ошибку отсутствия разделителя.

person florin    schedule 13.11.2008
comment
all тоже должно быть phony . - person shuva; 15.03.2018
comment
Согласованный. Документация GNU Make показывает, что all указан как .PHONY. Источник: Фальшивые цели - person Daniel Stevens; 26.11.2018

Вы просматривали SCons?

Просто создайте файл SConstruct со следующим:

Program("t.cpp")

Затем введите:

scons

Сделанный!

person grieve    schedule 13.11.2008
comment
Хотя я люблю возиться с makefile (это отдельный язык). Я думаю, что это лучший ответ, но я думаю, вам нужно немного расширить этот ответ, чтобы объяснить, почему использование SCons лучше, чем непосредственное использование Makefiles. Я убежден, но этого недостаточно, чтобы убедить других. - person Martin York; 13.11.2008

Предполагая, что нет предварительно настроенных общесистемных параметров make:

CXX = g++
CPPFLAGS =        # put pre-processor settings (-I, -D, etc) here
CXXFLAGS = -Wall  # put compiler settings here
LDFLAGS =         # put linker settings here

test: test.o
    $(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) test.o

.cpp.o:
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<

test.cpp: test.h
person Alnitak    schedule 13.11.2008
comment
Опять же это его конкретная ветка для теста. Почему? - person RichieHH; 14.11.2008
comment
потому что вы всегда должны указывать, что будет на самом деле строить Makefile. С подходящим глобальным определением вы можете просто сказать test: в файле, но указанный выше файл гарантированно будет работать независимо от каких-либо глобальных правил или макросов. - person Alnitak; 14.11.2008

довольно небольшой Makefile GNU, использующий предопределенные правила и авто-депозиты:

CC=c++
CXXFLAGS=-g -Wall -Wextra -MMD
LDLIBS=-lm
program: program.o sub.o
clean:
    $(RM) *.o *.d program
-include $(wildcard *.d)
person Sam Watkins    schedule 31.01.2015

Вы смотрели OMake?

OMakeroot

open build/C
DefineCommandVars()
.SUBDIRS: .

OMakefile

.DEFAULT: $(CXXProgram test, test)

Затем в Linux или Windows просто введите:

omake

В качестве бонуса вы автоматически получаете:

  • параллельные сборки с параметром -j (аналогично make).
  • Контрольные суммы MD5 вместо меток времени (сборка становится устойчивой к сбоям синхронизации времени).
  • Автоматические и точные зависимости заголовков C/C++.
  • Точные межкаталоговые зависимости (чего не предлагает рекурсивная make).
  • Портативность (1 цепочка сборки, чтобы управлять ими всеми, невосприимчивость к проблемам со стилем пути).
  • Настоящий язык программирования (лучше, чем GNU make).
person bltxd    schedule 14.11.2008
comment
Если бы OMake лучше поддерживал сборки вне исходного кода и мог генерировать проект Visual Studio, он был бы очень близок к идеалу. - person JesperE; 14.11.2008
comment
Здесь мы делаем сборки вне исходного кода с помощью OMake. Есть несколько вещей, которые нужно знать, но в остальном это работает (0.9.8.5). - person bltxd; 18.11.2008

Несколько хороших ссылок по созданию базового Makefile

http://en.wikipedia.org/wiki/Make_(программноеобеспечение)

http://mrbook.org/tutorials/make/

http://www.opussoftware.com/tutorial/TutMakefile.htm

http://www.hsrl.rutgers.edu/ug/make_help.html

Первая пара, в частности, имеет минимальный пример Makefile, как вы описали. Надеюсь, это поможет.

person Jay    schedule 13.11.2008

SConstruct с опцией отладки:

env = Environment()

if ARGUMENTS.get('debug', 0):
    env.Append(CCFLAGS = ' -g')

env.Program( source = "template.cpp" )
person RichieHH    schedule 14.11.2008

Флорин имеет хорошую отправную точку. Мне не нравился gnu autoconf, поэтому я начал с него, развил эту концепцию и назвал ее MagicMakefile. У меня есть 3 варианта от простого к более сложному. Последняя версия уже доступна на github: https://github.com/jdkoftinoff/magicmake.

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

[править] На данный момент я использую cmake для всех своих проектов, так как он генерирует полезные файлы проекта для многих систем сборки.

Джефф Кофтинофф

person jdkoftinoff    schedule 14.11.2008
comment
Ой! Извините за битые ссылки. Я переместил его на гитхаб. github.com/jdkoftinoff/magicmake - при этом вместо этого я использую CMake. - person jdkoftinoff; 01.02.2015

Я искал, как может выглядеть минимальный Makefile, кроме

some_stuff:
    @echo "Hello World"

Я знаю, что опаздываю на эту вечеринку, но я тоже решил бросить свою шляпу на ринг. Ниже приведен мой единственный проект каталога Makefile, который я использовал в течение многих лет. С небольшой модификацией он масштабируется для использования нескольких каталогов (например, src, obj, bin, header, test и т. д.). Предполагается, что все заголовки и исходные файлы находятся в текущем каталоге. И нужно дать проекту имя, которое используется для выходного двоичного имени.

NAME = my_project

FILES = $(shell basename -a $$(ls *.cpp) | sed 's/\.cpp//g')
SRC = $(patsubst %, %.cpp, $(FILES))
OBJ = $(patsubst %, %.o, $(FILES))
HDR = $(patsubst %, -include %.h, $(FILES))
CXX = g++ -Wall

%.o : %.cpp
        $(CXX) $(HDR) -c -o $@ $<

build: $(OBJ)
        $(CXX) -o $(NAME) $(OBJ)

clean:
        rm -vf $(NAME) $(OBJ)
person Bob Smith    schedule 27.01.2018

Если ваши проблемы связаны с тем, что autoconf считает файл .h файлом c, попробуйте переименовать его в .hpp или .h++.

person Adam Tegen    schedule 13.11.2008