Skip to content

GHC HEAD propagates -optc arguments to gcc in a strange order

I originally noticed this bug as it prevents the HsOpenSSL-0.11.4.17 library from compiling on GHC HEAD. Here is a minimized reproducer involving one .c file and one .hs file:

// foo.c
int foo() {
#if defined(FOO)
  return 1;
#else
  return 0;
#endif
}
-- Bug.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Bug where

import Foreign.C.Types

foreign import ccall "foo" foo :: IO CInt

You can compile this on GHC 8.8.1 like so:

$ /opt/ghc/8.8.1/bin/ghc foo.c Bug.hs -optc-D -optcFOO
[1 of 1] Compiling Bug              ( Bug.hs, Bug.o )

But on GHC HEAD, you'll get this instead:

$ ~/Software/ghc5/inplace/bin/ghc-stage2 foo.c Bug.hs -optc-D -optcFOO
cc: error: FOO: No such file or directory
cc: error: FOO: No such file or directory
`cc' failed in phase `C Compiler'. (Exit code: 1)

What is going on here? If you pass -v3 to ghc, you'll see what arguments it's passing to gcc. On GHC 8.8.1, you'll get this:

$ /opt/ghc/8.8.1/bin/ghc foo.c Bug.hs -optc-D -optcFOO -v3
...
*** C Compiler:
gcc -DTABLES_NEXT_TO_CODE -x c foo.c -o /tmp/ghc15237_0/ghc_1.s -no-pie -fno-PIC -Wimplicit -S -include /opt/ghc/8.8.1/lib/ghc-8.8.1/include/ghcversion.h -I/opt/ghc/8.8.1/lib/ghc-8.8.1/base-4.13.0.0/include -I/opt/ghc/8.8.1/lib/ghc-8.8.1/integer-gmp-1.0.2.0/include -I/opt/ghc/8.8.1/lib/ghc-8.8.1/include -D FOO

But on GHC HEAD, you'll get this:

$ ~/Software/ghc5/inplace/bin/ghc-stage2 foo.c Bug.hs -optc-D -optcFOO -v3
...
*** C Compiler:
cc -x c foo.c -o /tmp/ghc15256_0/ghc_1.s -no-pie -fno-PIC -Wimplicit -S -include /home/rgscott/Software/ghc5/includes/dist-install/build/ghcversion.h -I/home/rgscott/Software/ghc5/libraries/base/include -I/home/rgscott/Software/ghc5/libraries/base/dist-install/build/include -I/home/rgscott/Software/ghc5/libraries/base/dist-install/build/dist-install/build/include -I/home/rgscott/Software/ghc5/libraries/integer-gmp/include -I/home/rgscott/Software/ghc5/libraries/integer-gmp/dist-install/build/include -I/home/rgscott/Software/ghc5/libraries/integer-gmp/dist-install/build/dist-install/build/include -I/home/rgscott/Software/ghc5/rts/dist/build -I/home/rgscott/Software/ghc5/includes -I/home/rgscott/Software/ghc5/includes/dist-derivedconstants/header -I/home/rgscott/Software/ghc5/includes/dist-install/build FOO -D -D FOO
cc: error: FOO: No such file or directory
cc: error: FOO: No such file or directory

Note that 8.8.1 passes -D FOO, whereas HEAD passes FOO -D -D FOO.

I'm unclear on whether this is expected to work, but since the HsOpenSSL library currently relies on this, I figured that I would file a bug to be on the safe side.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information