Сокращение команды сборки

Есть ли способ сократить эту команду openCV build?

g++ file.cpp -o newFileName `pkg-config --cflags --libs opencv` 

Я попытался добавить:

 -o newFileName `pkg-config --cflags --libs opencv` 

к псевдониму, но он просто продолжает возвращать команду не найден, есть ли другой способ сократить эту команду?

РЕДАКТИРОВАТЬ:

В соответствии с приведенными ниже предложениями я создал makefile со следующим содержимым:

 OPENCV='pkg-config --cflags --libs opencv' %: %.cpp $(CXX) -o $* $*.cpp $(OPENCV) 

но когда я запускаю make surfPoints я получаю следующий вывод (файл строит отлично, когда команда запускается вручную):

 $ make surfPoints g++ -o surfPoints surfPoints.cpp /tmp/ccxxAU92.o: In function `main': surfPoints.cpp:(.text+0x81): undefined reference to `cv::imread(std::string const&, int)' surfPoints.cpp:(.text+0xf3): undefined reference to `cv::imread(std::string const&, int)' surfPoints.cpp:(.text+0x17f): undefined reference to `cv::SURF::SURF(double, int, int, bool, bool)' surfPoints.cpp:(.text+0x1d0): undefined reference to `cv::FeatureDetector::detect(cv::Mat const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&, cv::Mat const&) const' surfPoints.cpp:(.text+0x212): undefined reference to `cv::FeatureDetector::detect(cv::Mat const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&, cv::Mat const&) const' surfPoints.cpp:(.text+0x280): undefined reference to `cv::drawKeypoints(cv::Mat const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> > const&, cv::Mat&, cv::Scalar_<double> const&, int)' surfPoints.cpp:(.text+0x2c1): undefined reference to `cv::drawKeypoints(cv::Mat const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> > const&, cv::Mat&, cv::Scalar_<double> const&, int)' surfPoints.cpp:(.text+0x2d7): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)' surfPoints.cpp:(.text+0x30b): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)' surfPoints.cpp:(.text+0x339): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)' surfPoints.cpp:(.text+0x36d): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)' surfPoints.cpp:(.text+0x38f): undefined reference to `cv::waitKey(int)' /tmp/ccxxAU92.o: In function `cv::Mat::~Mat()': surfPoints.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)' /tmp/ccxxAU92.o: In function `cv::Mat::release()': surfPoints.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x47): undefined reference to `cv::Mat::deallocate()' /tmp/ccxxAU92.o: In function `cv::Feature2D::~Feature2D()': surfPoints.cpp:(.text._ZN2cv9Feature2DD2Ev[_ZN2cv9Feature2DD2Ev]+0x69): undefined reference to `cv::DescriptorExtractor::~DescriptorExtractor()' surfPoints.cpp:(.text._ZN2cv9Feature2DD2Ev[_ZN2cv9Feature2DD2Ev]+0x80): undefined reference to `cv::FeatureDetector::~FeatureDetector()' surfPoints.cpp:(.text._ZN2cv9Feature2DD2Ev[_ZN2cv9Feature2DD2Ev]+0x98): undefined reference to `cv::Algorithm::~Algorithm()' surfPoints.cpp:(.text._ZN2cv9Feature2DD2Ev[_ZN2cv9Feature2DD2Ev]+0xcc): undefined reference to `cv::FeatureDetector::~FeatureDetector()' surfPoints.cpp:(.text._ZN2cv9Feature2DD2Ev[_ZN2cv9Feature2DD2Ev]+0xe9): undefined reference to `cv::Algorithm::~Algorithm()' /tmp/ccxxAU92.o: In function `cv::SURF::~SURF()': surfPoints.cpp:(.text._ZN2cv4SURFD1Ev[_ZN2cv4SURFD1Ev]+0xe): undefined reference to `vtable for cv::SURF' surfPoints.cpp:(.text._ZN2cv4SURFD1Ev[_ZN2cv4SURFD1Ev]+0x26): undefined reference to `vtable for cv::SURF' surfPoints.cpp:(.text._ZN2cv4SURFD1Ev[_ZN2cv4SURFD1Ev]+0x2e): undefined reference to `vtable for cv::SURF' surfPoints.cpp:(.text._ZN2cv4SURFD1Ev[_ZN2cv4SURFD1Ev]+0x3b): undefined reference to `VTT for cv::SURF' surfPoints.cpp:(.text._ZN2cv4SURFD1Ev[_ZN2cv4SURFD1Ev]+0x62): undefined reference to `cv::Algorithm::~Algorithm()' surfPoints.cpp:(.text._ZN2cv4SURFD1Ev[_ZN2cv4SURFD1Ev]+0x97): undefined reference to `cv::Algorithm::~Algorithm()' collect2: error: ld returned 1 exit status make: *** [surfPoints] Error 1 

3 Solutions collect form web for “Сокращение команды сборки”

make – это инструмент, который вам нужен. Вам просто нужно ввести make с Makefile на место, и ваш файл будет создан.

Вот простой Makefile, который будет генерировать файл newFileName соответствии с строкой, которую вы отправили в вопросе:

 MYFLAGS=$(shell pkg-config --cflags --libs opencv) newFileName: file.cpp $(CXX) $< -o $@ $(MYFLAGS) 

Если вы поместите это в свою кодовую директорию, просто введите make и ваш код будет создан.

Краткое объяснение:

  • make будет искать Makefile в каталоге;
  • Поскольку файл есть, make выполнит первое правило: newFileName и выполнит его;
  • Этот синтаксис правила следующий:
    • newFileName: задает имя правила или цели, предпочтительно имя файла, который будет генерировать правило;
    • Все после : являются предпосылками, другими словами, файлами, которые будут необходимы для выполнения рецепта этого правила или правил, которые должны быть выполнены раньше;
    • Строка (строки) ниже – рецепт (обратите внимание на или 4 пробела в начале строки), они рассказывают, как создать файл newFileName .
  • $(CXX) будет расширяться до вашего компилятора C ++ по умолчанию, а MYFLAGS будет расширяться до вывода pkg-config --cflags --libs opencv .

Бонус: Make выполнит рецепт правила только в том случае, если предварительные условия были изменены после создания метки времени для цели, поэтому, если вы наберете make и у вас уже есть новый файл newFileName, вы не потеряете время, перекомпилируете что-то, что вы уже есть. Это особенно приятно, когда у вас много файлов.

Чем раньше вы научитесь использовать, тем лучше. Создайте makefile в том же каталоге, что и file.cppfile.cpp требует использования фактической вкладки для отступа. Если вы используете пробелы, вы получите сообщение об ошибке «missing separator»:

 OPENCV=`pkg-config --cflags --libs opencv` newFileName: file.cpp $(CXX) -o newFileName file.cpp $(OPENCV) 

Для сборки просто запустите make в этом каталоге. Это проверит правило для первой цели в make-файле. В этом случае есть только одна цель newFileName . Поскольку file.cpp является предварительным условием , если файл с целевым именем не существует или существует, но время модификации предварительного условия более новое (т. file.cpp Вы изменили file.cpp с newFileName последнего file.cpp newFileName ), рецепт будет быть казненным.

Чтобы убедиться, что в вашей системе определен параметр $(CXX) , запустите make -p | grep CXX make -p | grep CXX в каталоге с NO makefile . Результат должен включать CXX = g++ .


Если вы добавите другую цель, например:

 otherFile: file2.cpp $(CXX) -o otherFile file2.cpp $(OPENCV) 

Вы можете выполнить это правило, используя целевое имя, make otherFile . Опять же, если цель не указана, используется первая в make-файле.

Поскольку эти две цели соответствуют одинаковому шаблону, если вы использовали исполняемые имена, совпадающие с именами исходных файлов, вы можете сделать это:

 %: %.cpp $(CXX) -o $* $*.cpp $(OPENCV) 

Теперь make whatever , make whatever будет

 g++ -o whatever whatever.cpp `pkg-config --cflags --libs opencv` 

См. « Сравнение шаблонов» и « Автоматические переменные» для объяснения того, как это работает.


Make становится особенно полезным, когда вы начинаете делать более сложные вещи – компилируете объекты ( .o ) и объединяете их в исполняемые файлы и т. Д. В конце концов вам придется научиться использовать какую-то систему сборки, и make ее наиболее распространенной в мир * nix.

У вас есть 3 варианта укорачивания вещей в типичной оболочке, такой как Bash.

  1. Сделать сценарий оболочки
  2. Сделать псевдоним
  3. Сделать функцию

Я покажу вам 2 и 3.

псевдоним

Вы могли бы сделать что-то вроде этого как псевдоним.

 $ alias mygcc='g++ file.cpp -o newFileName $(pkg-config --cflags --libs opencv)' 

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

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

 $ alias myalias='ls -l' $ myalias -d drwxrwxr-x. 2 saml saml 4096 Jan 24 11:19 . $ myalias file1 -rw-rw-r--. 1 saml saml 0 Jan 24 11:19 file1 

Поэтому, когда мы запускаем myalias мы можем дать ему имена файлов или другие ключи, и это работает.

функция

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

 $ mygcc () { g++ file.cpp -o newFileName $(pkg-config --cflags --libs opencv); } 

Выходите за пределы?

Если вам нужно больше, чем просто простой лайнер, я настоятельно рекомендую вам изучить подходящий инструмент, такой как Make, CMake или любое из множества инструментов построения зависимостей.

  • Автоматизация производства
  • Список программного обеспечения для автоматизации сборки

Выбор инструмента построения должен быть дискуссией, которую вы и ваша команда, хотя и не просто уходите и выбираете что-то. Выбор должен быть сделан таким образом, чтобы соответствующий инструмент для вашей команды и технологий использовался для создания вашего приложения (ов).

  • как сделать переменную PKG_CONFIG_PATH ссылкой на установленную библиотеку?
  • что-то ужасно неправильно с pkg-config
  • Gentoo: пакет `glib-2.0` не найден
  • Как узнать, доступна ли команда в моем дистрибутиве Linux
  • Должен ли я установить ibus-1.0 для создания Webdriver?
  • Флаги pkg-config являются относительными
  • "Configure: error: Требования к пакету (blkid) не выполнялись"
  • Как бороться с переходом FreeBSD на pkgconf?
  • Linux и Unix - лучшая ОС в мире.