CMake Linker Error: undefined reference

Hi,

I am trying to get started with OpenCV with CMake, and have encountered what looks to be a linker error when building with CMake on visual studio code:

[main] Building folder: opencv test 
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build "c:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/build" --config Debug --target all -j 34 --
[build] [ 50%] Linking CXX executable opencvtest.exe
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\opencvtest.dir/objects.a(main.cpp.obj): in function `main':
[build] C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:8: undefined reference to `cv::Mat::Mat()'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:9: undefined reference to `cv::imread(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:9: undefined reference to `cv::Mat::operator=(cv::Mat&&)'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:9: undefined reference to `cv::Mat::~Mat()'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:15: undefined reference to `cv::namedWindow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:16: undefined reference to `cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:17: undefined reference to `cv::waitKey(int)'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:19: undefined reference to `cv::Mat::~Mat()'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:9: undefined reference to `cv::Mat::~Mat()'
[build] C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/main.cpp:19: undefined reference to `cv::Mat::~Mat()'
[build] collect2.exe: error: ld returned 1 exit status
[build] mingw32-make[2]: *** [CMakeFiles\opencvtest.dir\build.make:115: opencvtest.exe] Error 1
[build] mingw32-make[1]: *** [CMakeFiles\Makefile2:838: CMakeFiles/opencvtest.dir/all] Error 2
[build] mingw32-make: *** [Makefile:120: all] Error 2
[proc] The command: "C:\Program Files\CMake\bin\cmake.EXE" --build "c:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/build" --config Debug --target all -j 34 -- exited with code: 2
[driver] Build completed: 00:00:00.292
[build] Build finished with exit code 2

This is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.10.0)
project(opencvtest VERSION 0.1.0)

include(CTest)
enable_testing()

find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )

add_executable(opencvtest main.cpp)
target_link_libraries( opencvtest ${OpenCV_LIBS} )

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

and main program file:

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;
int main(int argc, char** argv )
{

    Mat image;
    image = imread("lenna.png");
    if ( !image.data )
    {
        printf("No image data \n");
        return -1;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE );
    imshow("Display Image", image);
    waitKey(0);
    return 0;
}

In my system environment variables for PATH, I’ve included:

C:\Program Files\CMake\bin
C:\Users\bobph\OneDrive\Desktop\Libraries\opencv\build\x64\vc16\bin
C:\Users\bobph\OneDrive\Desktop\Libraries\opencv\build\x64\vc16\lib

I’m not sure if it’s relevant, but the following paths are included in the user environmental variables for PATH instead of the system environmental variables for PATH:

C:\Users\bobph\AppData\Local\Programs\Microsoft VS Code\bin
C:\msys64\ucrt64\bin

Help would be appreciated!
Thank you

Can you printout the link map?
Maybe the libraries are in the wrong order may be you need add it couple times.
The link on ubuntu is a single pass linker

Thanks for the prompt response! What is a link map, and how do I print it out? Also, I’m on Windows.

Their is a option on the compiler/linker for the microsoft compiller
/map on the linker will generate a map file.

I’m not sure if I did this correctly, but I edited the cmake file to this to include the compiler option:

cmake_minimum_required(VERSION 3.10.0)
project(opencvtest VERSION 0.1.0)

include(CTest)
enable_testing()

find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )

add_executable(opencvtest main.cpp)
target_link_libraries( opencvtest ${OpenCV_LIBS} )
target_compile_options(opencvtest PRIVATE /map)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

After building I get this output:

[main] Building folder: opencv test 
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build "c:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/build" --config Debug --target all -j 34 --
[build] [ 50%] Building CXX object CMakeFiles/opencvtest.dir/main.cpp.obj
[build] g++.exe: warning: /map: linker input file unused because linking not done
[build] g++.exe: error: /map: linker input file not found: No such file or directory
[build] mingw32-make[2]: *** [CMakeFiles\opencvtest.dir\build.make:76: CMakeFiles/opencvtest.dir/main.cpp.obj] Error 1
[build] mingw32-make[2]: *** Deleting file 'CMakeFiles/opencvtest.dir/main.cpp.obj'
[build] mingw32-make[1]: *** [CMakeFiles\Makefile2:838: CMakeFiles/opencvtest.dir/all] Error 2
[build] mingw32-make: *** [Makefile:120: all] Error 2
[proc] The command: "C:\Program Files\CMake\bin\cmake.EXE" --build "c:/Users/bobph/OneDrive/Desktop/Projects/OpenCV Practice/opencv test/build" --config Debug --target all -j 34 -- exited with code: 2
[driver] Build completed: 00:00:04.305
[build] Build finished with exit code 2

again, if you want to use mingw, you CANNOT use the prebuilt c++ libs, those are for ** VS only**

to use mingw, you MUST build the opencv libs from src first, then use those self build libs to link your program.

we have several topics about this here, please use local search !