I'm new to this forum, but I've seen it a few times while trying to search for a solution to this problem. I'm trying to generate KML files to use in Google Earth using a C++ API library I found for Ubuntu (libkml-dev_1.2.0-1ubuntu6_amd64). I installed the package using the command sudo apt-get install libkml-dev, came back successful. Afterwards, I used the command line terminal to navigate to the examples folder to try and execute the program 'helloworld.cc' with the command g++ helloworld.cc -o helloworld, but then got a slew of errors (mainly claiming that kmldom is an undefined reference). Sorry, I wanted to attach the text file, but don't know how so I included a sample of the error below. I've searched high and low all week, made sure the header files were indeed included in the download, and even contacted the Google Earth developers about the problem (and they responded that they have nothing to do with this and to redirect all questions regarding this issue to StackOverflow).
Does anyone know what is causing this problem(s) and what I can do to resolve this so I can move on please?
/tmp/cc5u2JyV.o: In function HelloKml(bool)': helloworld.cc:(.text+0x17): undefined reference to kmldom::KmlFactory::GetFactory()'
helloworld.cc:(.text+0x27): undefined reference to kmldom::KmlFactory::CreateCoordinates() const' helloworld.cc:(.text+0x328): undefined reference to kmldom::AsPoint(boost::intrusive_ptrkmldom::Element)'
/tmp/cc5u2JyV.o: In function boost::intrusive_ptr<kmldom::Coordinates>::intrusive_ptr(kmldom::Coordinates*, bool)': helloworld.cc:(.text._ZN5boost13intrusive_ptrIN6kmldom11CoordinatesEEC2EPS2_b[_ZN5boost13intrusive_ptrIN6kmldom11CoordinatesEEC5EPS2_b]+0x3d): undefined reference to kmlbase::intrusive_ptr_add_ref(kmlbase::Referent*)'
/tmp/cc5u2JyV.o: In function boost::intrusive_ptr<kmldom::Coordinates>::~intrusive_ptr()': helloworld.cc:(.text._ZN5boost13intrusive_ptrIN6kmldom11CoordinatesEED2Ev[_ZN5boost13intrusive_ptrIN6kmldom11CoordinatesEED5Ev]+0x23): undefined reference to kmlbase::intrusive_ptr_release(kmlbase::Referent*)'
/tmp/cc5u2JyV.o: In function boost::intrusive_ptr<kmldom::Geometry>::intrusive_ptr(boost::intrusive_ptr<kmldom::Geometry> const&)': helloworld.cc:(.text._ZN5boost13intrusive_ptrIN6kmldom8GeometryEEC2ERKS3_[_ZN5boost13intrusive_ptrIN6kmldom8GeometryEEC5ERKS3_]+0x35): undefined reference to kmlbase::intrusive_ptr_add_ref(kmlbase::Referent*)'
collect2: ld returned 1 exit status
When you compile application that uses library, you need to link it when your application compiles. So, try using this parameters:
To specify a directory to search for your libs, use -L:
-L/data[...]/lib
To specify the actual library name, use -l:
-labc (links abc.a or abc.so)
To specify a directory to search for include files, use -I:
-I/data[...]/lib
I've found the solution. The problem is that you are linking libkml incrorrectly. You should find the paths to the header files and to the library files (*.so). I found them here:
/usr/include/kml/ (include dit with headers),
/usr/lib/x86_64-linux-gnu/ (library dir).
I use CMake and CMakeLists.txt for a project. Using libkml may look like this:
`cmake_minimum_required (VERSION 3.2)
# Set language standard
set(CMAKE_CXX_STANDARD "11")
project (test_proj)
add_definitions(-std=c++11)
# Set default build type to RelWithDebInfo if not specified
if (NOT CMAKE_BUILD_TYPE)
message (STATUS "Default CMAKE_BUILD_TYPE not set using Release with Debug Info")
set (CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE
STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel"
FORCE)
endif()
# linking boost library
find_package(Boost COMPONENTS system filesystem thread REQUIRED)
if(NOT Boost_FOUND)
message(SEND_ERROR "Failed to find boost.")
return()
else()
include_directories(${Boost_INCLUDE_DIRS})
endif()
add_executable(test_proj main.cpp)
set (LibKML_INCLUDE_DIRS /usr/include/kml/)
set (LibKML_LIBRARIES /usr/lib/x86_64-linux-gnu/libkmlbase.so /usr/lib/x86_64-linux-gnu/libkmlconvenience.so /usr/lib/x86_64-linux-gnu/libkmldom.so /usr/lib/x86_64-linux-gnu/libkmlengine.so /usr/lib/x86_64-linux-gnu/libkmlregionator.so /usr/lib/x86_64-linux-gnu/libkmlxsd.so)
message("LibKML is at: ${LibKML_INCLUDE_DIRS} and ${LibKML_LIBRARIES}")
message("Boost is at: ${Boost_INCLUDE_DIRS} and ${Boost_LIBRARIES}")
target_include_directories(test_proj
PUBLIC
${LibKML_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS} )
target_link_libraries(test_proj
PUBLIC
${LibKML_LIBRARIES} ${Boost_LIBRARIES})
install(TARGETS test_proj EXPORT test_proj_export)
export(EXPORT test_proj_export FILE cmake/test_proj-targets.cmake)`
Related
I want to build a statically, because I need to distribute the application on multiple platforms (Linux and Windows). OpenCV has been built and installed on a linux machine statically.
Here you can see the relevant parts that are included in my CMakeLists.txt that were supposed to make OpenCV link statically
#windows
message("Compiling for windows")
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(BUILD_SHARED_LIBS OFF) #this has no effect
set(CMAKE_LINK_LIBRARY_SUFFIX ".a") #this has no effect
#openCV
set(OpenCV_STATIC ON) #this has no effect
find_package(OpenCV REQUIRED )
include_directories(${OpenCV_INCLUDE_DIRS} )
During linking I get this error, as it apparently is a library required by opencv:
/usr/lib/x86_64-linux-gnu/libpng.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
As you can see libpng.so is being used. Even though in that Folder a libpng.a file is also available.
This only happens with mingw, but using the "-static" flag inside
target_link_libraries( Tracking ${OpenCV_LIBS} "-static")
results in
/usr/bin/x86_64-w64-mingw32-ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libpng.so'
collect2: error: ld returned 1 exit status
So It still uses the .so file instead of .a That is why I suspect I need to change the OpenCV configuration
I have spent hours on this, so help is appreciated.
This should force to link libpng statically:
set_target_properties(libpng PROPERTIES LINK_SEARCH_START_STATIC 1)
set_target_properties(libpng PROPERTIES LINK_SEARCH_END_STATIC 1)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
I know, there are plenty of different question out there regarding how to link boost libraries with a c++ project. However after hours of trying I still couldn't figure it out.
Here is my problem:
I need a filesystem library. Unluckily I didn't manage to use the new std::filesystem library so I thought let's simply use boost... until now I only needed some header only boost libraries, so I spend a couple of hours to finally manage to build boost (at least I think I have build it) in my directory C:/boost/stage/lib I have files called libboost_filesystem-mgw53-1_64.dll and so on...
I'm trying to use cmake to link these libraries to my own file, but I really get confused... First of all: in CMAKE should I use "BOOST" "Boost" or "boost"...
At the moment I have a mixture... I use something like:
set(CMAKE_CXX_STANDARD 17)
SET(BOOST_ROOT "C:/boost")
SET(BOOST_LIBRARYDIR "C:/boost/stage/lib")
find_package(BOOST 1.64.0 COMPONENTS system filesystem REQUIRED)
include_directories(${BOOST_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
set(SOURCE_FILES list of all my source files)
add_executable(myExecuteable ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(myExecuteable ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})
After hours I figured out that my find_package command only works if I type "BOOST" instead of "Boost"...
But I am not allowed to change:
SET(BOOST_ROOT "C:/boost")
to
SET(Boost_ROOT "C:/boost")
I'm using CLION and my Cmake now runs without error messages (finally...)
but if I try to build my program I get this error messages:
CMakeFiles\myFolder.dir/objects.a(main.cpp.obj): In function `_static_initialization_and_destruction_0':
C:/boost/boost/system/error_code.hpp:222: undefined reference to `boost::system::generic_category()'
C:/boost/boost/system/error_code.hpp:223: undefined reference to `boost::system::generic_category()'
C:/boost/boost/system/error_code.hpp:224: undefined reference to `boost::system::system_category()'
collect2.exe: error: ld returned 1 exit status
I have tried a lot of different solution provided here in previous questions but unluckily nothing worked so far...
I think I'm missing something obvious
OK, I know that opencv linking has been discussed before, but I can't see an error and I don't understand the corrective action. I'm trying to link DBoW2 library, which requires opencv. I'm getting undefined reference errors.
$ mingw32-make
Linking CXX shared library ..\lib\libDBoW2.dll
CMakeFiles\DBoW2.dir/objects.a(FORB.cpp.obj):FORB.cpp:(.text+0x124): undefined reference to `cv::Mat::zeros(int, int, int)'
CMakeFiles\DBoW2.dir/objects.a(FORB.cpp.obj):FORB.cpp:(.text+0x1db): undefined reference to `cv::fastFree(void*)'
CMakeFiles\DBoW2.dir/objects.a(FORB.cpp.obj):FORB.cpp:(.text+0x394): undefined reference to `cv::Mat::deallocate()'
CMakeFiles\DBoW2.dir/objects.a(FORB.cpp.obj):FORB.cpp:(.text+0x46a): undefined reference to `cv::Mat::copyTo(cv::_OutputArray const&) const'
CMakeFiles\DBoW2.dir/objects.a(FORB.cpp.obj):FORB.cpp:(.text+0x503): undefined reference to `cv::Mat::copySize(cv::Mat const&)'
CMakeFiles\DBoW2.dir/objects.a(FORB.cpp.obj):FORB.cpp:(.text+0x93f): undefined reference to `cv::Mat::create(int, int const*, int)'
collect2.exe: error: ld returned 1 exit status
Here's the CMakeLists.txt file
cmake_minimum_required(VERSION 2.8)
project(DBoW2)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")
set(HDRS_DBOW2
DBoW2/BowVector.h
DBoW2/FORB.h
DBoW2/FClass.h
DBoW2/FeatureVector.h
DBoW2/ScoringObject.h
DBoW2/TemplatedVocabulary.h)
set(SRCS_DBOW2
DBoW2/BowVector.cpp
DBoW2/FORB.cpp
DBoW2/FeatureVector.cpp
DBoW2/ScoringObject.cpp)
set(HDRS_DUTILS
DUtils/Random.h
DUtils/Timestamp.h)
set(SRCS_DUTILS
DUtils/Random.cpp
DUtils/Timestamp.cpp)
find_package(OpenCV REQUIRED)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
include_directories(${OpenCV_INCLUDE_DIRS})
add_library(DBoW2 SHARED ${SRCS_DBOW2} ${SRCS_DUTILS})
target_link_libraries(DBoW2 ${OpenCV_LIBS})
I'm using the gui interface, and the parameter OpenCV_DIR automatically sets to C:/OpenCV/minwg_64. Under that directory there is a directory lib containing library files like "libopencv_videostab300.dll.a"
The CMakeCache.txt file contains the lines
//Dependencies for the target
DBoW2_LIB_DEPENDS:STATIC=general;opencv_videostab;general;opencv_videoio;general;opencv_video;general;opencv_superres;general;opencv_stitching;general;opencv_shape;general;opencv_photo;general;opencv_objdetect;general;opencv_ml;general;opencv_imgproc;general;opencv_imgcodecs;general;opencv_highgui;general;opencv_hal;general;opencv_flann;general;opencv_features2d;general;opencv_core;general;opencv_calib3d;
From what I've read, the following lines should be sufficient, but I'm getting the linker errors.
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(DBoW2 ${OpenCV_LIBS})
Edit 1:
In response to Chris Maes
added the pkg check
pkg_check_modules (OPENCV REQUIRED opencv)
Now the configure causes an error, which is progress, but I'm still at a loss. I must have an error in the opencv installation / build. I do have a second copy on an external drive, that was built recently (and easily) using something like cmake .. . But setting OpenCV_DIR to the external build produces the same error.
Found PkgConfig: C:/msys64/usr/bin/pkg-config.exe (found version "0.28")
checking for module 'opencv'
package 'opencv' not found
Edit 2:
Here are the settings that CMake automatically generates when I start a new cache and press generate twice (first time it only generates the make, sh).
CMAKE_BUILD_TYPE (BLANK)
CMAKE_GNUtoMS (UNCHECKED)
CMAKE_INSTALL_PREFIX C:/Program Files (x86)/DBoW2
CMAKE_MAKE_PROGRAM C:/msys64/mingw64/bin/mingw32-make.exe
CMAKE_SH C:/msys64/usr/bin/sh.exe
OpenCV_DIR C:/OpenCV/minwg_64
The directory C:/OpenCV/minwg_64 contains the opencv library built from mingw gcc 64, and cmake files including OpenCVConfig.cmake and directories bin and lib. I wonder if I need directory staticlib?
For windows environment, I have
OPENCV_DIR = C:\OpenCV\minwg_64 (where built bin and lib are located)
OPENCV_VER = 300
PATH includes C:\OpenCV\minwg_64\bin
On linux I use pkg_check_modules plugin for cmake:
find_package( OpenCV REQUIRED )
find_package( PkgConfig REQUIRED )
pkg_check_modules (OPENCV REQUIRED opencv)
include_directories(/usr/include/opencv2)
target_link_libraries(DBoW2 ${OPENCV_LDFLAGS})
note: I don't remember why I used hardcoded /usr/include/opencv2, but I guess OPENCV_INCLUDE_DIRS wasn't any good when I tried. There might be a more clean way :)
Using VTK 6.2, there are multiple link errors when trying to make a project:
/usr/bin/ld: cannot find -lvtkWrappingTools
/usr/bin/ld: cannot find -lvtkGUISupportQt
/usr/bin/ld: cannot find -lvtkWrappingPythonCore
/usr/bin/ld: cannot find -lvtkFiltersPython
/usr/bin/ld: cannot find -lvtkGUISupportQtSQL
/usr/bin/ld: cannot find -lvtkRenderingQt
/usr/bin/ld: cannot find -lvtkglew
/usr/bin/ld: cannot find -lvtkGUISupportQtOpenGL
/usr/bin/ld: cannot find -lvtkLocalExample
/usr/bin/ld: cannot find -lvtkViewsQt
/usr/bin/ld: cannot find -lvtkoggtheora
/usr/bin/ld: cannot find -lvtkGUISupportQtWebkit
Problem:
Unresolved linker errors. This may be a path issue, since the libraries appear to be present in /usr/local/ but are not seen by ld at compile time...
Background information:
OS is Ubuntu 13.10
VTK is 6.2 from the Kitware github
CMake file follows guidelines supplied by the Kitware CMake for VTK 6+ docs
VTK was configured as an out-of-source CMake build (no problems) followed by make and make install so that all of the libraries are correctly placed in /usr/local/lib.
My project build now uses the following CMakeLists.txt:
# Add VTK, insist that it uses 6.2,
find_package(VTK 6.2 EXACT REQUIRED NO_MODULE)
include(${VTK_USE_FILE})
find_package(GLEW REQUIRED)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${VTK_DEFINITIONS})
include_directories(
${VTK_INCLUDE_DIRS}
${GLEW_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
####################
# Make my_target
####################
set(EXE my_target)
set(SOURCES
my_target.cpp
)
add_executable(${EXE} ${SOURCES})
target_link_libraries(${EXE} ${VTK_LIBRARIES} ${GLEW_LIBRARY} )
###################
Change the find_package parameters to specify just the modules that you want. For example:
find_package(VTK 6.2 EXACT REQUIRED COMPONENTS
vtkRenderingOpenGL vtkInteractionStyle NO_MODULE)
This 'fix' took some time to find. It looks like the default behaviour is for CMake to include all VTK modules ... some of which may not exist. If you specify components then the default behaviour is disabled. Unfortunately, it can be quite difficult to know what libraries to include, and so it would be nice to have the default "include everything" behaviour working!
My simple program didn't use Python or Qt, but ld still wants to resolve those basic libraries. This appears to be normal behaviour even when VTK is built without the Qt or Python modules.
This may be a bug in VTK 6.2. I'll raise it with Kitware, and revise the answer as/when new info is available...
A user of my project reported this error to me. I cannot reproduce it on my computer or my lab's server, so I ask it here.
The project uses CMake to generate build environment. It uses the FindBoost utility (provided with CMake) to find Boost resources.
On the beginning, my user said while linking the final programs, the compiler was provided with "/usr/lib64/lib64/libboost_XXX.so", instead of the correct "/usr/lib64/libboost_XXX.so". I failed to find why CMake generated such weird library location, and asked him to manually set the variable Boost_LIBRARIES, and print them:
Boost libraries are: /usr/lib64/libboost_thread-mt.so;/usr/lib64/libboost_program_options-mt.so;/usr/lib64/libboost_filesystem-mt.so
Things seem to be correct. The compilation was successful. But when it goes to linking, the program cries about many undefined symbols:
CMakeFiles/ht-filter.dir/ht-filter.cpp.o: In function `parse_options(int, char**)':
/public/home/yli/Downloads/htqc-0.15.0-Source/ht-filter.cpp:43: undefined reference to `boost::program_options::options_description::options_description(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
......
/usr/local/include/boost/program_options/errors.hpp:372: undefined reference to `boost::program_options::validation_error::get_template(boost::program_options::validation_error::kind_t)'
This is the two typical of the so-many errors: one locates from my source code, the other locates from boost's header. In the corresponding line of my source code, I just created the options_description object
// I renamed boost::program_options to opt
opt::options_description opt_main("Options:");
The OS of my user is CentOS 6.2, and his Boost version is 1.50.0 which is similiar with the one in my computer. The version of CMake of my user is 2.8.11 which is also same with mine.
While using CMake's find_package for Boost, you can give a few hints to CMake which may help it find the correct library, such as:
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(BOOST_ROOT "/usr")
find_package(Boost 1.50.0)
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}")
Also if you are linking with dynamic libs make sure to let Boost headers know about it (I think you shouldn't mess with the order in here):
link_directories(${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
add_definitions( -DBOOST_ALL_DYN_LINK )