Skip to content

Support for environment-configurable toolchains #1662

Closed
wants to merge 2 commits into from

3 participants

@pgj
pgj commented Jan 31, 2014

Both Cabal and cabal-install is currently lacking support for setting what C compiler, linker or C preprocessor to use. However, on systems like FreeBSD, one may want to specify which binaries to use at the various stages. Like one can install different versions of the GCC (such as 4.6, 4.7, and 4.8) that may even co-exist on the same system (not talking about Clang). Hence each version is identified by a version-specific suffix, such as gcc46 for GCC 4.6 (or clang34 for Clang 3.4) and so on -- basically, where setting the PATH would not really help.

I tried to work this problem around by implementing support for specifying the toolchain components from environment variables, such as CC and LD for Cabal. (Note that I have been using those patches for a while now in the FreeBSD Ports Collection.) I also met a similar problem in the bootstrap script for cabal-install, so I also changed it to make this possible there too.

I am aware that cabal-install supports --with-gcc and --with-ld flags but I felt it tedious to set them every time when I want to install something.

@23Skidoo
Haskell member

Note than you can use

program-locations
  gcc-location: /path/to/gcc
  ld-location: /path/to/ld

in ~/.cabal/config.

@pgj
pgj commented Jan 31, 2014

Great, that is good to know! We have cabal-install 1.16 in the Ports Collection (due to Haskell Platform) where it does not seem to be exist. So I guess 47c938a58def37eb79d2ba765eb6108a60179528 is not needed any more then...?

Although I do not see cpp in the list of configurable locations. I think this may be useful to have as Clang may need an external C preprocessor in order to satisfy the needs of GHC. But I have not really experimented with building Cabal packages via Clang, so I may be wrong here.

@pgj
pgj commented Jan 31, 2014

Actually, on a second thought... Note that Cabal is also used by GHC where there is no such fancy config file to set the program locations. For that reason, I also had to patch the Cabal library shipped with GHC to make it work with GCC 4.6.

@23Skidoo
Haskell member

Since CPP is invoked by GHC and not Cabal, you need to use GHC's -pgmP option.

@23Skidoo
Haskell member

LGTM.

@dcoutts
Haskell member
dcoutts commented Jan 31, 2014

So the principle of Cabal knowing about the toolchain is fine.

Currently we have a generic mechanism for configuring programs (so you can set where they are, extra flags etc). But this is a totally generic mechanism, it does not know that any of these programs are special in any way. So if you want to set "the linker" then that would currently translate into several things: telling Cabal where ld is, because Cabal invokes ld directly, but then you'd also have to tell Cabal to tell ghc where ld is because it uses it too (usually via gcc).

So a toolchain system where we know what the toolchain programs are and that they are special in some way, and then tell other things we call to use them too, that's all good.

On this specific patch: we don't want to use env vars in general. We have mechanism for configuring cabal, with config files etc. The one exception is we do have a single env var for specifying which config file to use. But I don't think we want a proliferation of env vars, it makes it very hard to work out where things are coming from if you're trying to debug it.

@dcoutts
Haskell member
dcoutts commented Jan 31, 2014

Oh, but the env vars in the bootstrap is fine.

@dcoutts
Haskell member
dcoutts commented Jan 31, 2014

Ok, looking at the patch more closely, I don't think we want to go that way. We already have mechanism for configuring.

Perhaps the right solution here is system-global config, so per-user configs can inherit from some system defaults set by the distro. That would be a reasonable way to go. There's two approaches there: explicit includes, where e.g. the default per-user config explicitly asks for /etc/cabal/config, or implicit. I'd prefer explicit if we can make that work. It'd be a useful general mechanism, and easier to see what's going on.

@23Skidoo
Haskell member

Merged the bootstrap.sh patch, but not the second one.

@pgj Thanks for the contribution!

@23Skidoo 23Skidoo closed this Jan 31, 2014
@pgj
pgj commented Jan 31, 2014

I accept your comments Duncan, but I think you missed this comment of mine:

Note that Cabal is also used by GHC where there is no such fancy config file to set the program locations. For that reason, I also had to patch the Cabal library shipped with GHC to make it work with GCC 4.6.

I am open to any other solution, but currently the environment variables are needed in order to make GHC build itself on a system where there is no gcc on the system path. For example, building GHC on 10.0-RELEASE and later, where Clang is the default compiler, and GCC 4.6 is used, but as gcc46. I would recommend you to try that on your system to see what I am talking about.

@pgj
pgj commented Jan 31, 2014

Okay, just for the record: I have verified my claims, and it turned out I was wrong, GHC can be built without the referenced changes. I will not have to change neither Cabal or cabal-install any more once their newer versions land in the Ports Collection. At the end of the day, I am glad that it worked out this way, thanks for the replies!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.