Boost-Build: Building windows executable from linux - c++

I have a c++ codebase that I need to build both windows and unix versions of. It is important that the windows executable work without cygwin or similar installed. Oh, and I'm trying to achieve this from ubuntu.
I've been trying to figure out how to make boost-build take care of it, but have so far come up short.. For simplicity assume this project structure:
root/
|- src/
| |- core/
| | |- number.cpp
| | |- number.hpp
| |- main.cpp
|- jamroot
In an attempt to make boost-build produce windows binaries as a first step, I create a user-config.jam file in my home directory containing the following:
using gcc : 4.4 : i586-mingw32msvc-g++ : <rc>i586-mingw32msvc-windres <archiver>i586-mingw32msvc-ar ;
My jamroot file looks like this:
exe hello :
[ glob-tree *.cpp ]
: : <target-os>windows
;
But when I run bjam I get a unix executable (no extension) but not a windows executable. Renaming the application with a .exe extension and running on windows does not work. I tried various options for bjam, like bjam --toolset=gcc --target-os=windows, bjam --toolset=gcc-mingw --target-os=windows etc. but noting seems to work..
For the record, mingw is properly installed and working.. Calling the compiler manually produces correct output files.
Any ideas?
Also, how do I get bjam to build a version for each toolset listed in my user-config.jam file?
Bonus question:
Eventually, I need to link against one boost library and one custom prebuilt library. How would I go about specifying different libraries for the different target systems?
UPDATE I downloaded the script from http://mingw-cross-env.nongnu.org/ which allowed me to compile a mingw as well as boost libraries in one go, so that problem is taken care of.. I found a way to make bjam call the mingw compiler (I am at a different computer so I cannot provide the solution at this time).. The other questions are still not resolved.

Unfortunately I don't think this can be done (I've failed many times) and I think the reason is because mingw is not suppported for compiling Boost. The only way people seem to have accomplished this is to maintain a separate build environment under win32 using MS Visual Studio.
From your question it's unclear if you're using bjam to build your application, or if you're just trying to build Windows versions of the Boost libraries (.lib or .dll files) to link with your application later. In my attempts I have tried to do this the 'usual' way, in that Windows versions of the Boost libraries are compiled, then the app is compiled separately with mingw32 and linked with Boost.
Unfortunately my stumbling block so far is that I can only get two outcomes - either the build fails when compiling Boost into Win32 dynamic libraries (.dll), or win32 static libraries are successfully built, but then libtool refuses to link them in with the app.
Have a look at the PKGBUILD file that Arch Linux uses to compile mingw32-boost as you might get some hints from how they do it. It seems that bjam threadapi=win32 target-os=windows is enough. Don't forget to set your prefix correctly though, so you don't overwrite your native libraries with win32 versions!

On my ubuntu box, it is as simple as
sudo apt-get install mingw
and then build
export CC=i586-mingw32msvc-gcc
make
Profit!

Related

How to build Crypto++ library on Linux with MinGW?

