Library linking in C++/Qt distribution - c++

I am developing a project in C++11, and am not the biggest expert in distrubition, compiling, packaging, etc. I use
CMake 3.1.0
Qt 5.4 (community edition)
Moreover, I want the program to work on both OS X and Windows. Therefore, my IDEs include:
Apple Xcode 7
Microsoft Visual Studio 2013
I am having troubles with the Windows build. As of now, I am not able to copy the executables to another computer, since the DLL-files are not included. If I copy all the DLL-files that I receive errors from, it simply says the program was not able to run. I have read a bit about static library linking, but am unsure whether this is what I need.
My CMakeLists.txt looks like this:
set(libsources file1.cpp file2.cpp)
set(exec1sources file3.cpp file4.cpp)
set(exec2sources file5.cpp file6.cpp)
# some qt commands
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ..)
add_library(sharedlib ${libsources])
generate_export_header(sharedlib)
add_executable(exec1 ${exec1sources})
add_executable(exec2 ${exec2sources})
target_link_libraries(sharedlib Qt5::A Qt5::B)
target_link_libraries(exec1 Qt5::A Qt5::B sharedlib)
target_link_libraries(exec2 Qt5::A Qt5::C sharedlib)
install(TARGETS exec1 RUNTIME DESTINATION bin)
install(TARGETS exec2 RUNTIME DESTINATION bin)
As you can probably see, I want 2 executables, that each use some functionality from a shared library. And I want them working stand-alone.
I am likely not the first in the world to have this issue, but I was unable to find a similar thread on StackOverflow.

Have you tried windeployqt? It will automatically copy all dependencies for you application. You can find it in the bin-folder of your Qt-Kit
For Mac, there is a similar tool, called macdeployqt.

Related

How to make a lib before making the program in CMAKE?

I would like to be able to dynamically compile a library that will be used by my project before compiling my project.
I am setting up a Vulkan project in C++ (with Clion) and would like it to be multi-platforms, I am using GLFW3.3 to make that happen.
Instead of building my library for each platform and putting the libs and .h in a folder that will be linked through the CMakeLists.txt, I would like to be able to CMAKE+make the library, then put the lib and .h where they need to be and then start compiling my program that will be using those.
GLFW has a working CMakeLists.txt (I manage to make it manually through the console) but I don't know how to tell CMAKE to make it etc.
I am used to using CMake to define path to libs and includes but my last project what also multi-platforms and I didn't like the way I handled the library (build manually etc).
So I am looking for a way in CMake to do everything at once even if it will take time to do so but I have no idea how that works.
Take a look at how Glitter does it:
option(GLFW_BUILD_DOCS OFF)
option(GLFW_BUILD_EXAMPLES OFF)
option(GLFW_BUILD_TESTS OFF)
add_subdirectory(Glitter/Vendor/glfw)
target_link_libraries(${PROJECT_NAME} ... glfw)
They just include the CMakeLists.txt file that GLFW provides and depend on it for the main target.

What's the easiest way to build Adobe's XMP toolkit as a shared library with CMake on OSX?

I'm putting together a little project that's supposed to be cross-platform, built with CMake, and it needs to link with Adobe's XMP toolkit (libxmp). Ideally I'd like CMake to be responsible for building the dependencies, including libxmp, in one fell swoop.
Unfortunately the XMP toolkit is designed to be built with XCode on OSX and CMake on Linux. The CMake build process doesn't appear to work out of the box on OSX.
What's the minimal change I can make to the XMP toolkit to get it to build with CMake on OSX? Should I just keep hacking away at it until it works, or is this a known/solved problem? And, more generally, what additions should I make to my own CMakeLists.txt file to integrate this project with my own?
I've learnt a few things today and several misconceptions have apparently evaporated.
After fulfilling the third-party dependency requirements (expat and zlib; this is just a matter of extracting files from source tarballs into a designated location), this was pretty easy once I realised that XCode can be leveraged here from the commandline, and that XMP's own "build system" has sufficient tools to do everything I need.
In short, from the build directory:
./cmake.command 64 Dynamic WarningAsError ToolchainLLVM.cmake
cd xcode/dynamic/intel_64
xcodebuild -scheme ALL_BUILD build
Then, the framework files are found under public/libraries/macintosh/intel_64/Debug, and the includes were already available under public/include.
After some liberal symlinking, in my own project's CMakeLists.txt it's just a matter of:
target_compile_definitions(myProject
PUBLIC
MAC_ENV
)
target_include_directories(
myProject
PRIVATE
include/libxmp
)
# Add build dir to path for finding frameworks (libmxp)
set_target_properties(
myProject
PROPERTIES
LINK_FLAGS "-Wl,-F${CMAKE_BINARY_DIR}/Frameworks"
)
target_link_libraries(
myProject
PRIVATE
catch
"-framework XMPCore"
"-framework XMPFiles"
)
It surely could be finessed, but this does otherwise "just work".
If you are using the XMP Toolkit 2016.07 (and, at time of writing, there is no newer version) and have Xcode 10+ & Mojave, you will need to put together a few patches before you build:
Xcode version detect fix
stdlib config fix
Map/pair type alias fixes
Furthermore, if you use expat 2.2.2 or newer:
Define HAVE_ARC4RANDOM_BUF or XML_POOR_ENTROPY at the top of expat's xmlparse.c (because the libxmp build system won't do this for you)

Enabling curses in both Linux and Windows

I am working on small project in C++ and I am using curses for user interface. I am pretty nicely able to make it work in my arch-linux installation, because it is pretty simple to set up ncurses to work there. But with my cmake setting which is working nicely at Linux I am not able to properly make it work at Windows.
Here is my CMakeList.txt
cmake_minimum_required(VERSION 3.9)
project(fighting_pit)
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
set(CMAKE_CXX_STANDARD 11)
include_directories( ./include)
include_directories( ./src)
add_executable(fighting_pit
include/Arena.h
include/cursor.h
include/Player.h
include/spell.h
include/Turns.h
include/weapon.h
include/Draw.h
src/Arena.cpp
src/cursor.cpp
src/Player.cpp
src/spell.cpp
src/Turns.cpp
src/weapon.cpp
src/Draw.cpp
main.cpp )
target_link_libraries(fighting_pit ${CURSES_LIBRARIES})
I tried several approaches to make it work on Windows too.
1. Downloading sources
I tried to build pdcurses with mingw32-make. It created pdcurses.a I added it to same location as project, but it still shows it cannot find curses library.
2. Downloading via mingw32-get
I used installation manager from mingw and let it download both .dll and dev package of libpdcurses. Just trying to run cmake through clion showed it is still not found. So I copied it both into windows32 and project folder but it still didn't help.
I don't know what I should do. Unfortunately I am neither C++ user neither Windows user.
I needed to build a cross-platform project that uses ncurses on Linux and MacOS but uses pdcurses on Windows. Some variant of curses is usually installed on popular distributions of Linux. ncurses is also available on MacOS as well. The same isn't quite true for Windows. My solution was to download the pdcurses sources and write a cmake script for building it on Windows. if (WIN32 or MSVC) build pdcurses else() find ncurses. You might also want to create a proxy header that #includes pdcurses or ncurses depending on the platform.
After cloning the GitHub repo, I copied the headers in ., the C files in ./pdcurses, the sources in ./wincon into a new directory in my project. Then I wrote a CMakeLists.txt file to compile all of these files into a library. It looked something like this:
cmake_minimum_required(VERSION 3.2)
add_library(PDcurses
# all of the sources
addch.c
addchstr.c
addstr.c
attr.c
beep.c
# ...
)
target_include_directories(PDcurses
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
My main CMakeLists.txt file compiled the pdcurses sources if the target is windows.
if(WIN32 OR MSVC)
add_subdirectory(pdcurses)
target_link_libraries(MyTarget
PRIVATE
PDcurses
)
else()
# find ncurses and use that
endif()
PDCurses seems to be a (more or less) drop-in replacement for ncurses in most situations. I was able to compile the example programs that came with PDcurses on my Mac using curses without any troubles.

CMake on Windows 10 doesn't generate executable

So I have a tiny C++ project that I code on both Windows 10 and Ubuntu 16.04, and I'm using CMake to coordinate relatively platform-independent build processes. I'm no master of CMake, but it worked up until recently, however now I cannot get the solution generated by CMake-gui to actually compile into an executable to run, despite my usage of add_executable. Here is my CMakeLists (there's a hideous mix of platform-specific stuff in there, however it appears that CMake simply ignores it):
cmake_minimum_required(VERSION 3.10)
set (CMAKE_CXX_STANDARD 17)
project (TestProject)
include_directories(C:/include/CImg-2.2.2)
ADD_LIBRARY(LibsModule Game.cpp Game.h TestGame.cpp TestGame.h)
target_link_libraries(LibsModule -lpthread)
target_link_libraries(LibsModule -lm)
target_link_libraries(LibsModule -lX11)
add_executable(TestProject TestGame.h)
target_link_libraries(TestProject LibsModule)
This compiles and runs fine on Ubuntu using CLion, however on 64-bit Windows 10 using VS17 it fails upon trying to run the executable it expects to be generated because the executable doesn't exist in the build folder (but the .lib file noted is generated just fine).
I've seen some mention that a third party antivirus program could cause this, but I have no such thing installed.
Now I'm pretty new to CMake so if this file is completely off the mark I would really appreciate a clear explanation as to what I'm doing wrong, this code is made from a short study of basic CMake usage.

Linking gtest based application on windows: visual studio and cmake

For linux I used the following cmake rules to build and link an executable that runs unit tests for my library (bt_lib):
set(TEST_EXECUTABLE unit_tests)
include_directories(
$ENV{GMOCK_ROOT}/include
$ENV{GMOCK_ROOT}
$ENV{GMOCK_ROOT}/gtest
$ENV{GMOCK_ROOT}/gtest/include
)
add_executable(${TEST_EXECUTABLE} test1.cpp ../${PROJECT_H})
target_link_libraries(${TEST_EXECUTABLE}
bt_lib
gtest
gtest_main
pthread
gmock
)
CMake generates visual studio project files and I can build my library and gmock/gtest without problems. But the actual test requires pthread which is not available on windows.
Can I have a check which OS I am configuring for and link $TEST_EXECUTABLE to something else than pthread if I am on Windows? If so, how?
I must add that I am a beginner in most things c++ on windows so even fairly trivial things would need an explanation. I think that using visual studio is they way I want to go though (not something like http://www.mingw.org/).
Basically, pthread do not exist natively in windows, as it is a POSIX specification. If your code has pthread_create and the like functions, you need a port of pthreads for windows, e.g:
http://www.sourceware.org/pthreads-win32/
http://web.cs.du.edu/~sturtevant/w13-sys/InstallingpthreadsforVisualStudio.pdf
When you download and install the pthread port, you should specificy typically the INCLUDE and LINK directories:
IF (WIN32)
INCLUDE_DIRECTORIES(your_path_to_pthreads_includes)
LINK_DIRECTORIES(your_path_to_pthreads_lib)
ELSE(WIN32)