I do a lot of cross compilations. With different software elements. But sometimes I want to kick their authors into ass…

There is a good sign when you see $(CC) in Makefiles as it shows that author of code learnt that “gcc” is not the only compiler. But this is not the only compiler you should know about.

Recently I was adding one component (will save a name) into OpenEmbedded as this is one of dependencies for some bigger project (which I do not want to blog about). Argh… I managed to cross built it but patches are UGLY (will get better).

Using $(CC) to build everything is just broken. Especially when you need to compile a tool which will generate some code to get everything built. There is $(BUILD_CC) for it but you have to use it wisely. If there are common parts then compile them with $(BUILD_CC) if you need to run it and with $(CC) if you not. This way we, cross compilation guys, can just do “./configure;make;make install;package” is it native or cross build. Autotools (die, die, die) are able to handle that — so is your code if you write Makefiles properly.

But do not reuse same object files for target and native binaries — let it be “common.o” and “native/common.o” for example. OK, if you do only native builds then it will take a bit more disk space but we have 2012 not 1995… Storage is cheap.

There is also $(HOST_CC) but that’s for other post…

There are other compilers than $(CC)

8 thoughts on “There are other compilers than $(CC)

  • 6th December 2012 at 03:10

    Could you explain how this breaks cross-compilation, and why?

    I have a library that uses one compiler. It seemed natural to call that compiler “$(CC)” in the makefiles (given that, you know, the autoconf documentation documents AC_PROG_CC as “Determine a C compiler to use” with no mention of native-only), and so that’s what we’ve done. We cross-compile the library all the time, without any trouble. We document that to build the library you set CC to the compiler to use. I’d like to know what sort of problem you’re running into, and why, and what the recommended usage is, so that we can avoid it if it’s important — but your post is no help; it just tells me that I am an idiot and that I have broken cross-compiling on a library that I successfully cross-compile every day.

    My guess is that you’re referring to some standard convention for what environment variables you define before calling “configure”, with the assumption that all software build systems will give them the same meanings, so that you can define them once and cross-build all packages without specifying package-specific options. What is this convention, and where is it defined? My attempts at a web search find nothing.

    • 6th December 2012 at 09:38

      You are doing it right. $(BUILD_CC) is needed only if you have need to run some kind of “gen-some-headers” binaries during compilation.

      • 6th December 2012 at 18:39

        Oh! Okay, that makes a lot more sense — and, yes, I can see how that would be a problem.

        Then there are certain packages where the “gen-some-headers” binary needs to be run on the target in order to do some performance tuning, but there’s no machinery for remotely running them. We shall not speak of those here, except to say that I find that I am, indeed, quite familiar with the pain of which you speak after all!

        • 6th December 2012 at 21:28

          Another example are software that bootstraps itself (usualy compilers, interpretators, etc). It can compile tiny-compiler and then bootstrap normal version with it.

  • 6th December 2012 at 11:47

    The problem is when you need to build and run a tool to generate source or data. For example, Mesa has an internal compiler that it uses to generate source.

    The convention for handling this with cross compilation is CC_FOR_BUILD, see http://www.sourceware.org/autobook/autobook/autobook_270.html#SEC270.

    The problem is it’s simple to drop a few CC_FOR_BUILDS in and think it works without testing it, but you’ll end up linking your CC_FOR_BUILD native binary with an object which was built for the target. Linking a x86 object against an ARM object doesn’t work… Automake avoids this by ensuring that these intermediate objects are specific to the target.

    As much as people hate on autotools, it does actually work. 🙂

  • 6th December 2012 at 11:51

    ahaha, did you just tried to compile gSoap? I fought against it a couple of weeks ago and I completely understand you!!

Comments are closed.