Linking gtest based application on windows: visual studio and cmake - c++

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)

Related

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.

Library linking in C++/Qt distribution

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.

Windows package-manager for C++ libraries

I've been working on various open-source projects, which involve the following C++ libraries (& others):
MuPDF
Boost
FreeType
GTKmm
hummus PDF libraries
LibTiff
LibXML2
Wt xpdf
xpdf
Poppler
ZLib
It often takes a long time to configure these libraries, when setting them up on a clean machine. Is there a way to automate the grabbing of all dependencies on a windows machine?
The closest I've found is CMake, which checks to make sure you have the dependencies installed/extracted before generating your project files. But I haven't found anything for Windows which can parse the list of dependencies and then download+install the required versions.
Please recommend a package manager for Windows with up-to-date C++ libraries.
Vcpkg, a Microsoft open source project, helps you get C and C++ libraries on Windows.
Take a look at the Hunter package manager when you already use CMake to setup your project. It automatically downloads and builds your dependencies whith only a few lines of extra cmake code. Hunter is based on cmake export and import targets.
For example if you want to use the GoogleTest library in your cmake based project you would add the following lines to your root CMakeLists.txt
# file root CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
# To get hunter you need to download and include a single cmake file
# see documentation for correct name
include("../gate.cmake")
project(download-gtest)
# set the location of all your hunter-packages
set( HUNTER_ROOT_DIR C:/CppLibraries/HunterLibraries )
# This call automaticall downloads and compiles gtest the first time
# cmake is executed. The library is then cached in the HUNTER_ROOT_DIR
hunter_add_package(GTest)
# Now the GTest library can be found and linked to by your own project
find_package(GTest CONFIG REQUIRED)
add_executable(foo foo.cpp)
target_link_libraries(foo GTest::main)
Not all the libraries you list are available as "hunter-packages" but the project is open source so you can create hunter-packages for your dependencies and commit them to the project. Here is a list of libraries that are already available as hunter packages.
This will not solve all your problems out of the box because you have to create hunter-packages for your dependencies. But the existing framework already does a lot of the work and it is better to use that instead of having a half-assed selfmade solution.
Biicode is a new dependency manager for C++. It also has a few libraries that you listed. Biicode automatically scans your source files for dependencies, downloads and builds them. See here for a very cool example that includes Freeglut.
What I've found:
Closest thing to what I'm looking for:
NuGET
Unfortunately it doesn't have any of the libraries I require in its repository.
So I ended getting most of the libraries from the KDE4windows project and custom building the rest.
Npackd is a package manager for Windows. There is a default repository for C++ libraries and also a third party repository for Visual Studio 2010 64 bit libraries. Boost and zlib are already in the default repository. If you decide to use Npackd, you could file an issue if you need other libraries.
Windows does not have a package manager. Go to the libraries' website and download the Windows builds if they provide any.
There are some alternatives, but not without drawbacks:
Cygwin: provides a nice package manager, but all binaries are built for Cygwin, which means they run slower than their native equivalent, any apps using them will link to the Cygwin DLL, and you're stuck with that license. Also the use of the native Win32 API is sometimes troublesome due to incompatibility with the POSIX emulation offered. Only for GCC.
MinGW-get: is a package manager for the MinGW.org compiler. These are native Win32 binaries, but only for use with MinGW's GCC.
There is no package manager or slightly equivalent thing for anything Visual Studio or MinGW-w64 related.
There is no package management on Windows. On Windows developers typically use full-blown everything-and-the-kitchen-sink development environments and produce monolithic applications themselves, shipped with all dependencies.

My program can not find the boost library

I tried to write code that was a sample of the Boost test library:
#include <boost/unit_test.hpp>
BOOST_AUTO_TEST_CASE(test)
{
BOOST_CHECK(true);
}
I built the source code, and I got the execution file test.exe. I tried to execute that file, but I got an error message.
The program can't start because boost_unit_test_framework-vc80-mt-1_44.dll is missing from your computer. Try reinstalling the program to fix this problem.
But, I have ready that file on my boost library directory.
What's the problem in this case?
Background:
For my build environment, I use Windows 7 Ultimate x64, and Visual Studio 2005.
So I built boost library by my self, and I got all the libraries for the 64-bit computing system.
Using bjam, and I use the command: bjam --toolset=mvsc-8.0 address-model=64 threading=multi --build-system=complete install on 64-bit command prompt window.
After the build, I set the boost library and header directory in Visual Studio directory path option.
Thank you all!
Make sure that the path to your DLL is included in the "PATH" environment variable. (Or include the DLL in your exe directory if you like). That way the DLL will be found.
You can also choose to use the static versions of the Boost libraries.
Build or download the static libraries and point Visual Studio at those instead. The Boost code will be built into your application (increasing its size some) and you will not need a DLL.
If using CMake to configure your application, you can tell CMake to use the static versions of the Boost libraries using Boost_USE_STATIC_LIBS:
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost ... )
This way, the DLLs will not be required, as the requisite Boost definitions will be built into your application via the static libraries.

How do you compile static pthread-win32 lib for x64?