im trying to port a c++ project from visual studio 2013 to netbeans on ubuntu. The target is a windows executable, so far im able to compile windows exe files from netbeans using mingw as compiler.
The project needs the Crypto++ library and i only have the .lib version for visual studio. To include the library in netbeans i first need to build the Crypto++ library in the .a format.
Its not clear to me how should i do that.
Ive found informations on how to build the library for linux with mingw but not for cross compilation with mingw. The provided GNUmakefile does not work.
Should i set up a vm with windows and mingw and compile the library that way? Or maybe use the qmake "hack" as suggested here http://www.qtcentre.org/threads/28809-Compiling-amp-using-Crypto-with-mingw-version-of-Qt ? The last good Crypto++ version suggested there is quite old. This is confusing, porting the whole project is easier than having the required library.
Im open to any suggestion.
tldr: how to build libcryptopp.a on linux for the cross compilation of a windows exe project
edit:
for example if i cross compile something there are windows libraries in the /usr/i686-w64-mingw32/lib/ folder like libuser32.a. i need to make the equivalend libcryptopp.a.. sorry if is a bit unclear.
if i simply build using the steps in answer (and in the wiki) i end up with a libcryptopp.a file but i suspect is linux-only, cause if i link that library in netbeans in the .exe file im cross compiling i end up with undefined references to cryptopp stuff everywere. the paths are correct, i suspect the library needs to be replaced with the equivalent libcryptopp.a compatible with crosscompiling.
edit2: im trying to follow the answer down here, now im stuck here. after this command to build cryptopp.
make CXX=/usr/bin/i686-w64-mingw32-gcc INCLUDES="-I /usr/i686-w64-mingw32/include" LIBS="-L /usr/i686-w64-mingw32/lib" CXXFLAGS="-std=c++0x"
and many variations of it i always end up with this error
trap.h:26:25: fatal error: Windows.h: No such file or directory
# include
which makes me think its using the right compiler to make a .a lib file for cross compiling the windows .exe with the lib.
however i dont understand whats going on now with the missing header..:(
Also if i try to link the lib file (used with visual studio) i get a lot of linking errors, undefined reference to cryptopp stuff.
ill offer a symbolic beer (a couple of $ of Bitcoins) if someone finds out how to do it.
Inspired by http://wiki.amule.org/wiki/Cross-compilation_for_windows_with_mingw:
sudo apt-get install mingw-w64
git clone https://github.com/weidai11/cryptopp
cd cryptopp
export TARGET=i686-w64-mingw32
CXX=$TARGET-g++ RANLIB=$TARGET-ranlib AR=$TARGET-ar LDLIBS=-lws2_32 make -f GNUmakefile
I've found informations on how to build the library for linux with mingw but not for cross compilation with mingw.
Its relatively easy...
Get Crypto++ ZIP into MinGW.
Unpack Crypto++ ZIP.
Change directories.
Build the library.
Verify All tests passed.
(1) and (2) can be tricky because Cygwin and MinGW are missing a lot of tools. So curl https://www.cryptopp.com/cryptopp563.zip -o cryptopp563.zip may not work.
For (2), I seem to recall ZIP is missing, so unzip -aoq cryptopp563.zip -d cryptopp-5.6.3 may not work.
At step (4), just perform make static dynamic test and be sure it finished with All tests passed.
I do a lot of testing with Cygwin and MinGW. I have a script that copies Crypto++ into the environments from my Desktop. I have not been able to figure out a way to automate it. A recent question on automating it was closed, so no one can supply an answer (see How to automate software testing for Cygwin and MinGW).

Building libtorrent with openssl with BJam

I am trying to build libtorrent (http://www.libtorrent.org/) using the provided jamfile. If I try to build it in its vanilla state everything goes well. I am then building using this command:
bjam msvc-12.0 boost=source
However I want to build it with OpenSSL which there seem to be support for. This is where I run into problems. Most likely because it is the first time I use Bjam (actually anything else than make files). I now try to run the following command:
bjam msvc-12.0 boost=source encryption=openssl
Now the compiler starts to complain about not finding the OpenSSL include files.
So I guess I have to include this path in the JAM file. But I have no idea where.
I also tried to add the path into the INCLUDE environment varaible in windows but that doesn't seem to be picked up by BJAM or msvc. Any suggestions?
My understanding of how this is normally done on windows is by installing libraries and headers into visual studio's include and lib folders.
(That's how I install openssl on windows at least).
The jamfile is also supposed to pick up CXXFLAGS and LDFLAGS environment variables, which you could use to introduce the library- and include paths. However, it only does this when boost=system is specified, i.e. you're building against "system" boost libraries instead of from source.

How to configure Qt Creator to use Boost in Windows

I created a Qt project in Ubuntu and everything went smoothly. However, I also need deploy it on Windows. It uses Boost libraries(the big problem).
I've been searching for hours to find a solution, but didn't have luck. I tried to install Boost libraries and link it with mingw; I think I missed something. Here is what I did and downloading the lastest version:
1) ran .\bootstrap
2) then .\b2 --prefix=C:\boost install
Sadly didn't install correctly. I got only 2 folder(bin and share) but no headers.
However, here (http://nuwen.net/) I found a bundle(Mingw+Boost and other libraries). This has everything I need.
Now I think the issue is .pro file, because I have a lot of undefined references. Here is .pro file with everything I tried (some commented):
http://pastebin.com/pBFMTAd8
Your help is appreciated!
I did solve the problem myself. And here is how I did it. First of all, it is required to have boost library compiled with same compiler you're using with Qt.
If you're using msvc, then you're lucky because Boost guys did you a favour and compiled libraries for you. You can download them here: http://sourceforge.net/projects/boost/files/boost-binaries/ .
If you're using mingw (which does come in bundle with Qt), you can do this:
add mingw compiler to Windows PATH variable:
~ go to control panel and search for System;
~ add mingw's path(e.g. C:\Qt\Tools\mingw\bin) to PATH variable by appending ';' to your path(e.g.: ";C:\Qt\Tools\mingw\bin")
compile Boost libraries:
~ unzip boost archive
~ open a Command Line window, go in the unzipped boost folder, then go in folder tools/build/v2/engine
~ you have you build installer with mingw toolset: .\build --toolset=mingw
~ this will create 2 files in folder bin.ntx86 or something similar; copy the files bjam and b2 in the unzipped boost folder;
~ now go in boost folder and start build it: .\b2 --toolset=mingw --build-type=complete stage (there is good tutorial to install it along with eclipse : http://theseekersquill.wordpress.com/2010/08/24/howto-boost-mingw/)
note: this gonna take few hours, so may want to watch a movie or what ever you want to do meanwhile. However you have the option to speed up things a little bit by adding another argument to the build command: -j N, where N is how many cores your processor have.
when build has finished, you can now link the library in Qt. To do this you need to modify .pro file. First you'll have to tell Qt where are headers are located, and you do so by adding:
INCLUDEPATH += path_to_boost_folder, e.g. : INCLUDEPATH += C:/boost_1_54_0
~ also if you're using libraries which requires link, for example system and filesystem you have to link them separately:
LIBS += "C:/boost_1_54_0/stage/lib/libboost_filesystem-mgw48-1_54.a",
LIBS += "C:/boost_1_54_0/stage/lib/libboost_system-mgw48-1_54.a"
after modifying the .pro file, run qmake, then rebuild.
Hope this works for you too!
Update: The folder hierarchy has change. For building the library, one should read the documentation associated with each version and Boost.Build's documentation.
Building the library from the root folder is easier (Building Boost 1.52 with MinGW):
C:\boost_1_60_0> bootstrap.bat mingw
C:\boost_1_60_0> .\b2 --toolset=gcc -j N --build-type=complete
building boost will not put the headers, the headers are for the developer when he creates new code. The installed dirs are the binaries for distribution.
see http://www.boost.org/doc/libs/1_54_0/more/getting_started/windows.html#prepare-to-use-a-boost-library-binary
this will install libraries, that you use at runtime (not compile time). Because you add this bin folder to your path and that is why when runing an app build with boost it will run and not say "could not find xxx.dll"

How to create simple Boost.Build make file containing links to libs I use on Windows and Linux?

main.cpp which should be executable C++ app. It shall depend on
Lib1 be a required to be compiled first (before main.cpp) project-lib (with lib1.h and lib1.cpp inside some separate folders)
'Lib2.lib' with its dependency given precompiled libs (like cross-platform OpenCV for example)
I need it to work for Windows and Linux and if possible Mac OS
found for windows: look here - "Common tasks" page 26
exe hello : hello.cpp some_library.lib /some_project//library
: <threading>multi
;
I hoped for better - more readable syntax form Boost creators... And BTW
What the hell on earth does
On Windows, if an application uses
shared libraries, and both the
application and the libraries are
built using Boost.Build, it is not
possible to immediately run the
application, because the PATH
environment variable should include
the path to the libraries. It means
you have to either add the paths
manually, or have the build place the
application and the libraries into the
same directory.
mean? I can not have a project with 2 nested project - one for .lib and one for app using that .lib?
With this I see how to connect 1 .lib but how to connect a folder with them? And how to connect includes? And when I'll go to Linux what shall be changed?
How should my bjam make/config file look like?
It sounds like you want a framework which works on a cross-platform(Multiple operating system) scenario.
Simplest option would be to install cygwin and create a standard makefile for linux. Compile in a cygwin environment to generate the windows equivalent.
You will save substantial time in creating the makefile.
Another option is mksnt.

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.