Use framework in static library - macos

I have a library which is being generated as .a file (to be statically linked). There I want to include Qt framework (QtCore.framework) since I am on OSX. Is that possible? How could I do it using cmake?
My attempt:
In CMakeLists.txt I have
FIND_LIBRARY(QTCORE_LIBRARY NAMES QtCore
HINTS "${CMAKE_SOURCE_DIR}/osx/frameworks")
Then I print variable ${QTCORE_LIBRARY} and it gives right path.
Then in src/CMakeLists.txt (where my sources are) I link the library
TARGET_LINK_LIBRARIES(libname $${QTCORE_LIBRARY})
However when I launch the compilation it complains because it does not find
fatal error: 'QtGlobal' file not found
I have checked and QtCore.framework contains QtGlobal header
EDIT: In case someone has same problem I found solution.
I needed to add "${QTCORE_LIBRARY}/Headers" in my project include directories
Thanks in advance and regards

Why don't using the CMake "config.cmake" provided by Qt5 ?
something like:
# Qt Setting
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
...
target_link_libraries(libname Qt5::Core Qt5::Gui Qt5::Widgets)
CMake can find and use [...] Qt5 libraries. [...] Qt5 libraries are found using “Config-file Packages” shipped with Qt5
src: https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html
In order for find_package to be successful, Qt 5 must be found below the CMAKE_PREFIX_PATH, or the Qt5_DIR must be set in the CMake cache to the location of the Qt5WidgetsConfig.cmake file. The easiest way to use CMake is to set the CMAKE_PREFIX_PATH environment variable to the install prefix of Qt 5.
src: http://doc.qt.io/qt-5/cmake-manual.html

Related

Linking SFML within CMake, compiling from sources

I'm trying to include SFML as a dependency in my CMake project, and it compiles SFML fine, but I can't figure out how to link it.
Here's my CMakeLists.txt, with annotated comments:
cmake_minimum_required(VERSION 3.9.1)
set(CMAKE_LEGACY_CYGWIN_WIN32 1)
set (CMAKE_CXX_STANDARD 11) # Set C++11
project(CHIP8)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) # static library
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) # dynamic library
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) # executables
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/modules" ${CMAKE_MODULE_PATH})
# Include SFML
add_subdirectory(${CMAKE_SOURCE_DIR}/dep/SFML)
include_directories(${CMAKE_SOURCE_DIR}/dep/SFML/include)
#Include where to find headers
include_directories(./src)
include_directories(./src/headers)
# Do a GLOB search, and add them to executable
set(EXECUTABLE_NAME "CHIP8")
file(GLOB SRC_FILES
"src/headers/*.h"
"src/*.cpp"
)
add_executable(${EXECUTABLE_NAME} ${SRC_FILES})
target_link_libraries(${EXECUTABLE_NAME} SFML) #Here is where the problem lies!
As you can see, I'm adding the subdirectory ./dep/SFML so it compiles with its own CMakeLists. Including the headers too on the next line, which VSCode picks up.
However, I'm having trouble on the last line: target_link_libraries. It can't find sfml SFML or SFML2. Therefore, I'm not sure how to link it.
Anyone have any idea?
Thanks.
SFML is not a single library, but a set of libraries, each of which corresponds to some component. For component named
<component-name>
the library target is named
sfml-<component-name>
When use SFML in your code, you should know which SFML component(s) you use (see SFML docs/tutorials), and link with corresponded libraries:
# Assuming you use "graphics" and "system" SFML components
target_link_libraries(<your-executable> sfml-graphics sfml-system)
Note, that such targets' naming is not officially documented, so it can be changed in the future.
Preferred way for link with SFML is to install it before (or during) configuring your project, and use
find_package(SFML REQUIRED COMPONENTS graphics system)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(<your-executable> ${SFML_LIBRARIES})

Add libraries Qt and LuaJIT / Lua51 with CMake

