In boost build, how to set compiler options conditionally? - boost-build

Is there a way (without modifying source files) to specify that I want to build boost with, say, msvc with one set of additional options in debug and another in release variants? In some config.jam or even better on command line? Like
using msvc : : <compileflags>-DRELEASE_DEFINES; - only if variant=release
using msvc : : <compileflags>-DDEBUG_DEFINES; - only if variant=debug
using msvc : : <compileflags>-DLL_SPECIFIC_STUFF; - only if link=shared
I was able to find a suggestion to use command line like variant=debug/somefeature=somevalue but that doesn't work.

Well, after some experimentation I was able to make it work through project-config.jam, here's a sample:
import option ;
import toolset ;
using msvc ;
toolset.flags msvc.compile CFLAGS <variant>release : "/GL /arch:SSE2 /fp:fast" : unchecked ;
toolset.flags msvc.compile CFLAGS <variant>debug : "/RTCc /RTC1 /GS" : unchecked ;
toolset.flags msvc.archive AROPTIONS <variant>release/<link>static : "/LTCG" : unchecked ;
toolset.flags msvc.link LINKFLAGS <variant>release/<link>shared : "/LTCG /OPT:REF /OPT:ICF" : unchecked ;
toolset.flags msvc.link LINKFLAGS <link>shared : "/PDB:c:\\Lib\\boost\\stage\\lib\\" : unchecked ;
option.set keep-going : false ;

Related

Adding OR-Tools Library to Visual Studio

