Opened 9 years ago

Last modified 9 years ago

#9704 assigned Bugs

b2: Compiler flavour has no flexibility for cross-compiling projects.

Reported by: lukasz.forynski@… Owned by: Steven Watanabe
Milestone: To Be Determined Component: build
Version: Boost 1.54.0 Severity: Problem
Keywords: boost build system Cc:

Description

Hi,

I've been trying hard, but it is annoying, didn't find it elsewhere and it could really be improved.

I am building my project (i.e. all of my project tree)

on 2 platforms:

  • Windows,
  • Linux,

for 3 different platforms:

  • Windows
  • Linux IA32
  • Linux ARM HF

Now, whilst b2 subsystem is quite flexible in specifying different types of compilers, it is not so much when using the same type of compiler, but using different versions of it.

I have managed to define it somehow, i.e. in my project_config.jam (@ home dir):

if [ os.name ] = NT
{
using gcc : : :
     <cxxflags>-std=c++11 
     <cxxflags>"-include cmath"
     <cxxflags>-Wdeprecated-declarations
    ;

using gcc : armhf : arm-linux-gnueabihf-g++.exe :
     <cxxflags>-std=c++11
     <cxxflags>"-include cmath"
     <cxxflags>-Wdeprecated-declarations
    ;
}

if [ os.name ] = LINUX
{
using gcc : : :
     <cxxflags>-std=c++11 
     <cxxflags>"-include cmath"
    ;

using gcc : armhf : /usr/bin/arm-linux-gnueabihf-g++ :
     <cxxflags>-std=c++11 
     <cxxflags>"-include cmath"
     <cxxflags>-Wdeprecated-declarations
    ;
}

But now, in every sub-project, where I'm moving files to a 'release' location, (* and whenever I need to specify copmiler-flavor specific configuration) I need to perform something like:

install copy_binaries_to_release
  : 
    target_names..
  :
    <target-os>linux:<toolset-gcc:version>4.7:<location>../../release/
    <target-os>windows:<toolset>gcc-4.7.2-mingw:<location>../../release/
    <toolset-gcc:version>armhf:<location>../../release_armhf/
    <toolset>gcc-mingw-armhf:<location>../../release/
  ;

Is there a better way of doing it?

If not, then the problem (and I guess a bug) is that b2 behaves differently on different platforms, somewhat lacks of mechanism to support what I need to do (and it's not really very uncommon).

Problems:

  1. Different toolset names when building on different OSes (and yes, I did try to specify a default flavor, but see Problem 2).
command toolset flavor
gcc XA32(linux) b2 gcc 4.7
gcc XA32(win) b2 gcc-4.7.2-mingw ?
gcc armhf(linux) b2 --toolset=gcc-armhf gcc armhf
gcc armhf(win) b2 --toolset=gcc-armhf target-os=linux gcc-mingw-armhf ?

Only gcc-armhf seems to achieve requested results. BUt the main issue it, that it is all different on different platforms, and both: armhf should produce compatible binaries.

BTW: is there really a need to distinguish between e.g. Cygwin and MinGW flavours if they produce the same target with the same version of compiler? If one builds from Cygwin and MinGW for the same platform: resulting executables should be compatible for the same target, so only in 'bin' build directory they can really be different (if needed), but it is unlikely that one builds both of them (target:gcc version) at the same time (like it is unlikely that I build under windows and linux at the same time).

  1. It is not possible to specify a flavor for GCC (by explicitly giving it a name and compiler location) - because b2 is performing a version check. This check either fails, or if it does not (and default version is used) - automatic build-platform-specific flavor value is created behind the control) - probably because b2 is trying to be too clever at this.

Couldn't it leave it alone, and use flavor that was explicitly specified?

I really wish that I could specify above:

using gcc : 4.7 : <my-path-to-gcc47> ... ;
using gcc : armhf : <my-path-to-gcc47 arm hf>  ... ;

and wouldn't have to create links or worry about the build system changing/ coming up with a flavor by concatenating target name (e.g. on

b2 --toolset=gcc-armhf

with g++ (and having to hack/create symlinks to match this etc.) -

It should just accept what I specify, and use it 'as-is' (and if someone does something stupid - let them fail and fix it).

There could also be a support for something like:

import toolset ;

if [ toolset.name ] == gcc
{
  if [ toolset.flavor ] == flav_1
  {
  }
}

# and my verbosive Jamfiles could be re-written to something like:

local gcc_flavor = [ toolset.flavor ] ;
install copy_binaries_to_release
  : 
    target_names..
  :
    <toolset>gcc,<flavor>4.7:<location>../../release
    <toolset>gcc,<flavor>armhf:<location>../../release_$(gcc_flavor)
    
    # or even to:
    <toolset>gcc:<location>../../release_$(gcc_flavor)
  ;

With a bit of guidance / advice from someone, who knows the build system well - I'm happy to help with implementing the above.

Thanks, LUkasz.

(BTW: what is the best component for build system / tools?)

Change History (3)

comment:1 by Steven Watanabe, 9 years ago

Component: Building Boostbuild
Owner: set to Steven Watanabe
Status: newassigned

Regarding (2), I believe that this used to work. If it's broken, it's probably to try to support uses that set flags for specific versions of gcc, which need the real gcc version number rather than some arbitrary identifier. I'll look into this.

P.S. The correct component for Boost.Build is "build". "Building Boost" is for issues when building the Boost C++ libraries. It's often ambiguous, though and if you use the wrong component it doesn't matter much, since the same people are responsible for both, and we can reassign it if needed.

in reply to:  description comment:2 by Steven Watanabe, 9 years ago

Replying to lukasz.forynski@…:

import toolset ;

if [ toolset.name ] == gcc
{
  if [ toolset.flavor ] == flav_1
  {
  }
}
<snip>

This is fundamentally impossible in Boost.Build. The main reason being that there is no such thing as the value of a feature in a Jamfile. See http://www.boost.org/boost-build2/doc/html/bbv2/faq.html#bbv2.faq.featurevalue

You would need to write this using a conditional

import feature ;
rule calculate-install-dir ( properties * )
{
    local gcc-version = [ feature.get-values <toolset-gcc:version> : $(properties) ] ;
    return <location>../../release_$(gcc-version) ;
}

install copy_binaries_to_release
  : # target names
  :
    <conditional>@calculate-install-dir
  ;

in reply to:  description comment:3 by Steven Watanabe, 9 years ago

Replying to lukasz.forynski@…:

Problems:

  1. Different toolset names when building on different OSes (and yes, I did try to specify a default flavor, but see Problem 2).
command toolset flavor
gcc XA32(linux) b2 gcc 4.7
gcc XA32(win) b2 gcc-4.7.2-mingw ?
gcc armhf(linux) b2 --toolset=gcc-armhf gcc armhf
gcc armhf(win) b2 --toolset=gcc-armhf target-os=linux gcc-mingw-armhf ?

Only gcc-armhf seems to achieve requested results. BUt the main issue it, that it is all different on different platforms, and both: armhf should produce compatible binaries.

I'm sorry. I don't understand this table. On line 1, gcc XA32(linux), the properties should be <toolset>gcc <toolset-gcc:version>4.7.2 On line 2, gcc XA32(win), they should be <toolset>gcc <toolset-gcc:version>4.7.2 <toolset-gcc:flavor>mingw. For lines 3-4, just replace 4.7.2 with armhf. I suppose my issue is that I don't see how you're deciding what is the toolset and what is the flavor.

I've been trying several things and the only issue that I ran into using multiple versions of gcc (including a cross-compiler) is the old problem when mixing MinGW with other versions of gcc (All versions of gcc are tagged as mingw).

Here's what I suggest. It seems to work for me with a combination of mingw-w64 and native gcc on linux.

using gcc : 4.7.2 : g++ : <flavor>host ;
using gcc : 4.8.0 : /usr/local/gcc-4.8.0/bin/g++ : <flavor>host ;
using gcc : 4.7.2 : i686-w64-mingw32-g++ : <flavor>mingw ;

Then you can access <toolset-gcc:flavor> to get the flavor. (Adjust the version number, path, and flavor for your environment. If you leave the version blank, it will be auto-deduced.)

Running

# Uses g++
b2
b2 gcc
b2 gcc-4.7.2
b2 gcc-linux
b2 gcc-linux-4.7.2
b2 gcc-4.7.2-linux
# Uses GCC 4.8
b2 gcc-4.8.0
b2 gcc-4.8.0-linux
# Uses MinGW g++
b2 gcc-4.7.2-mingw
b2 gcc-mingw

You have to be a little careful, since Boost.Build is not smart about filling in defaults. It's safest to specify just gcc, which will always take the first version initialized, or to specify the full gcc-version-flavor. (b2 gcc-mingw will break if you put gcc 4.8.0 first, since it becomes gcc-4.8.0-mingw, which doesn't exist.)

Note: See TracTickets for help on using tickets.