I am trying to use CMake with Qt and LuaJIT that will run on Visual Studio 2012. I managed somehow to run Qt, but i don't know how to add LuaJIT library to project. I am using source of LuaJIT cloned from http://luajit.org/git/luajit-2.0.git, which is build by running .bat file.
I dont care that LuaJIT will be build by CMake, i just need to link library and add headers to project.
I removed lib folder from my project... Is not worth troubles to have dependancies coupled with project whitout cmake file :D
My project hierarchy is:
+lib
-luajit-2.0
+src
-my sources
+ui
-ui files
-CMakeLists.txt
And CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 2.8.12)
set(PROJECT "Grapedit")
project(${PROJECT})
# Qt Stuff
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets REQUIRED)
set(SOURCE_FILES
src/main.cpp
src/mainwindow.h
src/mainwindow.cpp
)
set(UI_FILES
ui/mainwindow.ui
)
source_group("UI Files" FILES ${UI_FILES})
qt5_wrap_ui(UI_HEADERS ${UI_FILES})
source_group("Generated UI Headers" FILES ${UI_HEADERS})
add_executable(${PROJECT} ${SOURCE_FILES} ${UI_HEADERS} ${UI_FILES})
qt5_use_modules(${PROJECT} Widgets)
My solution
So it is finally working and I made couple of newbie mistakes... :)
I will write them down for others:
didn't know what is find module... This will search environment and set up locations of libraries or flag that it didn't find them. Since LuaJIT is compatible with Lua51 you can use find_package(Lua51).
Your libraries must be some way visible to CMake. On Windows simplest way is to add them to PATH variable. Or you can add path of your libraries to CMake variable CMAKE_PREFIX_PATH. Open find module, for example FindLua51.cmake and you will see how must be your library organized. On windows I've must installed LuaJIT manualy - created LuaJIT folder and I've put *.h files to include subfolder, *.dll to bin subfolder and *.lib to lib subfolder. Then add bin folder to PATH and set LUA_DIR to LuaJIT folder.
use include_directories on include folder
then you must link libraries target_link_libraries, but after add_executable!
My CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8.12)
# Declare project variables...
set (PROJECT "Grapedit")
set (
SOURCE_FILES
src/main.cpp
src/mainwindow.h
src/mainwindow.cpp
)
set(UI_FILES
ui/mainwindow.ui
)
# Set project name
project(${PROJECT})
# Include Lua directories
include_directories(${LUA_INCLUDE_DIR})
# Qt Stuff
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
# Find packages...
# Will find also LuaJIT, but must be named same as Lua51 and installed into directories
find_package(Lua51)
# Find Qt modules, every module separately
find_package(Qt5Widgets REQUIRED)
# Create nice groups in IDEs
source_group("UI Files" FILES ${UI_FILES})
source_group("Generated UI Headers" FILES ${UI_HEADERS})
# Use Qt UI files
qt5_wrap_ui(UI_HEADERS ${UI_FILES})
# Create executable
add_executable (
${PROJECT}
${SOURCE_FILES}
${UI_HEADERS}
${UI_FILES}
)
# Link libraries...
# Must be after executable is created!
# Link Qt modules
qt5_use_modules (
${PROJECT}
Widgets
)
# Link Lua
target_link_libraries(${PROJECT} ${LUA_LIBRARIES})
# Will not show new windows prompt when running program
if (MSVC)
set_target_properties(${PROJECT} PROPERTIES
WIN32_EXECUTABLE YES
LINK_FLAGS "/ENTRY:mainCRTStartup"
)
endif ()
You are missing the actual linkage which you can amend with the following statement:
target_link_libraries(${PROJECT} luajit-5.1)
For sure, it would be even better if this lua jit could have a cmake find module, or config/version file depending on its exact build system.
You could grab the find module from here:
https://github.com/brimworks/lua-zlib/blob/master/cmake/Modules/FindLuaJIT.cmake
Then you could link against it as follows:
target_link_libraries(${PROJECT} ${LUA_LIBRARIES})
You can see that it would become more dynamic this way rather than hard-coding the exact name. The details for figuring out that would be left with the find module.
Note that you would probably need to use the corresponding variables for the header inclusion then as follows:
include_directories(${LUA_INCLUDE_DIR})
This will take care of automatically finding the include directory, respectively, without you hard-coding it.
You would also need to add the following line into your CMakeLists.txt:
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
and you need to place the downloaded find module into a "cmake" subfolder.
Please refer to the following page for further details about this topic in general:
CMake:How To Find Libraries