It looks like some work has been done to make pthread-win32 work with x64, but there are no build instructions. I have tried simly building with the Visual Studio x64 Cross Tools Command Prompt, but when I try to link to the lib from an x64 application, it can't see any of the function exports. It seems like it is still compiling the lib as x86 or something.
I've even tried adding /MACHINE to the makefile in the appropriate places, but it doesn't help. Has anyone gotten this to work?
You can use the vcpkg here. Which is the Windows package manager for C++.
It supports pthread building and also other open source libraries.
I wanted to use a static pthread library.
When i downloaded the pthread i got the dll(pthread.dll) and import lib(pthread.lib) i.e I can not use only pthread.lib I had to use the pthread.dll file.
So using vcpkg I have built the static lib. Which I can use without any dll dependencies
Using "vcpkg" you can build both Static and Dynamic Libraries
You can use below steps
Below i have added the steps for all DLL (x86|x64) and LIB (x86|x64) cases. You can build it as per your need.
Clone the vcpkg from git directory vcpkg git repo
From the directory where you have cloned vcpkg run below command- Which will install the vcpkg
bootstrap - vcpkg.bat
Check for the library availability by running below commands
vcpkg search pthread
Which will show you below result
mbedtls[pthreads] Multi-threading support
pthread 3.0.0 empty package, linking to other port
pthreads 3.0.0-6 pthreads for windows
As you can see it supports pthread for windows
1 .Building Dynamic Library with import lib (DLL)
Building x86 DLL
vcpkg install pthreads:x86-windows
Which will build the dll and import library in .\vcpkg\installed\x86-windows from
here copy the lib and include and you can use them
Building x64 DLL
vcpkg install pthreads:x64-windows
Which will build the dll and import library in .\vcpkg\installed\x64-windows from
here copy the lib and include folders.
2. Building Static Library (LIB)
Building x86 LIB
vcpkg install pthreads:x86-windows-static
Which will build the dll and import library in .\vcpkg\installed\x86-windows-static
from here copy the lib and include and you can use them
Building x64 LIB
vcpkg install pthreads:x64-windows-static
Which will build the dll and import library in .\vcpkg\installed\x64-windows-static
from here copy the lib and include folders.
NOTE : Try to use with admin privileges
For me, I just use a 64-bit windows compiler (mingw-w64 cross compiler in this particular case) then make (with2.9.1) like:
$ make clean GC-static
Then how I install it for use (some of this may not be needed, of course),
cp libpthreadGC2.a $mingw_w64_x86_64_prefix/lib/libpthread.a
cp pthread.h sched.h semaphore.h $mingw_w64_x86_64_prefix/include
then to use it, you have to define this (example ffmpeg configure line to use it):
--extra-cflags=-DPTW32_STATIC_LIB
Anyhow that's one way.
Another way is to do the same then modify the *.h files and remove all references to dllexport from the headers (or manually define DPTW32_STATIC_LIB in the headers).
ex:
sed 's/ __declspec (dllexport)//g;s/ __declspec (dllimport)//g'
(ref: zeranoe build scripts)
Until it's officially released, it looks like you have to check out the CVS head to get version 2.9 of the library. Version 2.9 has all the x64 patches, but you will still have problems if you try to compile the static library from the command line.
The only workaround I know of is to use the DLLs instead of statically linking the LIB.
Here's how I did it (VS2015). Should work for older Visual Studios too.
1) Download the release .zip from SourceForge
2) Unpack to a clean folder- should see "pthreads.2"
3) Open up your Visual Studio command prompt, navigate to "pthreads.2."
4) Run "nmake", no arguments. It produces a help message listing all the legal commands you can give 'nmake' to build it. For more info, see "pthreads.2\FAQ" file which explains their 3 different flavors of 'cleanup' handling.
I would suggest building "VC" and "VC-debug" (and maybe the static ones of those) only. The 'real' pthreads is a C system library on POSIX platforms like Linux, so only those combos are going to give you the exact same C error behavior on Windows that you'd get on Linux, FreeBSD, etc.
to expand kgriffs answer one has to do two more things to actually build a 64bit DLL and not 32bit DLL.
First download latest pthreads via CVS (as suggested here)
1) use 64bit build tools - achieved by loading correct VC environment settings in command line (more about it here):
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat amd64
(change the 11.0 to whatever version you are using)
2) As it is written in the pthreads Makefile:
TARGET_CPU is an environment variable set by Visual Studio Command Prompt
as provided by the SDK (VS 2010 Express plus SDK 7.1)
PLATFORM is an environment variable that may be set in the VS 2013 Express x64 cross
development environment
which means, that if it was not done by the vcvars (in my case it wasn't) you need to set TARGET_CPU or PLATFORM (just in case I set them both):
set TARGET_CPU=x64
set PLATFORM=x64
3) and now the final step:
nmake clean VC
nmake clean VC-debug
this will make a 64bit DLL files (and proper import library and PDB). I can verify that it works with Visual Studio 2012.
This message might help.
I was successful in replacing "pthread-win32" with "pthreads4w" https://sourceforge.net/projects/pthreads4w/ and compiling in MSVC2019 for x64 target using the console nmake command. Even statically link.