CMake: undefined reference when linking libraries to KDE4 lib - c++

at the moment I am trying to create a shared library using kde4_add_library. Actually it does not matter if it is add_library or kde4_add_library but it seems that add_library makes no sense since it cannot handle classes with "Q_OBJECT" macros/moc files?! Unfortunately compiling says "undefined reference" for many methods from classes of shared libraries in sub directories which are linked against the kde4 lib target.
The error messages look like:
./wc3lib/src/editor/editor.cpp:71: undefined reference to `wc3lib::editor::BlpCodec::startup()'
For finding the packages I use the following macros:
if (EDITOR)
find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
elseif (PLUGINS)
find_package(Qt4 COMPONENTS QtCore QtGui)
endif ()
if (${QT4_FOUND})
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
include_directories(${QT_INCLUDE_DIR})
endif ()
if (EDITOR)
find_package(KDE4 REQUIRED)
elseif (PLUGINS)
find_package(KDE4) # only for MPQ plugins
endif ()
if (${KDE4_FOUND})
include(KDE4Defaults)
add_definitions(${KDE4_DEFINITIONS})
include_directories(${KDE4_INCLUDE_DIR} ${KDE4_INCLUDES})
link_directories(${KDE4_LIB_DIR})
endif ()
find_package(OGRE COMPONENTS Paging Terrain REQUIRED)
if (${OGRE_FOUND})
include_directories(${OGRE_INCLUDE_DIRS})
link_directories(${OGRE_LIB_DIR})
endif ()
the sub directories are added after that:
if (BLP AND ${OGRE_FOUND})
add_subdirectory(Plugin_BlpCodec)
endif ()
if (MPQ AND ${KDE4_FOUND})
add_subdirectory(kio_mpq)
endif ()
if (BLP AND ${QT4_FOUND})
add_subdirectory(qblp)
endif ()
they contain targets without any KDE macros:
add_library(Plugin_BlpCodec SHARED ${wc3lib_EDITOR_PLUGIN_BLPCODEC_SRC})
target_link_libraries(Plugin_BlpCodec wc3libblp ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${GETTEXT_LIBRARIES})
now finally in the parent directory the KDE target is created:
kde4_add_library(wc3libeditor SHARED ${wc3lib_EDITOR_SRC} ${wc3lib_EDITOR_UI_H})
target_link_libraries(wc3libeditor ${wc3lib_CORE_LIBRARIES} ${GETTEXT_LIBRARIES} ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${QT_LIBRARIES} ${KDE4_KIO_LIBS} ${KDE4_KUTILS_LIBS} ${KDE4_KPARTS_LIBS} Plugin_BlpCodec qblp)
the CMake options like "EDITOR" are all enabled.
For the one linked library "qblp" I use some Qt stuff:
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
the other one simply uses "add_library" and has itself also system libs linked against it.
None of these dependencies fails to compile.
The methods are all defined.
I use
cmake_minimum_required(VERSION 2.8.4)
kdelibs-4.11.5
qtcore-4.8.5-r1
this is not the first time I have problems using Qt/KDE via CMake. Any help so far?
edit:
Note that "Target "wc3libeditor" has an INTERFACE_LINK_LIBRARIES property which
differs from its LINK_INTERFACE_LIBRARIES properties." appear for the wc3libeditor target. Is this related to the linking issues?

So the problem seems to be that
find_package(KDE4 REQUIRED)
adds various C++ flags. You can find all this in /usr/share/apps/cmake/modules/FindKDE4Internal.cmake
Some of these flags lead to the undefined reference errors.
A simple workaround might be adding
set(CMAKE_CXX_FLAGS "")
after the find_package statement which is kind of ugly.
More information can be found here:
http://lists.kde.org/?l=kde-buildsystem&m=132906487119016
and there is a better solution using the export macro:
https://forum.kde.org/viewtopic.php?f=64&t=89265
Another solution might be using KDE Frameworks (5) instead.
I've also created a bug report: https://bugs.kde.org/show_bug.cgi?id=338151

Related

Building and adding several libraries with CMake [duplicate]

This question already has answers here:
CMake rejects a second target_link_libraries talking about "keyword" vs "plain" [duplicate]
(1 answer)
Using SDL2 with CMake
(12 answers)
Closed 6 days ago.
I am CMake newbie and trying to use it within a project of mine in order to learn it
The project is a small game engine that use different external libraries such as GLFW, GLUT and SDL2. Some of them such as GL are in my os include directory and some of them such as SDL are inside my source tree (/vendors/SDL2).
I am trying to build the SDL2 library which is a few header files and link it to my project.
After some research I found out that the INTERFACE keyword should be used, this is how I am trying to do it :
add_library(SDL2 INTERFACE)
target_include_directories(SDL2 INTERFACE vendors/SDL2)
And at the end of my CMakeLists :
target_link_libraries(engine INTERFACE SDL2)
But the problem that I have is that I have also other libraries that I build the traditional way (without using the interface keyword) :
find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED)
find_package(GLUT REQUIRED)
find_package(GLEW REQUIRED)
set(LIBS_DIR ${OPENGL_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS})
set(LIBS ${OPENGL_LIBRARIES} ${GLFW_LIBRARIES} ${GLUT_LIBRARIES} ${GLEW_LIBRARIES} SDL2 STB_IMAGE)
target_include_directories(
engine PUBLIC
${LIBS_DIR}
)
target_link_libraries(engine ${LIBS})
Doing that I end up with the following error which I interpret as saying that only a target_link_libraries per project should be used.
The plain signature for target_link_libraries has already been used with the target "engine". All uses of target_link_libraries with a target must be either all-keyword or all-plain.
My question is : how can I link two types of libraries to my project ?
And is my way of building the SDL2 library correct ? I've seen other methods online but this one seemed the simplest one to me
Thanks a lot !
I have also tried to add the SDL2 library to my LIBS value :
set(LIBS ${OPENGL_LIBRARIES} ${GLFW_LIBRARIES} ${GLUT_LIBRARIES} ${GLEW_LIBRARIES} SDL2 STB_IMAGE)
and link it the normal way without using the keyword INTERFACE but I get undefined reference linker errors. In fact the methods that my engine use from the SDL2 libraries seem to be undefined so I guess that the library ha not been lined properly.

Why can't I import DLL library in C++?

I'm trying to load dynamic libraries in C++ with following codes
Handle = LoadLibrary(wstring2string(FullLibraryPath).c_str());
In the terminal of CLion, it was fine. The same to Git Bash.
But when I am testing in cmd.exe and powershell.exe.
The problem happened.
LoadLibrary() function returned a NULL value.
The error message is The specified module could not be found.
I thought it may be a problem with dynamic linking, so I tried to add -static -lpthread in the compile arguments.The CMakeList file just like
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
add_definitions("--static -lpthread -static-libgcc -static-libstdc++")
endif ()
add_library(io SHARED libio/library.cpp ${SRC_FILES})
add_library(string SHARED libstring/library.cpp ${SRC_FILES})
add_library(array SHARED libarray/library.cpp ${SRC_FILES})
add_library(thread SHARED libthread/library.cpp ${SRC_FILES})
add_library(fs SHARED libfs/library.cpp ${SRC_FILES})
add_library(sys SHARED libsys/library.cpp ${SRC_FILES})
Unfortunately, the problem still exists.
What's the cause of the problem? And, how can I fix it?
I've uploaded a example to my netdisk.
link
Thanks for Remy Lebeau's help. I've solve this problem with
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_SHARED_LINKER_FLAGS "-static")
endif ()
Just add it before add_library or add_executable in the CMakeFileLists of dynamic library.

Linking SFML static libs to project

Good morning! I'm moving from shared SFML libs to static. But I have a lot of errors: g++ couldn't find some libs. I used this tutorial :https://github.com/SFML/SFML/wiki/Tutorial%3A-Build-your-SFML-project-with-CMake . My CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(LastFail)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/libs/)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/libs/)
set(CMAKE_C_COMPILER_INIT g++)
add_definitions(-std=c++1y -w)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
find_package(SFML 2 REQUIRED system window graphics network audio)
include_directories(
include/
libs/include/
)
file(GLOB SRC
"src/*/*.cpp"
"src/*.cpp"
)
add_executable(LastFail ${SRC})
target_link_libraries(LastFail
${CMAKE_SOURCE_DIR}/libs/libjsoncpp.a
${CMAKE_SOURCE_DIR}/libs/libsfml-audio-s.a
${CMAKE_SOURCE_DIR}/libs/libsfml-graphics-s.a
${CMAKE_SOURCE_DIR}/libs/libsfml-network-s.a
${CMAKE_SOURCE_DIR}/libs/libsfml-system-s.a
${CMAKE_SOURCE_DIR}/libs/libsfml-window-s.a
)
set_target_properties(LastFail PROPERTIES
OUTPUT_NAME "LastFail"
CLEAN_DIRECT_OUTPUT 1
)
Small part of my errors:
JoystickImpl.cpp:(.text+0x1166): undefined reference to 'udev_device_get_syspath'
libs/libsfml-window-s.a(JoystickImpl.cpp.o): In function 'sf::priv::JoystickImpl::open(unsigned int)':
JoystickImpl.cpp:(.text+0x19ed): undefined reference to 'udev_device_new_from_syspath'
How do I fix that? I need to do that cross-platform way. Thanks!
Edit:
Of course, I have a directory called libs with all needed libraries.
First, packaging all dependencies with the project itself is generally a bad idea, but for game-like applications there could be exceptions.
In your case, the problem is not within packaged SFML, but libudev library. This library is
Linux-specific (not cross-platform)
Can't be linked statically (well, it probably could, but i bet it is a very bad idea, because library you linked in could be different version that udev daemon running on the host machine)
So, you need to add udev to your target_link_libraries() anyway.

Unable to link an executable to shared library

I have a cmake project where I am trying to link the executable to the shared library. But it is not getting linked. After searching enough and not finding any useful solutions, I'm posting my question here, please let me know if there are any obvious mistakes as I am not familiar with cmake
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# Set Project Name
set(PROJECT_NAME myproj)
project(${PROJECT_NAME})
# Tell Cmake to invoke gcc with specific flags. Use c++11 standard.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Include all headers
include_directories(${PROJECT_SOURCE_DIR}/../public/include)
# Driver Program
file(GLOB_RECURSE SOURCE_FILES
"${PROJECT_SOURCE_DIR}/src/*.cpp"
)
# Dont know what to do about this
#set( CMAKE_SKIP_BUILD_RPATH true)
link_directories(${CMAKE_SOURCE_DIR}/../relative/path/to/sharedlib) #contains libshared.so
# Generate Executable, trying to generate shared library to see if it generates # correct dependencies
# add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
#Link the libraries
target_link_libraries(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/../relative/path/to/sharedlib/libshared.so)
Here is the steps I have tried and some observations.
If I generate a shared library instead of an executable, it is able to find the dependent shared library(i.e libshared.so)
ldd myproj.so
libshared.so => full/path/to/sharedlib/libshared.so (0x00007fa26c263000)
I did not fully understand what it meant, but it is able to find the shared library is what I guessed.
If I try to generate an executable instead of shared library, I see undefined reference errors to the functions within the library.
I tried just target_link_libraries(${PROJECT_NAME} shared) as well and it gave same error.
Any clues as to how can I get the shared library linked to my executable? Thanks

How to compile QtGui example with OpenGL/Angle in CMake?

I am trying to take the Qt example from the Qt-distribution in examples/gui/openglwindow/ and make it compile/run with CMake on Windows. However, when compiling, it fails with a bunch of
“error LNK2019: unresolved external symbol __imp_glClear”
I can fix that by manually adding C:\Qt_install\lib\libGLESv2d.lib to the linker path, however, that’s obviously not how CMake should work.
My CMakeLists is very simple:
PROJECT( oglwin )
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 )
cmake_policy(SET CMP0020 NEW) # for Qt: auto-link to qtmain.lib
set(CMAKE_AUTOMOC ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
SET(SOURCE
main.cpp
openglwindow.cpp
)
SET(HEADERS
openglwindow.h
)
ADD_EXECUTABLE( oglwin ${SOURCE} ${HEADERS} )
TARGET_LINK_LIBRARIES( oglwin Qt5::Core Qt5::Gui )
Now as I mentioned before, my expectation would be that this automatically links to libGLESv2.lib (or libGLESv2d.lib), as I am using a Qt-build built with ANGLE.
(For that matter, I guess when on the desktop/opengl build, it should link to GL.lib [or whatever the system openGL lib is called]).
Possibly in my case, it should also link to C:\Qt_install\lib\libEGLd.lib.
There are a few related topics around, for example this:
https://bugreports.qt-project.org/browse/QTBUG-29132
(where it says “fixed”), and one can follow that to gitorious:
https://codereview.qt-project.org/#change,53857
So basically what should happen is that QtGui automatically links to its correct OpenGL back-end, whatever that may be (desktop OpenGL, Angle/GLESv2), it says in the bugreport there that it's able to deduce which back-end to use from the installed Qt distribution.
Apparently what I’m trying to do should work, but it doesn’t. Am I doing something wrong?
The solution was as follows:
It was coupled with a Qt bug that is now fixed, but it was also necessary to add ${Qt5Gui_EGL_LIBRARIES} and ${Qt5Gui_OPENGL_LIBRARIES} to target_link_libraries.
That makes Qt find the correct OpenGL dependency.