I am trying to write a code using Google's OR-Tools library on Microsoft Visual Studio 2019. I followed the following steps:
Installed OR-Tools from Binary on Windows on their website.
Extracted the .zip file in C:\Libraries
Wrote my code on VS (I wrote #include <ortools/linear_solver/linear_solver.h> and using namespace operations_research; rest is usual C++ Code)
In Visual Studio, went to Project > Properties > C/C++ > Additional Include Directories
Added "C:\Libraries\or-tools\include" (which contains the folder "ortools" that I included)
Clicked Apply then OK then compiled my code.
I am getting a bunch of linking errors "error LINK2019". Is there anything else I should do so I can use this library freely on my machine?
From the supplied makefile:
Compile flags:
DEBUG = /O2 -DNDEBUG
CXXFLAGS = /std:c++17 /EHsc /MD /nologo /D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS -nologo $(DEBUG) \
/DPSAPI_VERSION=1 /D__WIN32__ /DNOMINMAX /DWIN32_LEAN_AND_MEAN=1 /D_CRT_SECURE_NO_WARNINGS \
/DGFLAGS_DLL_DECL= /DGFLAGS_DLL_DECLARE_FLAG= /DGFLAGS_DLL_DEFINE_FLAG= /DGOOGLE_GLOG_DLL_DECL= \
/I$(INC_DIR)\\src\\windows /I$(INC_DIR) /I. \
/DUSE_BOP /DUSE_GLOP \
/DUSE_CBC /DUSE_CLP \
/DUSE_SCIP
Link flags:
LDFLAGS = psapi.lib ws2_32.lib
OR_TOOLS_LNK = lib\\ortools.lib

Windows says 64-bit executable is "Unsupported 16-Bit Application"

I have a C++ program that links Google's WebRTC library that compiles and runs successfully when I target 32-bit but doesn't work at all when I target 64-bit. After some trial and error I created the following program:
#include <media/base/adapted_video_track_source.h>
class AdaptedVideoTrackSource : rtc::AdaptedVideoTrackSource
{
public:
void AddRef() const {}
rtc::RefCountReleaseStatus Release() const { return rtc::RefCountReleaseStatus::kDroppedLastRef; }
bool is_screencast() const {return false;}
absl::optional<bool> needs_denoising() const {return false;}
bool GetStats(webrtc::VideoTrackSourceInterface::Stats* stats) {return false;}
webrtc::MediaSourceInterface::SourceState state() const {return webrtc::MediaSourceInterface::kLive;}
bool remote() const {return false;}
};
int main() {
AdaptedVideoTrackSource source;
}
This program fails with this error:
If I remove the super class the program runs fine.
How exactly do I debug a problem like this? I'm at a loss since I can't exactly debug the program. dumpbin appears to think my webrtc library is fine but says warning LNK4048: Invalid format file; ignored for my executable.
There's a lot of steps in the build process and I don't think I can put all of them here. I use CMake with ExternalProject_Add to download and build webrtc. I generate Ninja makefiles to build my code. Here are the ninja rules used to link the exe.
rule CXX_EXECUTABLE_LINKER__Test
command = cmd.exe /C "$PRE_LINK && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=$OBJECT_DIR --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\mt.exe --manifests $MANIFESTS -- C:\PROGRA~2\MIB055~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo $in /out:$TARGET_FILE /implib:$TARGET_IMPLIB /pdb:$TARGET_PDB /version:0.0 $LINK_FLAGS $LINK_PATH $LINK_LIBRARIES && $POST_BUILD"
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
build utest\Test.exe: CXX_EXECUTABLE_LINKER__Test utest\CMakeFiles\Test.dir\main.cpp.obj | <OTHER LIBARIES> || <OTHER LIBARIES>
FLAGS = /DWIN32 /D_WINDOWS /GR /EHsc /bigobj /Zi /Ob0 /Od /RTC1 -MTd
LINK_FLAGS = /machine:x64 /debug /INCREMENTAL /subsystem:console
LINK_LIBRARIES = <OTHER LIBARIES> webrtc_bundle.lib <OTHER LIBRARIES>
LINK_PATH = -LIBPATH:D:\Folder\install64\lib
OBJECT_DIR = utest\CMakeFiles\Test.dir
POST_BUILD = cd .
PRE_LINK = cd .
TARGET_COMPILE_PDB = utest\CMakeFiles\Test.dir\
TARGET_FILE = utest\Test.exe
TARGET_IMPLIB = utest\Test.lib
TARGET_PDB = utest\Test.pdb
It's private code so I renamed the executable I build and replaced the non webrtc libraries with <OTHER LIBARIES>.
This is the args.gn I use to build webrtc:
target_cpu="x64"
rtc_enable_protobuf=true
is_official_build=false
rtc_build_examples=false
rtc_include_tests=false
enable_iterator_debugging=true
is_clang=false
Also, I wrote my own BUILD.gn file to bundle webrtc with other libraries that Google's build system can build.
UPDATE
I found that I can manually link my obj files and make a perfectly good exe. Then I started going into the Ninja Makefiles generated by CMake and playing around with the linker rules. I found that if I remove /debug from the linker flags then everything works great. Of course, I want to be able to debug my debug builds.
I moved on and tried to start building my project with clang-cl and lld-link which provided a little more diagnostic output. I started getting warnings about linking different versions of the run time library. MSVC_RUNTIME_LIBRARY was correctly set and I had the /MTd flag in CMAKE_CXX_FLAGS and CMAKE_LINKER_FLAGS but by running ninja with the verbose setting I could see that my flags were being followed by /MDd which overwrote the previous runtime setting. Eventually I appended /MTd to CMAKE_CXX_FLAGS_DEBUG and CMAKE_CXX_FLAGS_RELEASE and now it's the last runtime flag in the compiler and link commands and I haven't had this problem since.

How to build boost with "Omit default library name" and Visual C++?

I try to build static Boost library that will not depend on project runtime version (MT or MD). The only thing required to build such library is to add /Zl option to command line.
I edited tools/build/src/user-config.jam and specify compiler flags here:
using msvc : : : <cxxflags>/Zl ;
When I open rsp files generates by boost build system, I see /Zl flag here, for example, in regex.obj.rsp:
"libs\regex\build\..\src\regex.cpp" -Fo"bin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi\regex.obj" -TP /O2 /Ob2 /W4 /GR /MT /Zc:forScope /Zc:wchar_t /favor:blend /wd4675 /EHs /Zl -c
-DBOOST_ALL_NO_LIB=1
-DNDEBUG
"-I."
So, for me it looks like the resulted library can link both /MD and /MT. However, it is not true:
libboost_regex.lib(regex.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease'
This trick (with /Zl) works for me with zlib, openssl, libcurl, libsqlite3 and many other libraries; can anyone explain why does it not work with boost? Does boost somehow override /Zl option even it exists in rsp file and in user-config.jam, or why boost libraries require the same version of runtime even /Zl option is supposed to make it runtime-independent?

unrecognized command line option while compiling boost for android on cygwin

I am trying to compile boost on cygwin with help of following article
But when I ran following statement
bjam --without-python --without-serialization toolset=gcc-android4.4.3 link=static runtime-link=static target-os=linux --stagedir=android
It started compilation but failed due to following error:
cc1plus.exe: error: unrecognized command line option "-mthreads"
I am using latest cygwin and boost 1.48.0
I would appreciate if anybody can give me a hint to remove this error.
Update:
I found solution. Boost assumed cygwin has MingW gcc compiler so it added that special option in configuation file "gcc.jam" Once I removed the option it ran OK.
Short
Pass target-os=android to b2
Explanation
I faced with same issue for Boost 1.59
According boost/tools/build/src/tools/gcc.jam line 1024
rule setup-threading ( targets * : sources * : properties * )
{
local threading = [ feature.get-values threading : $(properties) ] ;
if $(threading) = multi
{
local target = [ feature.get-values target-os : $(properties) ] ;
local option ;
local libs ;
switch $(target)
{
case android : # No threading options, everything is in already.
case windows : option = -mthreads ;
case cygwin : option = -mthreads ;
case solaris : option = -pthreads ; libs = rt ;
case beos : # No threading options.
case haiku : option = ;
case *bsd : option = -pthread ; # There is no -lrt on BSD.
case sgi : # gcc on IRIX does not support multi-threading.
case darwin : # No threading options.
case * : option = -pthread ; libs = rt ;
}
if $(option)
{
OPTIONS on $(targets) += $(option) ;
}
if $(libs)
{
FINDLIBS-SA on $(targets) += $(libs) ;
}
}
}
As you can see -mthreads depends on target-os param

Cross-Compile of Boost for GCC ARM (Linux) from Windows building .o but not .a

I'm cross-compiling Boost for a Linux distro on an ARM board. I'm using windows with Boost 1.47.
My project-config.jam contains the following:
import option ;
using gcc : arm : "C:/Program Files (x86)/CodeSourcery/Sourcery
G++ Lite/bin/arm-none-linux-gnueabi-g++" ;
option.set keep-going : false ;
And I'm building with the command:
bjam toolset=gcc-arm target-os=linux
Whilst .o objects are building just fine, .a builds are failing usually with something like:
"C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin"
"bin.v2\libs\wav
e\build\gcc-arm\release\link-static\target-os-linux\threading-multi\libboost_wav
e-gcc-mt-1_47.a"
...failed gcc.archive
bin.v2\libs\wave\build\gcc-arm\release\link-static\target-
os-linux\threading-multi\libboost_wave-gcc-mt-1_47.a... ...skipped
libboost_wave-gcc-mt-1_47.a for lack of libboost_wav
e-gcc-mt-1_47.a... ...failed updating 23 targets... ...skipped 28
targets... ...updated 641 targets...
I am also getting quote a few of the following error messages:
'"C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin"' is not
recognized as an internal or external command, operable program or
batch file.
Any ideas guys?
Many thanks
I just have:
import option ;
using gcc : arm : arm-none-linux-gnueabi-g++.exe ;
option.set keep-going : false ;
And the compiler in the path. Works for me. Perhaps '\' vs '/' in your case.
http://www.boost.org/boost-build2/doc/html/bbv2/tasks/crosscompile.html
EDIT: To add the
C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin
directory to your path follow the instructions here:
http://geekswithblogs.net/renso/archive/2009/10/21/how-to-set-the-windows-path-in-windows-7.aspx
Faced the same problem, it was caused by the spaces within the path which aren't properly handled by boost.build. Either switch to boost 1.48.0, or move CS into a path without spaces.
The error for C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin sounds like a variable for the name of the compiler is missing.