Каковы преимущества использования make для небольших проектов?

Замена процесса >(thing)будет заменена именем файла. Это имя файла соответствует файлу, который подключен к стандартному входу thingвнутри подстановки.

Следующий пример будет лучшим примером его использования:

$ sort -o >(cat -n >/tmp/out) ~/.profile

Это отсортирует файл ~/.profileи отправит вывод в cat -n, который пронумерует строки и сохранит результат в /tmp/out.

Итак, чтобы ответить на ваш вопрос :Вы получаете этот вывод, потому что echoполучает два аргумента 123и /dev/fd/63. /dev/fd/63— это файл, подключенный к стандартному входу процесса catв замене процесса.

Немного изменив код вашего примера:

$ echo 101 > >(cat)

Это выведет только 101на стандартный вывод (вывод echoбудет перенаправлен в файл, который служит входом для cat, а catвыдаст содержимое этого файла на стандартный вывод ).


Также обратите внимание, что в конвейере cmd1 | cmd2cmd2может вообще не работать в той же оболочке, что и cmd1(, в зависимости от используемой вами реализации оболочки ). ksh93работает так, как вы описываете (ту же оболочку ), в то время как bashсоздает подоболочку для cmd2(, если не установлен параметр оболочки lastpipeи управление заданиями не активно ).

8
03.03.2019, 01:33
6 ответов

В отличие от чего?

Предположим, у вас есть программа, которую вы разделили на два файла. которые вы образно назвали file1.cи  file2.c. Вы можете скомпилировать программу, запустив

cc file1.c file2.c -o yourprogram

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

cc -c file1.c
cc -c file2.c
cc    file1.o file2.o -o yourprogram

а затем, когда вы редактируете один из файлов, перекомпилируйте только этот файл (и выполните шаг связывания независимо от того, что вы изменили ). Но что, если вы отредактируете один файл, , а затем другой, и вы забываете, что редактировали оба файла, а случайно перекомпилировать только один?

Кроме того, даже для двух файлов у вас есть около 60 символов команд. Набирать текст быстро становится утомительно. Хорошо, конечно, вы можете поместить их в сценарий, но потом вы каждый раз возвращаетесь к перекомпиляции. Или вы можете написать действительно причудливый, сложный скрипт, который проверяет какой файл (с )был изменен и делает только необходимые компиляции. Вы понимаете, к чему я клоню?

11
27.01.2020, 20:08

Даже в небольшом проекте может быть полезно контролировать логику зависимостей и автоматизировать сборку. Я также использовал его для запуска установок и деинсталляций, так что это был главный переключатель, сбрасывающий сцену.

5
27.01.2020, 20:08

Если вы связываете свое приложение из 2 исходных файлов(.c), вам не нужно перекомпилировать каждый файл, а только измененный, если вы используете make.

Также приведу пример из мира BSD. У них есть структура Makefiles на основе системы -. Они предоставляют вам пути к системным каталогам и имеют цели для установки вашего программного обеспечения и справочных страниц.

Например, вы только что написали beer.cприложение и руководство к нему под названием beer.6. Вы создаетеMakefile:

PROG=   beer
MAN=    beer.6

.include <bsd.prog.mk>

..и позвоните make install. Он автоматически компилирует и устанавливает ваше приложение в /usr/bin, а также компилирует и устанавливает вашу справочную страницу в то место, где manможет ее найти. Вы только что установили свое приложение с помощью одной простой команды!

Очень удобно и абсолютно прозрачно для всех, кто знаком с BSD. Гораздо лучше, чем ручной скрипт.

3
27.01.2020, 20:08

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

Я не хочу ничего вспоминать.

Даже если ваш проект действительно скучный и простой, и вы не используете make-файлы «правильно»:

all:
    gcc main.c -o project

Мне не нужно думать об этом или относиться к нему иначе, чем к более сложному проекту:

all:
    gcc libA.c libB.c main.c -o project2

Или, если я указал флаги (, например.-O2)Мне не нужно помнить, что они были.

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

15
27.01.2020, 20:08

makeдовольно надежно доступен. Если вы распространяете свой проект с makefile, пользователи будут иметь простую справку о том, как выполнять задачи так же, как и вы. makefileможет использоваться не только для компиляции.

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

0
27.01.2020, 20:08

Пример Makefileдля моего очень маленького проекта:getPixelColor

Он делает именно то, что говорит его название, принимая два необязательных аргумента — координаты.

Мне особенно нравится, как там все становится зависимым.

COORDS ?= 0 0

CXX := g++-8
CXXFLAGS := -std=c++17 -Wall -Wextra -Werror -Wpedantic -pedantic-errors
LDLIBS := -lX11
RM := rm -f

BIN := getPixelColor
SRC := $(BIN).cpp

$(BIN): $(SRC)
    $(CXX) $(CXXFLAGS) $(SRC) -o $(BIN) $(LDLIBS)

.PHONY: clean
clean:
    $(RM) $(BIN)

.PHONY: run
run: $(BIN)
   ./$(BIN) $(COORDS)

Как видите, он может делать все, что вам нужно, не вводя ничего лишнего:


Использование

Вы можете запустить это так:

  1. Очистить -старый бинарный файл:

    make clean
    
  2. Скомпилируйте новый бинарник:

    make
    
  3. Запустите исполняемый файл двумя способами:

    • координаты по умолчанию [0,0]

      make run     # equals COORDS='0 0'
      
    • любые заданные координаты

      COORDS='5 6' make run
      

Makefiles иногда могут быть чрезвычайно полезны. Чем больше проект, тем больше выгода. Но даже с этим мой самый маленький проект на C++, как вы можете видеть на примерах, избавляет вас от многих головных болей.

1
27.01.2020, 20:08

Теги

Похожие вопросы