CMake: wrong zlib found - how to build zlib from src (with main project CMakeLists.txt) and link it?

// brief version
How can I make CMake to use my supplied zlib (which it also has to build from source) instead of the one found by the finder without breaking the finder for other libs (OpenGL)?
ZLib needs to be used by the main project and also libPNG which comes as source as well.
Primary target platform is Windows.
// longer version:
In my project I need to link against libpng, zlib and OpenGL. With libpng being dependent on zlib. But zlib is also required by the main project.
I need to supply sourcecode for all libs except OpenGL, and build those libraries along with
the main project to assert linking the correct version and simplify building on Windows.
I found ways to do all this with custom libraries where no built-in finder exists, but I can't override the finder properly for just zlib. If I change the search path for libs, then OpenGL is not found.
However I can't get cmake to use my supplied zlib instead of a rouge zlib.DLL that the package finder finds somewhere in my system. (The one from tortoise git)
I tried to set ZLIB_LIBRARY to a specific filepath, but that only works on MinGW, and I also think this is not the way to do it.
(And also I had to explicitly link to png16_static instead of just libpng, for an inexplicable reason.)
Any help on this is much appreciated. Maybe I'm taking this on the wrong way?
Target&Development Platform:
Windows7
Visual Studio 2010
and MinGW (both need to work)
My (simplified example) CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project (MyProject)
find_package(OpenGL)
add_executable(MyProject main.cpp)
include_directories(${INCLUDE_DIRECTORIES} "${PROJECT_BINARY_DIR}")
include_directories(${INCLUDE_DIRECTORIES} "external_libs/lpng162")
include_directories(${INCLUDE_DIRECTORIES} "external_libs/zlib-1.2.8")
include_directories(${INCLUDE_DIRECTORIES} "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8")
add_subdirectory("external_libs/zlib-1.2.8")
link_directories(${LINK_DIRECTORIES} "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8")
# libpng will not build correctly if this not set
set (ZLIB_ROOT "${PROJECT_SOURCE_DIR}/external_libs/zlib-1.2.8")
# manually set this to prevent cmake from finding the tortiose-git zlib.dll first
# DOES NOT WORK CORRECTLY, only with mingw32
set (ZLIB_LIBRARY "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8/libzlib.dll")
add_subdirectory("external_libs/lpng162")
TARGET_LINK_LIBRARIES(MyProject png16_static zlib ${OPENGL_LIBRARY})
Project (simplified example) structure:
./main.cpp
./CMakeLists.txt
./external_libs/zlib-1.2.8/ <- contains respective source
./external_libs/lpng162/ <- contains respective source
Third-party libraries most likely call FindZLIB.cmake to determine the location of CMake. You already had the right idea by setting the ZLIB_LIBRARY manually, but were not quite getting it right:
add_subdirectory(<path_to_zlib_src_dir>)
set(ZLIB_INCLUDE_DIR "<path_to_zlib_src_dir>" "${CMAKE_BINARY_DIR}/<path_to_zlib_build_dir>")
set(ZLIB_LIBRARY zlib)
add_subdirectory(<path_to_lpng_src_dir>)
The include directory needs to contain both src and build path as zconf.h is build by CMake
The library name is only the CMake-target name, not the complete path to the resulting file.
On Windows dlls are not automatically copied by CMake. You might want to add some additional code to make sure that the zlib and lpng dlls end up in the right place.
You can call find_package(zlib) yourself to make sure it behaves as expected
In the rare case that a third-party lib does not use the find script, you will have to dig into that project's CMakeLists to find out what is going on

