[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Allowing both cross building and using an alternative compiler

+++ Guillem Jover [2015-05-10 03:32 +0200]:
> [ Please followup on debian-devel (M-F-T set). ]
> Hi!
> There are currently two goals people are pursuing that seemed to
> initially conflict with each other:
>   <https://wiki.debian.org/ReleaseGoals/CrossBuildableBase>
>   <https://wiki.debian.org/ReleaseGoals/honorCCandCXX>

Right. I noticed some time ago that the proposed fix for allowing LLVM
builds ignored cross-building and was not compatible with it. 

> But they can be made to coexist gracefully, if using the same
> semantics as used by autotools but on a Makefile.
> ,---
> DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
> ifeq ($(origin CC),default)
> endif
> CC ?= $(DEB_HOST_GNU_TYPE)-gcc
> CC_FOR_BUILD = gcc
> `---
> This allows the user to both set CC to any non-default compiler such
> as clang or gcc-6, and supports cross compiling out of the box. I guess
> that if people do not see any obvious problem with it, something like
> this should probably be codified in policy.

So, things people mostly want to do are change the default compiler, and
automatically have crossbuilding use the correct compiler for HOST and

The above logic seems like the right sort of idea, but I'm not sure
that it's quite correct.

E.g if someone sets CC=clang (in the environment), that correctly sets
CC=clang, but sets CC_FOR_BUILD = gcc. Is it a not a reasonable
expectation that the same toolchain is used for native and cross
components, at least by default?

So I think we should determine the 'base' compiler and propogate that
into the FOR_BUILD variable. That's a little tricky when someone has
set say CC=vendor-toolchain-gcc. What rule should we use to determine
the 'base' compiler from $CC in order to make CC_FOR_BUILD match up?
It'll usually end in 'gcc' or 'clang' so 'last-component' will usually
work, but there are other reasonable values and I'm not sure how
reliable this will be.

Also what fraction of packages recognise CC_FOR_BUILD, as opposed to
other random names like BUILD_CC and other less regular things? A
check check on codesource.debian.net sugests that 1/3rd of packages
use BUILD_CC (e.g glibc, e2fsprogs) and 2/3rds CC_FOR_BUILD (which is
in autotools). (Also autotools used to use HOST_CC (!) to mean the
same thing, but I think it deals with that itself).

I've not checked exactly how these are used, but maybe we need to set
both for a reasonable level of 'works out of the box'? I know some
packages use random other made-up things. Maybe Debian should be
patching those as part of making them crossable, to use the
autotools-derived 'standard' names? 

Currently there isn't really a good standard for the FOR-BUILD
variables, but it's probably time to set one at least in Debian and
work on propogating that upstream.

testing with e2fsprogs(an example that uses BUILD_CC upstream)

Simply trying 

BUILD_CC=clang ./configure --host=arm-linux-gnueabi --build=x86_64-linux-gnu
correctly sets BUILD_CC=clang

CC_FOR_BUILD=clang ./configure --host=arm-linux-gnueabi --build=x86_64-linux-gnu
doesn't set BUILD_CC

CC=clang ./configure --host=arm-linux-gnueabi --build=x86_64-linux-gnu
sets CC=clang, but doesn't set BUILD_CC to anything.

BUILD_CC=clang ./configure 
leaves BUILD_CC unset (correctly, I guess), but CC defaulting to
'gcc'. perhaps unexpected, but reasonably correct in the absence of
--hotst and --build.

So, we do need to either patch things or also set BUILD_CC for this to
work with some number of packages. Needs a bit more investigation

I'm not sure if cmake or other build systems have other conventions
that we'd need to cope with (or patch). 

> I'm in principle planning to add the attached Makefile to dpkg-dev to
> make this kind of usage easier for packagers.

Because the base toolchain type/version and arch are encoded together,
I agree that there is no getting round having to set two things, one
for HOST, one for BUILD. The HOST CC variable is well-honoured, but
there is more variability in the BUILD variable(s) used upstream.

We have at least got gcc to a state where <arch>-gcc will always do
the right thing, and if
is implemented then build-dependencies will work too (at least for gcc)

Have you thought about how this will interact with packages that
specify particular toolchains e.g. Build-Depends: gcc-4.8, usually
because they (at least at some point in the past) were known not to
work with other ones. This covers both versionning and

Should packaging be allowed to override dpkg-dev-provided variable
settings in that case? Or should we assume some higher-level tool will
set CC and CC_FOR_BUILD in a compatible fashion? I admit that I have
thought about these things before and not reached clear conclusions. 

I do agree that a sensible mechanism to automatically set a consistent
set of BUILD-basecompiler and HOST-basecompiler variables in the dpkg
build env is a step forwards, and we can then see how that works, and
intereracts with existing usage and specific packaging.

Cheers for pushing this forward, sorry it's taken me so long to reply.

> # This Makefile snippet defines the following variables for host tools:
> #
> # CPP: C preprocessor
> # CC: C compiler
> # CXX: C++ compiler
> # OBJC: Objective C compiler
> # OBJCXX: Objective C++ compiler
> # GCJ: GNU Java compiler
> # F77: Fortran 77 compiler
> # FC: Fortran 9x compiler
> # LD: linker
> #
> # All the above variables have a counterpart variable for the build tool,
> # as in CC → CC_FOR_BUILD.
> #
> # The variables are not exported by default. This can be changed by
> DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
> define dpkg_buildtool_setvar
> ifeq ($(origin $(1)),default)
> $(1) = $(DEB_HOST_GNU_TYPE)-$(2)
> endif
> $(1) ?= $(DEB_HOST_GNU_TYPE)-$(2)
> $(1)_FOR_BUILD = $(2)
> export $(1)
> export $(1)_FOR_BUILD
> endif
> endef
> $(eval $(call dpkg_buildtool_setvar,CPP,gcc -E))
> $(eval $(call dpkg_buildtool_setvar,CC,gcc))
> $(eval $(call dpkg_buildtool_setvar,CXX,g++))
> $(eval $(call dpkg_buildtool_setvar,OBJC,gcc))
> $(eval $(call dpkg_buildtool_setvar,OBJCXX,g++))
> $(eval $(call dpkg_buildtool_setvar,GCJ,gcj))
> $(eval $(call dpkg_buildtool_setvar,F77,f77))
> $(eval $(call dpkg_buildtool_setvar,FC,f95))
> $(eval $(call dpkg_buildtool_setvar,LD,ld))

Principal hats:  Linaro, Debian, Wookware, ARM

Reply to: