How to fix "ld: symbol(s) not found for architecture x86_64" using C++, CMake and Tensorflow? - c++

I created a test project in C ++ using TensorFlow with CMake. But I have an error:
ld: symbol(s) not found for architecture x86_64
I think, I have an error in my CMake files. When I try compile via the terminal with gcc tensortest.cpp -ltensorflow -o tf, everything works fine.
I have two CMake files.
FindTensorFlow.cmake:
# Locates the tensorFlow library and include directories.
include(FindPackageHandleStandardArgs)
unset(TENSORFLOW_FOUND)
find_path(TensorFlow_INCLUDE_DIR
NAMES
tensorflow
HINTS
/usr/local/include/tensorflow)
find_library(TensorFlow_LIBRARY
NAMES
libtensorflow_framework.1.14.0.dylib
libtensorflow_framework.1.dylib
libtensorflow_framework.dylib
libtensorflow.1.14.0.dylib
libtensorflow.1.dylib
libtensorflow.dylib
HINTS
/usr/local/lib)
# set TensorFlow_FOUND
find_package_handle_standard_args(TensorFlow DEFAULT_MSG TensorFlow_INCLUDE_DIR TensorFlow_LIBRARY)
# set external variables for usage in CMakeLists.txt
if(TENSORFLOW_FOUND)
set(TensorFlow_LIBRARIES ${TensorFlow_LIBRARY})
set(TensorFlow_INCLUDE_DIRS ${TensorFlow_INCLUDE_DIR})
endif()
# hide locals from GUI
mark_as_advanced(TensorFlow_INCLUDE_DIR TensorFlow_LIBRARY)
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(TensorFlowTest)
set(CMAKE_CXX_STANDARD 14)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
find_package(TensorFlow REQUIRED)
include_directories(${TensorFlow_INCLUDE_DIRS} ${TensorFlow_LIBRARIES})
add_executable(TensorFlowTest main.cpp)
target_link_libraries(TensorFlowTest ${TensorFlow_INCLUDE_DIRS} ${TensorFlow_LIBRARIES})
And one main.cpp
#include <stdio.h>
#include <tensorflow/c/c_api.h>
int main() {
printf("Hello from TensorFlow C library version %s\n", TF_Version());
return 0;
}
When reload project, I have a CMake message:
-- Found TensorFlow: /usr/local/include
-- Configuring done
WARNING: Target "TensorFlowTest" requests linking to directory "/usr/local/include". Targets may link only to libraries. CMake is dropping the item.
-- Generating done
-- Build files have been written to: /Users/neikr/CLionProjects/TensorFlowTest/cmake-build-debug
And when compiling:
Scanning dependencies of target TensorFlowTest
[ 50%] Building CXX object CMakeFiles/TensorFlowTest.dir/main.cpp.o
[100%] Linking CXX executable TensorFlowTest
Undefined symbols for architecture x86_64:
"_TF_Version", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [TensorFlowTest] Error 1
make[2]: *** [CMakeFiles/TensorFlowTest.dir/all] Error 2
make[1]: *** [CMakeFiles/TensorFlowTest.dir/rule] Error 2
make: *** [TensorFlowTest] Error 2
Update
I tried make with VERBOSE=1 and I get this output:
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -S/Users/neikr/CLionProjects/TensorFlowTest -B/Users/neikr/CLionProjects/TensorFlowTest --check-build-system CMakeFiles/Makefile.cmake 0
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_progress_start /Users/neikr/CLionProjects/TensorFlowTest/CMakeFiles /Users/neikr/CLionProjects/TensorFlowTest/CMakeFiles/progress.marks
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/Makefile2 all
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/TensorFlowTest.dir/build.make CMakeFiles/TensorFlowTest.dir/depend
cd /Users/neikr/CLionProjects/TensorFlowTest && /Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_depends "Unix Makefiles" /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest/CMakeFiles/TensorFlowTest.dir/DependInfo.cmake --color=
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/TensorFlowTest.dir/build.make CMakeFiles/TensorFlowTest.dir/build
[ 50%] Linking CXX executable TensorFlowTest
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_link_script CMakeFiles/TensorFlowTest.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/TensorFlowTest.dir/main.cpp.o -o TensorFlowTest -Wl,-rpath,/usr/local/lib /usr/local/lib/libtensorflow_framework.1.14.0.dylib
Undefined symbols for architecture x86_64:
"_TF_Version", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [TensorFlowTest] Error 1
make[1]: *** [CMakeFiles/TensorFlowTest.dir/all] Error 2
make: *** [all] Error 2
Also, I tried adding message("TensorFlow_LIBRARIES: ${TensorFlow_LIBRARIES}") to the end of my CMake and I get this message:
TensorFlow_LIBRARIES: /usr/local/lib/libtensorflow_framework.1.14.0.dylib

Based on your print-out from the message() command, it is more clear what is going on. In your FindTensorFlow.cmake file, the find_library() call only finds one library (libtensorflow_framework.1.14.0.dylib), which is expected behavior:
Once one of the calls succeeds the result variable will be set and stored in the cache so that no call will search again.
When more than one value is given to the NAMES option this command by default will consider one name at a time and search every directory for it.
Thus, once find_library() finds the libtensorflow_framework library, the search stops. If you want to also find libtensorflow.dylib, which may help with your link error, you have to specify another find_library() call, using a different TensorFlow_ variable. So changing that section of your FindTensorFlow.cmake to something like this should help:
find_library(TensorFlow_LIBRARY
NAMES
libtensorflow.1.14.0.dylib
libtensorflow.1.dylib
libtensorflow.dylib
HINTS
/usr/local/lib)
find_library(TensorFlow_FRAMEWORK_LIBRARY
NAMES
libtensorflow_framework.1.14.0.dylib
libtensorflow_framework.1.dylib
libtensorflow_framework.dylib
HINTS
/usr/local/lib)
# set TensorFlow_FOUND
find_package_handle_standard_args(TensorFlow DEFAULT_MSG
TensorFlow_INCLUDE_DIR
TensorFlow_LIBRARY
TensorFlow_FRAMEWORK_LIBRARY
)

Related

cmake on Mac with ARM M1 is running linker with x86_64 architecture instead of arm64

I am trying to compile glfw from source on Mac with M1 arm64 processor, and while running the linker, cmake strangely is trying to link the project for x86_64 architecture, while the binaries were built for arm64.
I clone the project, create build folder named cmake-build-debug, generate build system in it with the Makefile etc. as follows:
git clone https://github.com/glfw/glfw.git
cd glfw
mkdir cmake-build-debug
cd cmake-build-debug
cmake -S .. -B . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_HOST_SYSTEM_PROCESSOR=arm64 -DCMAKE_SYSTEM_PROCESSOR=arm64
This works fine. But now that I build it with make or cmake --config Debug --build ., the .o binaries are generated perfectly fine, but linker script is incorrectly invoked by cmake with x86_64 target architecture for some reason:
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Including Cocoa support
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/burkov/Documents/Projects/open-source/glfw/cmake-build-debug
[ 47%] Built target glfw
Scanning dependencies of target wave
[ 50%] Linking C executable wave.app/Contents/MacOS/wave
ld: warning: ignoring file CMakeFiles/wave.dir/wave.c.o, building for macOS-x86_64 but attempting to link with file built for unknown-arm64
ld: warning: ignoring file ../src/libglfw3.a, building for macOS-x86_64 but attempting to link with file built for macOS-arm64
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [examples/wave.app/Contents/MacOS/wave] Error 1
make[1]: *** [examples/CMakeFiles/wave.dir/all] Error 2
make: *** [all] Error 2
I look at the failing Makefile in glfw/cmake-build-debug/examples/CMakeFiles/wave.dir/build.make and see the line, where cmake is crashing:
cd /Users/me/Documents/Projects/open-source/glfw/cmake-build-debug/examples && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/wave.dir/link.txt --verbose=$(VERBOSE)
I manually open the file glfw/cmake-build-debug/examples/CMakeFiles/wave.dir/link.txt file and see the following link script code there:
/Library/Developer/CommandLineTools/usr/bin/cc -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/wave.dir/wave.c.o -o wave.app/Contents/MacOS/wave ../src/libglfw3.a -framework Cocoa -framework IOKit -framework CoreFoundation
If I manually execute this line from shell, it successfully builds my binary for arm64 architecture, as expected.
But when this link.txt script is automatically invoked with cmake via cmake -E cmake_link_script CMakeFiles/wave.dir/link.txt --verbose=$(VERBOSE), it fails, apparently, trying to build the binary for the wrong x86_64 architecture.
Why is this happening and how to fix this?
For anyone running into the same problem, it looks like the first version of cmake with an adequate support for Apple Silicon is 3.19.
I was using 3.17.5 as my slightly out-of-date version of CLion does not support versions of cmake above that.
After an update to cmake 3.22.4 the problem is gone.