linking libraries in qt creator for c++ project

I am creating normal c++ project using QT creator .
I need to link the boost library. I have used this in eclipse project under Project Properties/C C++ build/Gcc C++ linker/-l boost_filesystem but i am not sure how to do it in QT creator.
I use Qt, but not Qt-Creator so I'm not sure where in it's UI you might do this.
But in the .pro file (the input to the makefile), you would specify the library with:
LIBS += -lboost_filesystem # assuming 'boost_filesystem' is the name of the lib file
LIBS += -L/[wherever boost lib files are on your system]
"-l" is the file name and "-L" is the library path name.
LIBS += -lboost_filesystem -L/[wherever boost lib files are on your system]
works too.
"+=" appends it to the current QMake variables, be careful about using "=", unless you really intend to replace the values.
I don't know, if this is still an issue for you, but I answer because it may help some others like me who had a similar issue.
As far as I understood it: When you use QtCreator with normal C++ you will be asked which build tool to use. I have chosen CMake, so from now on everything goes via CMake and less things go directly via QtCreator. That's the reason that there is no .pro file anymore.
So what I did to resolve the issue was to add following line after the add_executable(...) line in the CMakeLists.txt file:
target_link_libraries(my_project_name -lboost_system)
Note: I just needed lboost_system, but I think that just expanding the list with -lboost_filesystem etc.. will do the job.
Hope that it helps somebody.

Why doesn't Xcode recognize my LIBRARY_SEARCH_PATHS?

I've set LIBRARY_SEARCH_PATHS to /opt/local/lib, and verified that the library in question is there (I'm linking to GLEW):
$ls /opt/local/lib
libGLEW.1.5.1.dylib libfreetype.a libz.a
libGLEW.1.5.dylib libfreetype.dylib libz.dylib
libGLEW.a libfreetype.la pkgconfig
libGLEW.dylib libz.1.2.3.dylib
libfreetype.6.dylib libz.1.dylib
but Xcode gives me the linker error
library not found for -lGLEW
I'm generating the Xcode project with CMake, so I don't want to explicitly modify the Xcode project (if someone suggests adding it as a framework, or something like that). Xcode recognizes USER_HEADER_SEARCH_PATHS fine (as in this question); why doesn't it work here?
Perhaps adding something like this to your CMakeLists.txt?
find_library(GLEW_LIB GLEW /opt/local/lib)
if(NOT ${GLEW_LIB})
message(FATAL_ERROR "Could not find GLEW")
endif()
target_link_libraries(myprogram ${GLEW_LIB} ...)
Where myprogram is the name of the target executable that needs to link with the library. You would replace the ... with the other libraries you are using on that executable.
This way CMake would handle the library path details for you.
Xcode works on potentially multiple SDK's, so whenever your define these kinds of things (like HEADER_SEARCH_PATHS or LIBRARY_SEARCH_PATHS) the current SDK root is prepended to the actual path that's getting passed to the linker.
So, one way to make this work would be to add your directory to the SDK. For example, assuming you're building with the Mac OS X 10.5 sdk, you could add your opt dir:
ln -s /opt /Developer/SDKs/MacOSX10.5.sdk/opt
Your library would now be found on your system.
If you don't want to do this, then you will have to look at CMake and find out how to get it to generate a library requirement for your actual library (I don't know anything about CMake, so I can't help you there). This is also why you see a difference between USER_HEADER_SEARCH_PATHS and HEADER_SEARCH_PATHS re your other question.
As another option, you could also specify this path with the OTHER_LDFLAGS build variable:
OTHER_LDFLAGS=-L/opt/local/lib
This would cause the linker to search /opt/local/lib as well as its standard paths and wouldn't require you to generate a different project file.

Resources