Qt Creator cannot find library with custom cmake step - c++

In Qt Creator (version 3.0.1, with Qt version 5.2.1), I have made a custom cmake step (instead of qmake), with the following CMakeLists.txt file:
cmake_minimum_required (VERSION 2.8)
add_executable (myapp source.cpp)
target_link_libraries(myapp dl)
In my source.cpp file, I have the following code:
#include <dlfcn.h>
int main()
{
dlopen("mylibrary.so", RTLD_NOW|RTLD_GLOBAL);
return 0;
}
And mylibrary.so is located in /usr/lib.
When I compile this using cmake and make from the command line, it compiles as expected. However, if I try to build this in Qt Creator, I receive the following error:
undefined reference to `dlopen'
This suggests that Qt Creator does not know where to look to find libdl.so, which is in /usr/lib/x86_64-linux-gnu.
So my question is: Why does running cmake and make from the command line work, whereas building in Qt Creator does not work? And how do I tell Qt Creator where to search for libdl.so?

First of all, you should use QLibrary in Qt software for dealing with dynamic loading, lookup and the like. You would also spare the hassle that you are seeing now.
Secondly, you can use this, but it is a bit hard-wiring things, admittedly:
target_link_libraries(myapp /usr/lib/x86_64-linux-gnu/libdl.so)
Thirdly, the even better approach would be to use some find module for this as follows:
# - Find libdl
# Find the native LIBDL includes and library
#
# LIBDL_INCLUDE_DIR - where to find dlfcn.h, etc.
# LIBDL_LIBRARIES - List of libraries when using libdl.
# LIBDL_FOUND - True if libdl found.
IF (LIBDL_INCLUDE_DIR)
# Already in cache, be silent
SET(LIBDL_FIND_QUIETLY TRUE)
ENDIF (LIBDL_INCLUDE_DIR)
FIND_PATH(LIBDL_INCLUDE_DIR dlfcn.h)
SET(LIBDL_NAMES dl libdl ltdl libltdl)
FIND_LIBRARY(LIBDL_LIBRARY NAMES ${LIBDL_NAMES} )
# handle the QUIETLY and REQUIRED arguments and set LIBDL_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibDL DEFAULT_MSG LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
IF(LIBDL_FOUND)
SET( LIBDL_LIBRARIES ${LIBDL_LIBRARY} )
ELSE(LIBDL_FOUND)
SET( LIBDL_LIBRARIES )
ENDIF(LIBDL_FOUND)
MARK_AS_ADVANCED( LIBDL_LIBRARY LIBDL_INCLUDE_DIR )
and then you can find it as follows given that you have it in your cmake module path:
find_package(LIBDL REQUIRED)

Related

CMake: How to compile with different library versions of Qt?

How do you get CMake to compile conditionally with Qt4.8 or Qt5?
In other words, if Qt5 is available then compile with Qt5.
Otherwise if Qt4.8 is available use that.
In my CMake, I have:
find_package(Qt5 COMPONENTS Core Gui Widgets...)
This works fine with my Qt5 builds, but how do I get the same software to build with Qt4.8?
I need something that contains the major version number, eg.:
find_package(Qt $QT_VERSION_MAJOR...)
or to use a condition, such as:
result = find_package(Qt 5...)
if (!result) then find_package(Qt4 ...)
or somehow detect the currently install Qt version.
The error I get for the machine with Qt4.8 installed is (unsurprisingly):
CMake Error at CMakeLists.txt:54 (find_package):
By not providing "FindQt5.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Qt5", but
CMake did not find one.
Could not find a package configuration file provided by "Qt5" with any of
the following names:
Qt5Config.cmake
What is the best approach here?
Automatically selecting an available version of Qt is fairly easy with the NAME option of the find_package command. The problem is that Qt4 and Qt5 have different names for the same modules.
# We first try to find the main module of Qt4, Qt5 or Qt6
find_package(QT NAMES Qt4 Qt5 Qt6 REQUIRED)
set(QT Qt${QT_VERSION_MAJOR})
# We prepare lists of modules and libraries for different
# versions of Qt
if (QT_VERSION_MAJOR EQUAL 4)
set(APP_QT_MODULES QtCore QtNetwork QtGui QtXml)
set(APP_QT_TARGETS Qt4::QtCore Qt4::QtNetwork Qt4::QtGui Qt4::QtXml)
else ()
set(APP_QT_MODULES Core Network PrintSupport Widgets Xml)
set(APP_QT_TARGETS ${QT}::Core ${QT}::Network ${QT}::PrintSupport ${QT}::Widgets ${QT}::Xml)
endif ()
# Here everything is simple - find the modules we need.
find_package(${QT} REQUIRED ${APP_QT_MODULES})
. . .
. . .
# And at last don't forget to add libraries.
add_executable(my_app app.cpp main.cpp window.cpp)
target_link_libraries(my_app ${APP_QT_TARGETS})
Another problem is that Qt functions have different names too, for example qt4_add_resources and qt5_add_resources. And this is a good reason to wonder whether or not you really need Qt4 support in your project.
Update
We can make Qt function aliases (as is done in Qt since version 5.15).
if (QT_VERSION VERSION_LESS 5.15)
macro(qt_wrap_cpp)
${QT}_wrap_cpp(${ARGV})
endmacro()
macro(qt_add_resources)
${QT}_add_resources(${ARGV})
endmacro()
macro(qt_generate_moc)
${QT}_generate_moc(${ARGV})
endmacro()
endif ()

CMake BUILD undefined reference (findpng)

I'm still very new to CMake so feedback is definitely welcome. So, I'm trying to build a simple application that should eventually create a pdf using the library libharu.
I think i figured it out how to link the library. But I still receive build errors for the findpng module (I suppose libharu depends on it)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) # current latest stable version (if lower give FATAL_ERROR)
project(pdf_generator VERSION 0.1.0) # name of the project, version.
file(GLOB TARGET_SRC "./src/*.cpp") # Creates variable, using globbing.
include_directories(${PROJECT_SOURCE_DIR}/include) # list of directories to be used as header search paths.
add_executable(main ${TARGET_SRC}) # Create an executable of set of source files [exe name files to bundle].
find_library(libhpdf_location NAMES libhpdf.a) # find the location of libhpdf.a and save the value in the variable libhpdf_location.
message(STATUS ${libhpdf_location}) # print status of variable.
add_library(libhpdf STATIC IMPORTED) # Add library via a static import.
set_target_properties(
libhpdf PROPERTIES
IMPORTED_LOCATION ${libhpdf_location}
)
target_link_libraries(main libhpdf)
I've never worked with that particular library before, but skimming their CMakeLists.txt on GitHub it seems like libharu has optional dependencies on libpdf and zlib. Without knowing how you built your version of libharu I'm going to assume that both are needed.
Luckily, CMake comes with find-modules for both libpng and zlib, so adding the following should work:
find_package(PNG REQUIRED)
find_package(ZLIB REQUIRED)
set_target_properties(libhpdf
PROPERTIES
INTERFACE_LINK_LIBRARIES "ZLIB::ZLIB;PNG::PNG"
)
Looks like all you need to do is tell cmake to link libpng.

Qt w/ Cmake: set(QT_USE_QTWEBKIT TRUE) not working

I'm attempting to build a Qt-based application using cmake (It's what Kdevelop gave me). I tried to use a QWebView;
QWebView *webView = new QWebView( this );
webView->load(QUrl("http://google.ca"));
But it failed with Undefined Reference errors...
undefined reference to `QWebView::QWebView(QWidget*)'
undefined reference to `QWebView::load(QUrl const&)'
I looked it up and I needed to add QTWEBKIT to my project, but all the solutions said to add it to my .pro file... And I'm not using .pro. In the QT documentation it said to add "set(QT_USE_QTWEBKIT TRUE)" to my CMAKE file, this is my CMakeLists.txt file now:
#-------------------------------------------------------------------------------
# Corrections Tool CMAKE list
#-------------------------------------------------------------------------------
project(corrections)
# Versioning Requirements
#-------------------------------------------------------------------------------
cmake_minimum_required(VERSION 2.6)
find_package(Qt4 REQUIRED)
# Include QT Librtaries
#-------------------------------------------------------------------------------
set(QT_USE_QTWEBKIT TRUE)
# Set Sources
#-------------------------------------------------------------------------------
set(corrections_SRCS corrections.cpp main.cpp utilities.cpp prettySplash.cpp)
#The Rest
#-------------------------------------------------------------------------------
include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
qt4_automoc(${corrections_SRCS})
add_executable(corrections ${corrections_SRCS})
target_link_libraries(corrections ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
install(TARGETS corrections RUNTIME DESTINATION bin)
But I'm still getting the errors, so either I did it wrong, in the wrong place, etc. I've also cleaned out and reconfigured my project several times making sure I wasn't using a bad generated makefile.
How would I either fix my cmake config to actually work, or convert my project to using .pro (with minimum stress & heartache)?
Thank you.
The canonical way to select Qt components in CMake is to specify the them in the find_package call and then to include ${QT_USE_FILE}
FIND_PACKAGE( Qt4 COMPONENTS QtWebKit REQUIRED )
INCLUDE( ${QT_USE_FILE} )
...
TARGET_LINK_LIBRARIES( corrections ${QT_LIBRARIES} )
This already configures the include directories and sets ${QT_LIBRARIES} to contain all relevant Qt libraries (i.e. your selected component and all Qt libraries it depends on).
So you don't need to manually add the libraries by listing them individually as you did in your example.
Edit:
Additional explaination:
The COMPONENTparameter to FIND_PACKAGE actually does the same as your manual call to set QT_USE_WEBKIT. But this variable is only evaluated/used in UseQt4.cmake which is included (and "executed") by the INCLUDEcommand. See CMake documentation of FindQt4 for details.
You do not appear to be linking against all of the Qt libraries. Use ${QT_LIBRARIES} instead of ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} in your target_link_libraries
target_link_libraries(corrections ${QT_LIBRARIES} )

cmake + sdl - disable sdlmain

I"m linking SDL with my application using cmake (winxp sp3, cmake 2.8.4).
cmake_minimum_required(VERSION 2.8)
find_package(SDL REQUIRED)
set(src WIN32 main.cpp)
include_directories(${QT_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR} ${SDL_INCLUDE_DIR})
add_executable(test ${src})
target_link_libraries(test ${SDL_LIBRARY})
Problem: SDL_LIBRARY contains SDLmain.lib, and I need to avoid linking with it (I already have one other library that contains main but isn't mentioned in this cmakelists.txt example).
I need to remove SDLmain entry from SDL_LIBRARY. This must be done without using hard-coded paths to the library - basically I need to keep using find_package to set up sdl-related variables, but I must ensure that SDLmain is not within SDL_LIBRARY. Also, I'm using cmake 2.8.4 which doesn't have string(FIND).
How can I do that?
Does that help?
FindSDL.cmake:
# This module responds to the the flag:
# SDL_BUILDING_LIBRARY
# If this is defined, then no SDL_main will be linked in because
# only applications need main().
# Otherwise, it is assumed you are building an application and this
# module will attempt to locate and set the the proper link flags
# as part of the returned SDL_LIBRARY variable.

Compiling error: "cannot find -lQtCore4"

Yesterday I downloaded the Qt4 Opensource library for linux. After running
./configure
./make
./make install
And inserting this into my .bashrc-file:
PATH=/usr/local/TrollTech/Qt-4.7.3/bin:$PATH
export PATH
After this, I ran cmake in order to produce a Makefile for me. CMakeLists.txt:
project(VTKToVTFx)
cmake_minimum_required(VERSION 2.6)
find_package(VTK REQUIRED)
find_package(Qt4 REQUIRED)
include(${VTK_USE_FILE})
include(${QT_USE_FILE})
SET(VTK_TO_VTFX_FORMS main.ui)
QT4_WRAP_UI(VTK_TO_VTFX_FORMS_UIC ${VTK_TO_VTFX_FORMS})
SET(MOC_HEADERS VTKToVTFx.h)
qt4_wrap_cpp(MOC_OUTFILES ${MOC_HEADERS})
SET(CPP_SOURCES VTKToVTFx.cpp
VTKPatch.cpp
VTKFile.cpp
VTKData.cpp
VTKDataHolder.cpp
)
add_executable(VTKToVTFx ${CPP_SOURCES} ${VTK_TO_VTFX_FORMS_UIC} ${MOC_OUTFILES})
# Adds folders for Visual Studio solution explorer (and for Xcode explorer)
source_group( "Generated" FILES ${MOC_FILES_CPP} ${VTK_TO_VTFX_FORMS_UIC} ${QRC_FILES_CPP} ${MOC_OUTFILES})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(VTKToVTFx vtkHybrid)
target_link_libraries(VTKToVTFx QtCore4)
target_link_libraries(VTKToVTFx QtGUI4)
This CMakeLists.txt works perfectly well on Windows, but when I try to compile the output on my installation of Ubuntu, this error occurs:
/usr/bin/ld: cannot find -lQtCore4
/usr/bin/ld: cannot find -lQtGUI4
Anyone who could point me to my problem here?
In the unix[like] world, the slash is the path seperator, not the backslash.
\usr\local\TrollTech\Qt-4.7.3\bin evaluates to usrlocalTrollTechQt-4.7.3bin.
edit: Also, your CMakeLists.txt seems a bit foul. Have a look at http://qtnode.net/wiki/Qt4_with_cmake . Instead of
target_link_libraries(VTKToVTFx QtCore4)
use something like (source is the linked site):
To add support for Qt4 libraries like network or qttest, you need to add both the include files and corresponding libraries. For example, to add support for the network and qttest libraries, you can use:
INCLUDE_DIRECTORIES(
${QT_INCLUDE_DIR}
${QT_QTNETWORK_INCLUDE_DIR}
${QT_QTTEST_INCLUDE_DIR}
)
TARGET_LINK_LIBRARIES(
${QT_LIBRARIES}
${QT_QTNETWORK_LIBRARIES}
${QT_QTTEST_LIBRARIES}
)
Even within the 4.x line of releases, libraries have been renamed and will be renamed. Fortunately there is no need for hardcodery :)