Linker error when building with Emscripten

I have an existing C++ library that I'm trying to port to Wasm using Emscripten.
The library itself builds fine:
[ 33%] Linking CXX static library libFoo.a
[ 33%] Built target Foo
However, I'm encountering a linker error when building the test suite:
[ 67%] Linking CXX executable FooTests_Run_Wasm.html
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Tests/FooTests_Run_Wasm.html] Error 1
make[1]: *** [Tests/CMakeFiles/FooTests_Run_Wasm.dir/all] Error 2
make: *** [all] Error 2
emmake: error: 'make' failed (returned 2)
Here are the linker flags I'm using:
-fexceptions
-pthread
--bind
-s ALLOW_MEMORY_GROWTH=1
-s ERROR_ON_UNDEFINED_SYMBOLS=0
-s FILESYSTEM=0
-s LLD_REPORT_UNDEFINED=1
-s PROXY_TO_PTHREAD=1
-s SAFE_HEAP=1
-s STRICT=1

CMake - undefined symbols encountered when building application depends on PcapPlusPlus

I programmed a simple application using PcapPlusPlus library with CLion on MacOS.
The code is really simple:
#include "../include/PCPP/PcapFileDevice.h"
int main(int argc, char* argv[])
{
std::string path;
pcpp::PcapFileReaderDevice reader(path);
reader.open();
reader.close();
return 0;
}
Here is CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
project (Test CXX)
add_executable(cmd_main ${PROJECT_SOURCE_DIR}/test/cmd_main.cpp)
target_include_directories(cmd_main
PUBLIC
${PROJECT_SOURCE_DIR}/include)
target_link_libraries(cmd_main
PUBLIC
${PROJECT_SOURCE_DIR}/lib/libCommon++.a
${PROJECT_SOURCE_DIR}/lib/libPacket++.a
${PROJECT_SOURCE_DIR}/lib/libPcap++.a
)
The directory is also simple:
|
|--include
|----PCPP/
|--lib
|----libCommon++.a
|----libPacket++.a
|----libPcap++.a
|--test
|----cmd_main.cpp
Here is compile result:
(base) 2ir0#iMac Test % cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/2ir0/Documents/Maltrace
(base) 2ir0#iMac Test % make
Scanning dependencies of target cmd_main
[ 50%] Building CXX object CMakeFiles/cmd_main.dir/test/cmd_main.cpp.o
[100%] Linking CXX executable cmd_main
Undefined symbols for architecture x86_64:
"_pcap_close", referenced from:
pcpp::IFileDevice::close() in libPcap++.a(PcapFileDevice.o)
pcpp::PcapFileReaderDevice::open() in libPcap++.a(PcapFileDevice.o)
"_pcap_compile", referenced from:
pcpp::IPcapDevice::setFilter(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in libPcap++.a(PcapDevice.o)
......
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [cmd_main] Error 1
make[1]: *** [CMakeFiles/cmd_main.dir/all] Error 2
make: *** [all] Error 2
It seems cmd_main didn't link PcapPlusPlus library. But why?
I read the error information carefully, found that PcapPlusPlus need libpcap library, so I added libpcap.a, and fixed the problem.

OpenCV 3.0 source code installation troubleshooting

I installed OpenCV3.0 using the source code obtained from itseez github repo. I set the install prefix as /home/ubuntu/installed_libs/. All went well. I even set ldconfig path in /etc/ld.so.conf.d/local.conf and then sudo ldconfig.
However in my project (CMake) I cannot find the newly installed directory.
When I do cmake ../ in the build directory it throws the following error.
I did some changes as suggested in the answers.
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
set(OpenCV_DIR /home/ubuntu/installed_libs/share/OpenCV)
find_package( OpenCV )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBRARIES} )
message(STATUS "OpenCV_FOUND=${OpenCV_FOUND}")
message(STATUS "OpenCV_INCLUDES=${OpenCV_INCLUDE_DIR}")
message(STATUS "OpenCV_LIBRARIES=${OpenCV_LIBRARIES}")
message(STATUS "OpenCV_DEFINATIONS=${OpenCV_DEFINATIONS}")
message(STATUS "OpenCV_DIR=${OpenCV_DIR}")
Now cmake happens successfully.
$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found CUDA: /usr/local/cuda (found suitable exact version "6.5")
-- OpenCV_FOUND=1
-- OpenCV_INCLUDES=
-- OpenCV_LIBRARIES=opencv_videostab;opencv_videoio;opencv_video;opencv_ts;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_hal;opencv_flann;opencv_features2d;opencv_cudev;opencv_cudawarping;opencv_cudastereo;opencv_cudaoptflow;opencv_cudaobjdetect;opencv_cudalegacy;opencv_cudaimgproc;opencv_cudafilters;opencv_cudafeatures2d;opencv_cudacodec;opencv_cudabgsegm;opencv_cudaarithm;opencv_core;opencv_calib3d
-- OpenCV_DEFINATIONS=
-- OpenCV_DIR=/home/ubuntu/installed_libs/share/OpenCV
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/ctry/opencvtest/build
However, when I do a make, I get an error :
Scanning dependencies of target DisplayImage
[100%] Building CXX object CMakeFiles/DisplayImage.dir/DisplayImage.cpp.o
Linking CXX executable DisplayImage
CMakeFiles/DisplayImage.dir/DisplayImage.cpp.o: In function `main':
DisplayImage.cpp:(.text+0x94): undefined reference to `cv::imread(std::string const&, int)'
DisplayImage.cpp:(.text+0x108): undefined reference to `cv::namedWindow(std::string const&, int)'
DisplayImage.cpp:(.text+0x14e): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
DisplayImage.cpp:(.text+0x15e): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [DisplayImage] Error 1
make[1]: *** [CMakeFiles/DisplayImage.dir/all] Error 2
make: *** [all] Error 2
I know this is a linking error. How should I fix this?
Verbose make display incase it is helpful.
$ make VERBOSE=1
/usr/bin/cmake -H/home/ubuntu/ctry/opencvtest -B/home/ubuntu/ctry/opencvtest/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/ubuntu/ctry/opencvtest/build/CMakeFiles /home/ubuntu/ctry/opencvtest/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/ubuntu/ctry/opencvtest/build'
make -f CMakeFiles/DisplayImage.dir/build.make CMakeFiles/DisplayImage.dir/depend
make[2]: Entering directory `/home/ubuntu/ctry/opencvtest/build'
cd /home/ubuntu/ctry/opencvtest/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ubuntu/ctry/opencvtest /home/ubuntu/ctry/opencvtest /home/ubuntu/ctry/opencvtest/build /home/ubuntu/ctry/opencvtest/build /home/ubuntu/ctry/opencvtest/build/CMakeFiles/DisplayImage.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/ubuntu/ctry/opencvtest/build'
make -f CMakeFiles/DisplayImage.dir/build.make CMakeFiles/DisplayImage.dir/build
make[2]: Entering directory `/home/ubuntu/ctry/opencvtest/build'
Linking CXX executable DisplayImage
/usr/bin/cmake -E cmake_link_script CMakeFiles/DisplayImage.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/DisplayImage.dir/DisplayImage.cpp.o -o DisplayImage -L/usr/local/cuda/lib -rdynamic /home/ubuntu/installed_libs/lib/libopencv_videostab.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_videoio.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_video.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_ts.a /home/ubuntu/installed_libs/lib/libopencv_superres.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_stitching.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_shape.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_photo.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_objdetect.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_ml.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_imgproc.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_imgcodecs.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_highgui.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_hal.a /home/ubuntu/installed_libs/lib/libopencv_flann.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_features2d.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudev.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudawarping.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudastereo.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudaoptflow.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudaobjdetect.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudalegacy.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudaimgproc.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudafilters.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudafeatures2d.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudacodec.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudabgsegm.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudaarithm.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_core.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_calib3d.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudawarping.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_objdetect.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudafilters.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudaarithm.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_features2d.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_ml.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_highgui.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_videoio.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_imgcodecs.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_flann.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_video.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_imgproc.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_core.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_cudev.so.3.0.0 /home/ubuntu/installed_libs/lib/libopencv_hal.a -ldl -lm -lpthread -lrt -lcudart -lnppc -lnppi -lnpps -lcufft -lcudart -lnppc -lnppi -lnpps -lcufft -Wl,-rpath,/usr/local/cuda/lib:/home/ubuntu/installed_libs/lib
CMakeFiles/DisplayImage.dir/DisplayImage.cpp.o: In function `main':
DisplayImage.cpp:(.text+0x94): undefined reference to `cv::imread(std::string const&, int)'
DisplayImage.cpp:(.text+0x108): undefined reference to `cv::namedWindow(std::string const&, int)'
DisplayImage.cpp:(.text+0x14e): undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
DisplayImage.cpp:(.text+0x15e): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [DisplayImage] Error 1
make[2]: Leaving directory `/home/ubuntu/ctry/opencvtest/build'
make[1]: *** [CMakeFiles/DisplayImage.dir/all] Error 2
make[1]: Leaving directory `/home/ubuntu/ctry/opencvtest/build'
make: *** [all] Error 2
You should check the output of:
ldconfig -p | grep -i opencv
pkg-config --cflags opencv
pkg-config --libs opencv
If nothing is listed, then you ldconfig may configured incorrectly. If the system-installed version of OpenCV is listed, it may be a problem of the search order.
In either case, you could try to configure the CMAKE_MODULE_PATH of your project DisplayImage, which is searched by CMake before standard system locations. So, assuming your in your build directory of DisplayImage is $SRC_DIR/build, configure your project like this
cmake -DCMAKE_MODULE_PATH="/home/ubuntu/installed_libs/<OpenCV directory>" <other options> ..
Also interesting: what happens in the background of find_package().
You can add
set(OpenCV_DIR /home/ubuntu/installed_libs/share/OpenCV)
to your CMakeLists, so it looks something like
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
set(OpenCV_DIR /home/ubuntu/installed_libs/share/OpenCV)
find_package( OpenCV REQUIRED 3.0 )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

