Linking with a custom external library in CMAKE - cmake

There is a project, when building the project has problem with a linking library to the project.
I would be very grateful if someone told me how to solve this problem.
As I understand the problem is in the correct location of the library. So that when build the project correctly linked with it.
This is projects file CmakeList
cmake_minimum_required(VERSION 3.5.1)
project(maintenance)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC OFF)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Charts REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5Network REQUIRED)
include_directories(../../088)
#include(FindPackageHandleStandardArgs)
#find_library(Network_LIBRARY NAMES NetworkCommunication PATHS ../../088/build-libs-ubuntu-Release)
#find_package_handle_standard_args(Network DEFAULT_MSG Network_LIBRARY)
add_library(NetworkCommunication SHARED IMPORTED)
set_property(TARGET NetworkCommunication PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/../../088/build-libs-ubuntu-Release/libNetworkCommunication.so)
set(Network_LIBRARY NetworkCommunication)
#link_directories(${CMAKE_CURRENT_LIST_DIR}/../../088/build-libs-ubuntu-Release)
qt5_add_resources(RCC_RESOURCES resources.qrc)
file(GLOB SOURCE_FILES_2
${CMAKE_CURRENT_SOURCE_DIR}/cop/*.h
${CMAKE_CURRENT_SOURCE_DIR}/cop/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/curves/*.h
${CMAKE_CURRENT_SOURCE_DIR}/curves/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/curves/shapes/*.h
${CMAKE_CURRENT_SOURCE_DIR}/curves/shapes/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/general/*.h
${CMAKE_CURRENT_SOURCE_DIR}/general/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/load_cells/*.h
${CMAKE_CURRENT_SOURCE_DIR}/load_cells/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/motors/*.h
${CMAKE_CURRENT_SOURCE_DIR}/motors/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/passive_mode/*.h
${CMAKE_CURRENT_SOURCE_DIR}/passive_mode/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/settings/*.h
${CMAKE_CURRENT_SOURCE_DIR}/settings/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/system/*.h
${CMAKE_CURRENT_SOURCE_DIR}/system/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../Gener095/Messages/*.h
${CMAKE_CURRENT_SOURCE_DIR}/../Gener095/Messages/*.cpp
)
set(SOURCE_FILES
Error.cpp
Error.hpp
main.cpp
MainWindow.cpp
MainWindow.h
NetworkCommunicator.cpp
NetworkCommunicator.h
Utils.cpp
Utils.h
ITab.h
)
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${SOURCE_FILES_2} ${RCC_RESOURCES})
#target_link_libraries(${PROJECT_NAME} ${Network_LIBRARY})
target_link_libraries(${PROJECT_NAME} NetworkCommunication)
target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::Core Qt5::Gui Qt5::Charts Qt5::Xml Qt5::Network)
include(../../088/BuildUtilities/scripts/lib_setup.cmake)
and logs with errors
...
[ 95%] Building CXX object CMakeFiles/maintenance.dir/qrc_resources.cpp.o
[ 97%] Building CXX object CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o
[100%] Linking CXX executable maintenance
CMakeFiles/maintenance.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow(QMainWindow*)':
/media/blinct/free1/QtProjects/Applications/095/maintenance/MainWindow.cpp:74: undefined reference to `TenzGraphTab::TenzGraphTab(QWidget*)'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o: In function `AngleSensors::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)':
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:92: undefined reference to `AngleSensors::OnSetNullPosition()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:93: undefined reference to `AngleSensors::OnResetAccel()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:94: undefined reference to `AngleSensors::OnDataReceived(QString, QMap<QString, QVariant>)'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:95: undefined reference to `AngleSensors::OnHandleUp()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:96: undefined reference to `AngleSensors::OnHandleDown()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:97: undefined reference to `AngleSensors::OnHandleReleased()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:98: undefined reference to `AngleSensors::OnHandleTimer()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x28): undefined reference to `AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x30): undefined reference to `AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x1c0): undefined reference to `non-virtual thunk to AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x1c8): undefined reference to `non-virtual thunk to AngleSensorColumn::~AngleSensorColumn()'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlSerialPortImpl::setRequestToSend(bool)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `g_sVersion_NetworkCommunication'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlUdpSocketImpl::writeDatagram(QByteArray const&, QHostAddress const&, unsigned short)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::isListening() const'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlFileImpl::close()'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::hasPendingConnections() const'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpSocketImpl::connectToHost(QHostAddress const&, unsigned short)'
...
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlUdpSocketImpl::readDatagram(char*, long long, QHostAddress*, unsigned short*)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::close()'
collect2: error: ld returned 1 exit status
CMakeFiles/maintenance.dir/build.make:936: recipe for target 'maintenance' failed
make[3]: *** [maintenance] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/maintenance.dir/all' failed
make[2]: *** [CMakeFiles/maintenance.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/maintenance.dir/rule' failed
make[1]: *** [CMakeFiles/maintenance.dir/rule] Error 2
Makefile:118: recipe for target 'maintenance' failed
make: *** [maintenance] Error 2
Thanks in advance.
For a very long time I can not understand how to solve this problem.

If NetworkCommunication is something you've written and already have installed, then consider including a FindNetworkCommunication.cmake file with the package. That file should contain a method for finding NetworkCommunication like so:
# Sets NetworkCommunication_FOUND if found.
#
# If NetworkCommunication_FOUND is TRUE, then the following variables are also
# set:
#
# NetworkCommunication_LIBRARY - Full path to library to link
# NetworkCommunication_INCLUDE_DIR - Path to include directory
#
# $NetworkCommunicationDIR is an environment variable that would correspond to the
# ./configure --prefix=$NetworkCommunicationDIR used in building NetworkCommunication.
#
find_path(NetworkCommunication_INCLUDE_DIR NetworkCommunication.h
HINTS
ENV NetworkCommunicationDIR
PATH_SUFFIXES include/NetworkCommunication include/NetworkCommunication include
PATHS
/opt/local
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Alexey\\NetworkCommunication\\1.00.0000;InstallDir]
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_NetworkCommunication_ARCH_DIR libs/Win64)
else()
set(_NetworkCommunication_ARCH_DIR libs/Win32)
endif()
find_library(NetworkCommunication_LIBRARY
NAMES NetworkCommunication
HINTS
ENV NetworkCommunicationDIR
PATH_SUFFIXES lib64 lib libs64 libs ${_NetworkCommunication_ARCH_DIR}
PATHS
/opt/local
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Alexey\\NetworkCommunication\\1.00.0000;InstallDir]
)
unset(_NetworkCommunication_ARCH_DIR)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NetworkCommunication DEFAULT_MSG NetworkCommunication_LIBRARY NetworkCommunication_INCLUDE_DIR)
mark_as_advanced(NetworkCommunication_LIBRARY NetworkCommunication_INCLUDE_DIR)
Copy FindNetworkCommunication.cmake into the cmake installation's Modules folders (/usr/share/cmake-3.8/Modules) or copy it to a local folder and include the path to that folder in ${CMAKE_MODULES_PATH}.
Next, in your CMakeLists.txt file of your maintenance project add the following after add_executable
Find_Package(NetworkCommunication REQUIRED)
if (NetworkCommunication_FOUND)
target_include_directories(${PROJECT_NAME} ${NetworkCommunication_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${NetworkCommunication_LIBRARY})
endif (NetworkCommunication_FOUND)
This is a good solution if NetworkCommunication is an independant library which is used by maintenance but you intend to have it used by several other libraries too. If NetworkCommunication is part of the same project solution as maintenance and is really only meant to be linked to one project ever, then there are probably simpler solutions.

In maintenance.pro for Qt Creator i have this link for this library
U_LIB_DIR_PREFIX += ../../088/build-libs
U_LIBS += NetworkCommunication
There are many similar libraries for another project and I linked like
U_LIBS += NetworkCommunication \
Logging \
UnitController \
TherapyRunnersController \
GenersControllerCommon
All these libraries are build as dynamic libraries. And after this I link this libraries to projects.

Maybe there is another way how to link library to the project?
Because if you compare this option
U_LIB_DIR_PREFIX += ../../088/build-libs-ubuntu-Release
U_LIBS += NetworkCommunication
from QtCreator project file maintenance.pro and and writing a module for each library, it turns out very strange and difficult in comparison with 2 lines from *.pro

Related

ld: library not found for -lnetcdf

I am new to CMake. I can not resolve the flowing error. Could someone help me?
------------ERROR--------------
ld: library not found for -lnetcdf
collect2: error: ld returned 1 exit status
make[3]: *** [NUP] Error 1
make[2]: *** [CMakeFiles/NUP.dir/all] Error 2
make[1]: *** [CMakeFiles/NUP.dir/rule] Error 2
make: *** [NUP] Error 2
------------------- CMake File------------------
cmake_minimum_required(VERSION 3.10.0)
project(NUP Fortran)
enable_language(Fortran)
set(INCLUDE_FILE /usr/local/Cellar/netcdf/4.7.4/include)
set(lib_FILE /usr/local/Cellar/netcdf/4.7.4/lib)
find_package(netcdf REQUIRED)
if(netcdf_FOUND)
include_directories(${INCLUDE_FILE})
set(
SOURCE_FILES
${PROJECT_BINARY_DIR} unpack.f90
)
add_executable(NUP ${SOURCE_FILES} )
target_link_libraries(NUP netcdf)
endif()
--------------unpack.f90-------------------
PROGRAM unpack_array
IMPLICIT NONE
INCLUDE 'netcdf.inc'
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307)
......
I am using MACOS Catalina. Apple clang version 11.0.3 (clang-1103.0.32.59)
Target: x86_64-apple-darwin19.4.0
If you're using find_package() to find NetCDF on your machine, you shouldn't need to manually specify the paths as you have. Let find_package do that for you.
Note: CMake doesn't ship with a Find Module for NetCDF, so you'll have to download one (like this one) from the internet. Then, you need to tell CMake where to locate this FindNetCDF.cmake file on your system using CMAKE_MODULE_PATH. Finally, you can use the NetCDF::NetCDF imported target to link NetCDF to your project's targets.
cmake_minimum_required(VERSION 3.10.0)
project(NUP Fortran)
# Don't need this, you already enabled Fortran above in the 'project' call.
enable_language(Fortran)
set(INCLUDE_FILE /usr/local/Cellar/netcdf/4.7.4/include)
set(lib_FILE /usr/local/Cellar/netcdf/4.7.4/lib)
# Add the location of the 'FindNetCDF.cmake' file to your module path.
list(APPEND CMAKE_MODULE_PATH "/path/to/downloaded/find/module")
# Then, call find package for NetCDF.
find_package(NetCDF REQUIRED)
if(${NetCDF_FOUND})
# Don't need this if you use the imported target below.
include_directories(${INCLUDE_FILE})
# Don't provide directories with source file list.
set(SOURCE_FILES
${PROJECT_BINARY_DIR}
unpack.f90
)
add_executable(NUP ${SOURCE_FILES})
# Use the imported target to link netcdf instead.
target_link_libraries(NUP PRIVATE NetCDF::NetCDF)
endif()
As commented, there are other approaches to adding NetCDF to your CMake project. If you use a different find module, the syntax of the provided NetCDF CMake variables and imported targets may be slightly different. You'll have to examine the find module file itself.
In addition, you may instead use a CMake package configuration file (e.g. netCDFConfig.cmake) downloaded from the internet to add NetCDF to your project. In this case, you would still use find_package(), but you would specify the configuration file's location using CMAKE_PREFIX_PATH, rather than CMAKE_MODULE_PATH.
You can find detailed descriptions for each of these approaches in the CMake find_package() documentation. I highly encourage you spend some time to read it.

Crazy error when running a connector c++ program

I have a problem with Connector/C++.
I'm using CLion as IDE and want to create a c++ program to interact with mysql database.
this is my CMakeList.txt file which i include c++/connector static and dynamic libraries in it:
cmake_minimum_required(VERSION 3.15)
project(cpp_programming)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(MYSQL_CPPCONN_DIR "C:/Program Files/MySQL/MySQL Connector C++ 8.0")
include_directories(${PROJECT_NAME} PUBLIC ${MYSQL_CPPCONN_DIR}/include)
add_executable(${PROJECT_NAME} main.cpp)
# Static Libraries
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/libcrypto.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/libssl.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn8.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn8-static.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn-static.lib)
# Dynamic Link Libraries
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/libcrypto-1_1-x64.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/libssl-1_1-x64.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/mysqlcppconn-7-vs14.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/mysqlcppconn8-2-vs14.dll)
And i just include xdevapi.h header in my c++ source file like this:
#include <iostream>
#include <mysqlx/xdevapi.h>
using namespace std;
int main()
{
return 0;
}
And i run file in Release mode in clion and i receive these errors:
Error message i see in the clion console
====================[ Build | cpp_programming | Release ]=======================
"C:\Program Files\JetBrains\CLion 2019.3.2\bin\cmake\win\bin\cmake.exe" --build C:\Users\Kianoush\CLionProjects\cpp_programming\cmake-build-release --target cpp_programming -- -j 2
Scanning dependencies of target cpp_programming
[ 50%] Building CXX object CMakeFiles/cpp_programming.dir/main.cpp.obj
[100%] Linking CXX executable cpp_programming.exe
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x21): undefined reference to `mysqlx::abi2::r0::DbDoc::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x2c): undefined reference to `mysqlx::abi2::r0::common::Value::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r08internal14Warning_detail5printERSo[_ZNK6mysqlx4abi22r08internal14Warning_detail5printERSo]+0x87): undefined reference to `mysqlx::abi2::r0::string::Impl::to_utf8[abi:cxx11](mysqlx::abi2::r0::string const&)'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$_ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE[_ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE]+0x20): undefined reference to `mysqlx::abi2::r0::common::Value::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$.refptr._ZTVN6mysqlx4abi22r05DbDocE[.refptr._ZTVN6mysqlx4abi22r05DbDocE]+0x0): undefined reference to `vtable for mysqlx::abi2::r0::DbDoc'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\cpp_programming.dir\build.make:97: recipe for target 'cpp_programming.exe' failed
CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/cpp_programming.dir/all' failed
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/cpp_programming.dir/rule' failed
mingw32-make.exe[3]: *** [cpp_programming.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/cpp_programming.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/cpp_programming.dir/rule] Error 2
mingw32-make.exe: *** [cpp_programming] Error 2
Makefile:117: recipe for target 'cpp_programming' failed
Do i make mistakes in linking dll files or static files ?
What solution do you suggest ?
please help me, this take me in trouble for many days.
Full screen image
There are a couple of issues here.
You do not need to link all of these different libraries. You really only should require one mysqlcppconn library to be linked. To locate the library, try using find_library(), and use it for linking instead. Your CMake file should reduce to something like this:
cmake_minimum_required(VERSION 3.15)
project(cpp_programming)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(MYSQL_CPPCONN_DIR "C:/Program Files/MySQL/MySQL Connector C++ 8.0")
include_directories(${PROJECT_NAME} PUBLIC ${MYSQL_CPPCONN_DIR}/include)
add_executable(${PROJECT_NAME} main.cpp)
# Find the mysqlcppconn library.
find_library(mysqlcppconn_LIB
mysqlcppconn8
HINTS ${MYSQL_CPPCONN_DIR}/lib/vs14
# Static Libraries
target_link_libraries(${PROJECT_NAME} PUBLIC ${mysqlcppconn_LIB})
I'm not sure if you are using the ssl and crypto libraries, so add those back in if needed.
Your libraries (VisualC++) do not match the compiler (MinGW) you are using. To my knowledge, the MySQL Connector C++ downloads do not provide a MinGW set of libraries; they only provide libraries that are built with the Visual Studio compiler. Thus, you need to switch to use the VisualC++ compiler to use these libraries. Another option would be to download the MySQL source and try to build it with MinGW, but that may be more difficult.
Hope this helps!

Linking to libuv. Can't use vsbuild.bat version, own compilation links correctly

After sucessfully building libuv on windows in a mingw64 environment, I'm having a problems linking the libuv.dll/libuv.lib that are built as part of the vsbuild.bat build script.
When I build libuv by myself from the sources to produce either a .dll or .lib I can link without any issues.
The errors I get back when including the static or shared lib from the vsbuild.bat are related to undefined references e.g.:
[ 9%] Linking CXX shared library ..\buildcmake\bin\libuws.dll
CMakeFiles\uws.dir/objects.a(Group.cpp.obj): In function `uS::Async::start(void (*)(uS::Async*))':
D:/test/uWebSockets/git/src/Libuv.h:37: undefined reference to `uv_async_init'
CMakeFiles\uws.dir/objects.a(Group.cpp.obj): In function `uS::Async::close()':
D:/test/uWebSockets/git/src/Libuv.h:45: undefined reference to `uv_close'
...etc
The specific part of my cmake script that deals with the linking is:
find_library(LIBUV_STATIC_LIBRARY NAMES libuv.lib PATHS ${LIBUV_DEPS_DIR}/git/Debug ${LIBUV_DEPS_DIR}/git/Release PATH_SUFFIXES ${CMAKE_BUILD_TYPE}/lib NO_DEFAULT_PATH)
find_library(LIBUV_SHARED_LIBRARY NAMES libuv.dll PATHS ${LIBUV_DEPS_DIR}/git PATH_SUFFIXES .libs ${CMAKE_BUILD_TYPE} NO_DEFAULT_PATH)
MESSAGE(STATUS ".${LIBUV_STATIC_LIBRARY}")
MESSAGE(STATUS ".${LIBUV_SHARED_LIBRARY}")
include_directories(${UWS_DIR} ${LIBUVDIR_SRC} ${ZLIB_DIR_INCLUDE} ${LIBUVDIR_INCLUDE} ${OPENSSL_INCLUDE_DIR} )
add_library(uws SHARED ${UWS_SOURCES})
target_link_libraries(uws PUBLIC ${LIBUV_SHARED_LIBRARY} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
add_definitions(-D_WIN32_WINNT=0x0A00)
cmake output shows the libraries are found ok...
-- .D:/test/deps/libuv/git/Debug/lib/libuv.lib
-- .D:/test/deps/libuv/git/Debug/libuv.dll
Version of CMake is 3.9.something and I'm using nu-mingw with g++.

HDF5 error while compiling another library

I have compiled HDF5 following these steps:
untar hdf5-xxx.tar.gz
cd hdf5-xxx
make
make install
However, while I install another library (OpenGM), which request HDF5, I give the following arguments:
HDF5_CORE_LIBRARY /Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5
HDF5_CPP_LIBRARY /Users/Florian/Documents/THESE/hdf5-1.8.7/c++
HDF5_HL_LIBRARY /Users/Florian/Documents/THESE/hdf5-1.8.7/hl
HDF5_INCLUDE_DIR /Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5/include
HDF5_Z_LIBRARY /usr/lib/libz.dylib
After using CMake and generate, I get:
WARNING: Target "example-io" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only to libraries.
CMake is dropping the item.
WARNING: Target "example-io" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hl". Targets may link only to libraries.
CMake is dropping the item.
WARNING: Target "external-library-daoopt" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only
to libraries. CMake is dropping the item.
WARNING: Target "external-library-daoopt" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hl". Targets may link only to
libraries. CMake is dropping the item.
WARNING: Target "external-library-daoopt-shared" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may
link only to libraries. CMake is dropping the item.
WARNING: Target "external-library-daoopt-shared" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hl". Targets may link
only to libraries. CMake is dropping the item.
WARNING: Target "_opengmcore" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only to
libraries. CMake is dropping the item.
WARNING: Target "_opengmcore" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only to
libraries. CMake is dropping the item.
WARNING: Target "_opengmcore" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hl". Targets may link only to libraries.
CMake is dropping the item.
WARNING: Target "_hdf5" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only to libraries.
CMake is dropping the item.
WARNING: Target "_hdf5" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hl". Targets may link only to libraries. CMake
is dropping the item.
WARNING: Target "modelIO" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only to libraries.
CMake is dropping the item.
WARNING: Target "modelIO" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hl". Targets may link only to libraries.
CMake is dropping the item.
WARNING: Target "buildFoE" requests linking to directory "/Users/Florian/Documents/THESE/hdf5-1.8.7/hdf5". Targets may link only to libraries.
CMake is dropping the item.
As those are "just" warnings, I can compile my OpenGM library:
make
But I thus end up with the following error:
Undefined symbols for architecture x86_64:
"_H5Aclose", referenced from:
void marray::hdf5::save<unsigned long>(int const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, marray::Marray<unsigned long, std::__1::allocator<unsigned long> > const&) in io_graphical_model.cxx.o
void marray::hdf5::save<float>(int const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, marray::Marray<float, std::__1::allocator<unsigned long> > const&) in io_graphical_model.cxx.o
void marray::hdf5::save<double>(int const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, marray::Marray<double, std::__1::allocator<unsigned long> > const&) in io_graphical_model.cxx.o
void marray::hdf5::save<long>(int const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, marray::Marray<long, std::__1::allocator<unsigned long> > const&) in io_graphical_model.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)
As both warnings and the error deal with HDF5, I suppose the main problem comes from this library.
I am using MacOSX if it can help.
**EDIT:**Add the FindHDF5.cmake file
# - Find HDF5, a library for reading and writing self describing array data.
#
FIND_PATH(HDF5_INCLUDE_DIR hdf5.h)
FIND_LIBRARY(HDF5_CORE_LIBRARY NAMES hdf5dll hdf5 )
FIND_LIBRARY(HDF5_HL_LIBRARY NAMES hdf5_hldll hdf5_hl )
FIND_LIBRARY(HDF5_CPP_LIBRARY NAMES hdf5_cppdll hdf5_cpp )
IF(WIN32 AND HDF5_CORE_LIBRARY MATCHES "dll.lib$")
SET(HDF5_CFLAGS "-D_HDF5USEDLL_")
SET(HDF5_CPPFLAGS "-D_HDF5USEDLL_ -DHDF5CPP_USEDLL")
ELSE()
SET(HDF5_CFLAGS)
SET(HDF5_CPPFLAGS)
ENDIF()
SET(HDF5_VERSION_MAJOR 1)
SET(HDF5_VERSION_MINOR 8)
set(HDF5_SUFFICIENT_VERSION FALSE)
TRY_COMPILE(HDF5_SUFFICIENT_VERSION
${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}/checkHDF5version.c
COMPILE_DEFINITIONS "-I\"${HDF5_INCLUDE_DIR}\" -DMIN_MAJOR=${HDF5_VERSION_MAJOR} -DMIN_MINOR=${HDF5_VERSION_MINOR}")
if(HDF5_SUFFICIENT_VERSION)
MESSAGE(STATUS
"Checking HDF5 version (at least ${HDF5_VERSION_MAJOR}.${HDF5_VERSION_MINOR}): ok")
else()
MESSAGE( STATUS "HDF5: need at least version ${HDF5_VERSION_MAJOR}.${HDF5_VERSION_MINOR}" )
endif()
set(HDF5_USES_ZLIB FALSE)
TRY_COMPILE(HDF5_USES_ZLIB
${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}/checkHDF5usesCompression.c
COMPILE_DEFINITIONS "-I\"${HDF5_INCLUDE_DIR}\" -DH5_SOMETHING=H5_HAVE_FILTER_DEFLATE")
if(HDF5_USES_ZLIB)
FIND_LIBRARY(HDF5_Z_LIBRARY NAMES zlib1 zlib z )
set(HDF5_ZLIB_OK ${HDF5_Z_LIBRARY})
else()
set(HDF5_ZLIB_OK TRUE)
set(HDF5_Z_LIBRARY "")
endif()
set(HDF5_USES_SZLIB FALSE)
TRY_COMPILE(HDF5_USES_SZLIB
${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}/checkHDF5usesCompression.c
COMPILE_DEFINITIONS "-I\"${HDF5_INCLUDE_DIR}\" -DH5_SOMETHING=H5_HAVE_FILTER_SZIP")
if(HDF5_USES_SZLIB)
FIND_LIBRARY(HDF5_SZ_LIBRARY NAMES szlibdll sz )
set(HDF5_SZLIB_OK ${HDF5_SZ_LIBRARY})
else()
set(HDF5_SZLIB_OK TRUE)
set(HDF5_SZ_LIBRARY "")
endif()
# handle the QUIETLY and REQUIRED arguments and set HDF5_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(HDF5 DEFAULT_MSG HDF5_CORE_LIBRARY
HDF5_HL_LIBRARY HDF5_ZLIB_OK HDF5_SZLIB_OK HDF5_INCLUDE_DIR)
IF(HDF5_FOUND)
SET(HDF5_LIBRARIES ${HDF5_CORE_LIBRARY} ${HDF5_HL_LIBRARY} ${HDF5_Z_LIBRARY} ${HDF5_SZ_LIBRARY})
ELSE()
SET(HDF5_CORE_LIBRARY HDF5_CORE_LIBRARY-NOTFOUND)
SET(HDF5_HL_LIBRARY HDF5_HL_LIBRARY-NOTFOUND)
SET(HDF5_Z_LIBRARY HDF5_Z_LIBRARY-NOTFOUND)
SET(HDF5_SZ_LIBRARY HDF5_SZ_LIBRARY-NOTFOUND)
ENDIF(HDF5_FOUND)
The problem was solved by compiling the HDF5 library with the --with_cxx flag to build the C++ interface. In addition, I installed the HDF5 library in /usr/local so that it is automatically found when installing opengm.

CMake linking error (undefined reference to)

I am working with the SSL-Vision software. It has an example client that I've been trying to separate from the whole project. I found the sources needed to edit a client myself, so I just copied them from the software and used CMake to build my client.
The project structure below is simplified, narrowing to the issue (I believe!).
.
├── CMakeLists.txt
├── main.cc
├── build
│ ├── CMakeLists.txt
│ └── messages_ssl_... (.cc/.h, 4 each)
└── src
├── CMakeLists.txt
└── (Other subdirs and sources/headers)
./CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
project( TestClient )
find_package( PkgConfig REQUIRED )
pkg_check_modules( QTCORE_PKG QtCore )
include_directories( ${QTCORE_PKG_INCLUDE_DIRS} )
include(FindProtobuf)
find_package( Protobuf REQUIRED )
include_directories( ${PROTOBUF_INCLUDE_DIRS} )
find_package( PkgConfig REQUIRED )
pkg_check_modules( GLIB_PKG glib-2.0 )
include_directories( ${GLIB_PKG_INCLUDE_DIRS} )
include_directories( "src" )
add_subdirectory( src )
include_directories( "build" )
add_subdirectory( build )
add_executable( clientTest clientTest.cc )
target_link_libraries( clientTest robocup_ssl_client messages_robocup_ssl_detection.pb messages_robocup_ssl_geometry.pb messages_robocup_ssl_wrapper.pb messages_robocup_ssl_refbox_log.pb netraw robocup_ssl_client protobuf QtCore )
./build/CMakeLists.txt:
add_library( messages_robocup_ssl_detection.pb SHARED messages_robocup_ssl_detection.pb.cc )
add_library( messages_robocup_ssl_refbox_log.pb SHARED messages_robocup_ssl_refbox_log.pb.cc )
add_library( messages_robocup_ssl_geometry.pb SHARED messages_robocup_ssl_geometry.pb.cc )
add_library( messages_robocup_ssl_wrapper.pb SHARED messages_robocup_ssl_wrapper.pb.cc )
It could be a missing #include in the messages_ssl_... files, but they all are auto-generated and seems to be correct.
In messages_robocup_ssl_detection.pb.h and messages_robocup_ssl_detection.pb.h there are only protobuf includes.
In messages_robocup_ssl_refbox_log.pb.h:
#include "messages_robocup_ssl_detection.pb.h"
// Other protobuf includes
In messages_robocup_ssl_wrapper.h:
#include "messages_robocup_ssl_detection.pb.h"
#include "messages_robocup_ssl_geometry.pb.h"
// Other protobuf includes
In each .cc file is included only its header and other protobuf libs.
Finally, when I do make, the following error is generated:
Linking CXX executable clientTest
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::ByteSize() const'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::MergeFrom(SSL_GeometryData const&)'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `protobuf_AddDesc_messages_5frobocup_5fssl_5fgeometry_2eproto()'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::Clear()'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::SSL_GeometryData()'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::default_instance()'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::SerializeWithCachedSizesToArray(unsigned char*) const'
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)'
collect2: ld returned 1 exit status
make[2]: ** [clientTest] Erro 1
make[1]: ** [CMakeFiles/clientTest.dir/all] Erro 2
make: ** [all] Erro 2
I've been trying to fix this for some time.
Why is the libmessages_robocup_ssl_wrapper.pb.so showing errors if it has already been built before the linkage?
It could well be the linking order.
It looks like messages_robocup_ssl_wrapper.pb depends on messages_robocup_ssl_geometry.pb. If so, wrapper should come before geometry in the link line.
target_link_libraries( clientTest robocup_ssl_client
messages_robocup_ssl_detection.pb
messages_robocup_ssl_wrapper.pb
messages_robocup_ssl_geometry.pb
messages_robocup_ssl_refbox_log.pb
netraw
robocup_ssl_client
protobuf
QtCore )
Even better, let CMake take care of dependencies like this.
If you add...
target_link_libraries( messages_robocup_ssl_wrapper.pb
messages_robocup_ssl_geometry.pb )
then CMake will automatically retain that dependency when messages_robocup_ssl_wrapper.pb is specified as a dependency of another target. If you do this, then you can choose to omit messages_robocup_ssl_geometry.pb from the target_link_libraries( clientTest ... ) call.
Yet another reason to observe this error, maybe a less common one though, is that the ABIs are not compatible.
For instance, one of the library files could be built with the flag -D_GLIBCXX_USE_CXX11_ABI=0 while the project is not. This can be nasty to debug, especially when not being aware that this can be the problem.
I realize that this is not the issue in your specific scenario, but this answer might help other stumbling on it.
Another reason for undefined reference to ... can be a function marked as inline in a source file that is not a header. When optimization is enabled, the compiler can actually inline the function and skip generating the symbol leading to the error.
For this case, the solution is to either move inline functions to headers or remove the inline mark.