неопределенная ссылка на функцию opencv при компиляции с Makefile - PullRequest
0 голосов
/ 09 февраля 2019

Я хочу скомпилировать opencv4.0 с Makefile, но произошла неопределенная ошибка ссылки.
Я использовал opencv в Windows, а код - это просто простой код, который показывает только изображение для тестирования в ubuntu18.10.

но это работает, если я набрал строку ниже на оболочке.

g++ -o simple main.cpp $(pkg-config opencv4 --libs --cflags)

мой Makefile ниже

CC = g++                                                                                             
CFLAGS = -W -Wall
SRCS = main.cpp
TARGET = simple

OPENCV = $(pkg-config opencv4 --libs --cflags)
LIBS = $(OPENCV)

$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

clean:
    rm -f $(OBJECTS) $(TARGET) core

, а мой opencv4.pc ниже.

# Package Information for pkg-config                                                                 

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.0.0
Libs: -L${exec_prefix}/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_b
Libs.private: -ldl -lm -lpthread -lrt -L/usr/lib/x86_64-linux-gnu -lGL -lGLU
Cflags: -I${includedir}

и ошибка ниже.

g++ -W -Wall -o simple main.cpp 
/usr/bin/ld: /tmp/cciHsvhP.o: in function `main':
main.cpp:(.text+0x70): undefined reference to `cv::imread(cv::String const&, int)'
/usr/bin/ld: main.cpp:(.text+0xc4): undefined reference to `cv::imshow(cv::String const&, cv::_InputArray const&)'
....
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: simple] Error 1

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Я предполагаю, что вы используете GNU Make, так как вы работаете в Ubuntu Linux.

Я также предполагаю, что вы опубликовали следующее:

$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

неправильно отформатировано ви что ваш Makefile действительно содержит:

$(TARGET):$(SRCS)
    (CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

с отступом команды рецепта, как и должно быть.

В вашем Makefile вы считаете, что:

OPENCV = $(pkg-config opencv4 --libs --cflags)

это расширение оболочки команды pkg-config opencv4 --libs --cflags, которое назначает вывод команды для переменной Make OPENCV.Это не.Это просто расширение Make строки pkg-config opencv4 --libs --cflags, как и в следующей строке:

LIBS = $(OPENCV)

$(OPENCV) - это расширение Make переменной Make OPENCV, а не расширение оболочкикоманда оболочки OPENCV.

Строка pkg-config opencv4 --libs --cflags не является переменной Make, которая имеет значение (очевидно).

Также она не может быть вызовом GNU Make-функция $(pkg-config ...), так как нет такой функции GNU Make.

Так что $(pkg-config opencv4 --libs --cflags) расширяется до ничто .Следовательно:

LIBS = $(OPENCV)

заставляет $(LIBS) расширяться до нуля, а:

$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

расширяется так же, как:

$(CC) $(CFLAGS) -o $(TARGET) $(SRCS)

, поэтому opencvбиблиотеки отсутствуют в вашей связи, и эта связь завершается ошибкой.

Чтобы назначить вывод команды оболочки переменной Make, используя функцию $(shell ...) :

OPENCV := $(shell pkg-config opencv4 --libs --cflags)

Тогда $(OPENCV) и $(LIBS) получат правильное значение.

BTW ...

Обратите внимание, что ваш рецепт clean пытается удалить файл, core, который никогда не создается вашим Makefile.

И ..

Помните, что рецепт:

$(TARGET):$(SRCS)
    (CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

представляетв общем, самый неэффективный способ автоматизации процесса сборки программы с помощью Make, поскольку он будет перекомпилировать все N исходные файлы в $(SRCS) всякий раз, когда вы изменяете хотя бы 1 из них.В вашем конкретном случае, опубликованном, это не имеет значения, потому что N = 1. Но когда N = 1, в Make нет необходимости.В преддверии написания более профессиональных проектов, в которых N велик, вы можете поработать с Глава 2. Введение в Makefile , по крайней мере, в руководстве по GNU Make.

0 голосов
/ 09 февраля 2019

Эта часть вашего make-файла, вероятно, повреждена:

$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

Похоже, во второй строке отсутствует символ ведущей табуляции.

Он не используется, поэтому make используетправило по умолчанию для сборки исполняемых файлов из .cpp файлов, в котором не используется переменная LIBS (только CFLAGS).

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