Why won't a CMake-generated Makefile find an external library?

I'm attempting to use CMake for the first time and meeting with little success. My CMakeLists.txt is:
# Sets the version of CMake that is required.
cmake_minimum_required(VERSION 2.8.10)
# Name of the project.
project(QTCODERLIB)
# Adds common directories to the build.
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
# Check for header files that we depend on.
include(CheckIncludeFiles)
check_include_files(libavcodec/avcodec.h HAVE_AVCODEC_H)
# Adds all of the source files.
file(GLOB SOURCE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cxx)
# Builds a library named `qtcoder` from source.
add_library(qtcoder SHARED ${SOURCE})
# Links the library against third-party dependencies.
target_link_libraries(qtcoder avcodec)
My test.cxx file is:
#include "config.h"
#include <libavcodec/avcodec.h>
void f(void) {
avcodec_register_all();
}
cmake . && make VERBOSE=1 results in this:
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -H/Users/phowes/Personal/QTCoder/QTCoderLib -B/Users/phowes/Personal/QTCoder/QTCoderLib --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_progress_start /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make -f CMakeFiles/qtcoder.dir/build.make CMakeFiles/qtcoder.dir/depend
cd /Users/phowes/Personal/QTCoder/QTCoderLib && /usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles/qtcoder.dir/DependInfo.cmake --color=
make -f CMakeFiles/qtcoder.dir/build.make CMakeFiles/qtcoder.dir/build
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_progress_report /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles 1
[100%] Building CXX object CMakeFiles/qtcoder.dir/test.cxx.o
/usr/bin/c++ -Dqtcoder_EXPORTS -fPIC -I/usr/local/include -o CMakeFiles/qtcoder.dir/test.cxx.o -c /Users/phowes/Personal/QTCoder/QTCoderLib/test.cxx
Linking CXX shared library libqtcoder.dylib
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_link_script CMakeFiles/qtcoder.dir/link.txt --verbose=1
/usr/bin/c++ -dynamiclib -Wl,-headerpad_max_install_names -o libqtcoder.dylib -install_name /Users/phowes/Personal/QTCoder/QTCoderLib/libqtcoder.dylib CMakeFiles/qtcoder.dir/test.cxx.o -L/usr/local/lib -lavcodec
Undefined symbols for architecture x86_64:
"avcodec_register_all()", referenced from:
f() in test.cxx.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libqtcoder.dylib] Error 1
make[1]: *** [CMakeFiles/qtcoder.dir/all] Error 2
make: *** [all] Error 2
Both the object file and the library are compiled as 64-bit:
$ lipo -info CMakeFiles/qtcoder.dir/test.cxx.o
Non-fat file: CMakeFiles/qtcoder.dir/test.cxx.o is architecture: x86_64
$ lipo -info /usr/local/lib/libavcodec.dylib
Non-fat file: /usr/local/lib/libavcodec.dylib is architecture: x86_64
The function exists in the library:
$ nm /usr/local/lib/libavcodec.dylib | grep avcodec_register_all
0000000000033c01 T _avcodec_register_all
What am I doing wrong here?
The avcodec libary is a C library and looking at your cmake output you are compiling for CXX. This question addresses how to handle precisely that scenario: g++ Linking Error on Mac while compiling FFMPEG
Usually you'd use find_package to do these sorts of heavy lifting tasks. CMake ships with a lot of modules by default, but sometimes you have to download one for less used projects.
Here is some documentation on how to find libraries.
Here is their contrived example of what you'd expect to see.
cmake_minimum_required(VERSION 2.8)
project(helloworld)
add_executable(helloworld hello.c)
find_package (BZip2)
if (BZIP2_FOUND)
include_directories(${BZIP_INCLUDE_DIRS})
target_link_libraries (helloworld ${BZIP2_LIBRARIES})
endif (BZIP2_FOUND)
From simple web searches it isn't clear to me that CMake provides an AVCodec module. I found a few online:
https://github.com/arjanhouben/SDL_ffmpeg/blob/master/Findavcodec.cmake
http://whispercast.org/trac/browser/trunk/cmake/FindLibAvCodec.cmake
I see most people using this library are interested in FFMPEG, which maybe is what you are interested too.
https://github.com/zinnschlag/openmw/blob/master/cmake/FindFFMPEG.cmake
If you do need to use one that you download, here are some instructions for how to use custom modoules.