CMake linking error (undefined reference to) - cmake

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.

Related

Copy compilation/linking settings from project in CMake object library?

I'm in a similar situation to Adding object-file dependencies where it is mentioned:
... I need some object files that are part of the same library to be compiled before others.
Don't try to declare dependencies between object files. If there are files that have a dependency, break them out into a separate library with add_library and then declare the dependency with add_dependencies and target_link_libraries. There is no extra cost for doing this. Particularly, consider looking at Object Libraries.
I tried to implement this in my original project, where I'm working with a massive CMakeLists.txt file, where include & linker paths may be conditionally inserted or removed, and I failed. In essence, that CMakeLists.txt file would looks like this simplified:
project(MY_PROGRAM C CXX ASM)
set(MY_PROGRAM_sources
main.c
file_one.c
file_two.c
)
add_executable(MY_PROGRAM ${MY_PROGRAM_sources})
target_include_directories(MY_PROGRAM PRIVATE
${CUSTOM_PATH}/src/custom/include
...
)
add_compile_options(-Wall
-Wno-format
...
)
target_link_libraries(MY_PROGRAM
somelib1
somelib2
)
This builds fine, using Unix Makefiles.
Now, I've tried to extract file_one and file_two objects like this:
project(MY_PROGRAM C CXX ASM)
set(MY_PROGRAM_sources
main.c
#file_one.c
#file_two.c
$<TARGET_OBJECTS:SEPFILE_OBJS>
)
add_library(SEPFILE_OBJS OBJECT
file_one.c
file_two.c
)
add_executable(MY_PROGRAM ${MY_PROGRAM_sources})
target_include_directories(MY_PROGRAM PRIVATE
${CUSTOM_PATH}/src/custom/include
...
)
add_compile_options(-Wall
-Wno-format
...
)
target_link_libraries(MY_PROGRAM
somelib1
somelib2
)
cmake passes fine here, but when I hit make, there is breakage as soon as file_one.c starts compiling:
...
[ 9%] Building C object CMakeFiles/SEPFILE_OBJS.dir/file_one.c.obj
In file included from C:/tmp/file_one.c:14:
C:/tmp/file_one.h:19:10: fatal error: ExoticHeader.h: No such file or directory
19 | #include <ExoticHeader.h>
Clearly, the SEPFILE_OBJS library did not inherit the include libraries nor other compilation/linker settings from the MY_PROGRAM executable.
I could probably repeat all target_* lines for SEPFILE_OBJS - but that looks quite unmanageable, plus my original CMakeLists.txt is huge, and I'd like to avoid that kind of work.
So is there a way to say to CMake "keep the same compilation and linker settings as in executable for MY_PROGRAM, also for the object library SEPFILE_OBJS"?
I would do it the way around. I would first define a library section, including file_one.c and file_two.c, and then a main executable section, which would link against this library target.
I would also follow something along the lines below for a directory structure (ideally, I would put the source files within a src directory):
/ MY_PROGRAM
|- include
| \- MY_PROGRAM
| |- file_one.h
| \- fine_two.h
|- file_one.c
|- file_two.c
|- main.c
\- CMakeLists.txt
Put your header files in an include/${PROJECT_NAME} folder, and set an include_dir var pointing to it.
set(include_dir ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME})
Define the list of library and application sources:
set(lib_sources
"${CMAKE_CURRENT_SOURCE_DIR}/file_one.c"
"${CMAKE_CURRENT_SOURCE_DIR}/file_two.c"
)
set(app_sources
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
)
Library section. Define a lib_MY_PROGRAM target, and set the include directories, compile options, and link libraries for it. Notice it's better to use the target_... specific commands than the more general ones, such as add_compile_options:
add_library(lib_${PROJECT_NAME} ${lib_sources})
target_include_directories(lib_${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${include_dir}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_include_directories(lib_${PROJECT_NAME} SYSTEM PUBLIC
${CUSTOM_PATH}/src/custom/include
)
target_compile_options(lib_${PROJECT_NAME} PRIVATE
-Wall
-Wno-format
)
target_link_libraries(lib_${PROJECT_NAME} PRIVATE
somelib1
somelib2
)
Main binary section:
add_executable(${PROJECT_NAME} ${app_sources})
target_include_directories(${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${include_dir}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_compile_options(lib_${PROJECT_NAME} PRIVATE
-Wall
-Wno-format
)
target_link_libraries(${PROJECT_NAME} PRIVATE lib_${PROJECT_NAME})

Wrong SDL_config.h when building SDL2 with cmake

I have been trying to add SDL2 to my project using CMake.
My CMakeLists.txt looks like this.
...
include_directories(
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/test
${PROJECT_SOURCE_DIR}/external
${PROJECT_SOURCE_DIR}/external/KHR
${PROJECT_SOURCE_DIR}/external/glm
${PROJECT_SOURCE_DIR}/external/nvToolsExt
${PROJECT_SOURCE_DIR}/external/stb_image
${PROJECT_SOURCE_DIR}/external/SDL2/include
${PROJECT_SOURCE_DIR}/external/assimp/include
)
# Setup dependencies
link_directories(
${PROJECT_SOURCE_DIR}/external/SDL2/lib/x64
${PROJECT_SOURCE_DIR}/external/assimp/lib
)
# Glad
add_subdirectory(external/glad)
# ImGui
add_subdirectory(external/imgui)
# Assimp
add_subdirectory(external/assimp ${EXECUTABLE_OUTPUT_PATH}/external/assimp)
# SDL2
add_subdirectory(external/SDL2 ${EXECUTABLE_OUTPUT_PATH}/external/SDL2)
# Setup build
set(TARGET_NAME sre)
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${TARGET_NAME})
add_executable(${TARGET_NAME} ${SRC_FILES})
set_target_properties(sre PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
)
target_link_libraries(
${TARGET_NAME}
opengl32
SDL2Main
SDL2
glad
imgui
assimp
)
It generates the VS solution correctly but when I build it I get the following error from SDL2:
external\sdl2\include\sdl_config.h(52): fatal error C1189: #error: Wrong SDL_config.h, check your include path?
As a result, my build fails. I'm kind of a noob using cmake so any sort of advice is welcome.

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 with a custom external library in 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

CMAKE - resolving dependencies between libraries in project

I am using CMAKE to build a quite large project consisting of many libraries and executables. There is something wrong with how I specify library-library dependencies, and things do not work fully as wanted. Schematically my project looks like this:
CMakeLists.txt
lib1/src/CMakeLists.txt
lib2/src/CMakeLists.txt
app/src/CMakeLists.txt
I.e. I have two libraries lib1 and lib2 where lib2 depends on lib1 and app depends on both lib1 and lib2. I build libraries using both shared and static linking:
add_library(lib1_static STATIC lib1_src)
add_library(lib1_shared SHARED lib1_src)
set_target_properties( lib1_static PROPERTIES OUTPUT_NAME lib1)
set_target_properties( lib1_shared PROPERTIES OUTPUT_NAME lib2)
To ensure that the dependies are satisfied I have target_link_libraries() as:
#lib2/src/CMakeLists.txt:
target_link_libraries( lib2_shared lib1_shared )
target_link_libraries( lib2_static lib1_static )
And for the app:
#app/src/CMakeLists.txt
target_link_libraries( app_static lib2_static ) # <- No explicit dependance on lib1
target_link_libraries( app_shared lib2_shared )
Now - the problem is that when I make a fresh build it compiles for quite a long time, but when creating the liblib2.so file the error message:
make[2]: *** No rule to make target 'lib1/src/liblib1.so' needed by 'lib2/src/liblib2.so'. Stop.
appears. If I then just issue a new make command - things will build successfully. So it seems I have not managed to configure the dependencies correctly? Note that the make output from the first build attempt shows:
Linking C shared library liblib1.so
So the build itself has suceeded - but it seems like the build will not use the liblib1.s0 file created during this build instance to resolve the lib2 dependencies?
I have tried - and removed again - several varietes of link_directories() and target_depends() without success.
It seems, CMake got confused by usage of
set_target_properties( lib1_static PROPERTIES OUTPUT_NAME lib1)
Try this:
target_link_libraries( lib2_shared lib1 )
or remove these property settings.
I was using CMake version 2.6 - I upgraded to CMake 2.8 and then it worked for me.