Opened 5 years ago

Last modified 6 weeks ago

#6132 new bug

Can't use both shebang line and #ifdef declarations in the same file.

Reported by: gfxmonk Owned by:
Priority: normal Milestone: 8.4.1
Component: Compiler (Parser) Version: 7.0.4
Keywords: cpp Cc: lelf
Operating System: MacOS X Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case: runghc/T6132
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

I have an (admittedly awkward) script which can be compiled or interpreted.

If it's compiled, I want the full goodness. If it's interpreted, I want to run a "minimal" version (because if I don't have the compiled version, I probably don't have the required libraries either).

The following almost works:

module Main (main) where
#ifdef FANCY
import qualified System.Console.ANSI as Term
start = Term.setSGR [Term.SetColor Term.Foreground Term.Dull Term.Green]
end = Term.setSGR []
#else
start = return ()
end = return ()
#endif
main :: IO ()
main = do
	start
	putStrLn "hello world"
	end

and then I can do:

$ runghc -cpp main.hs
hello world
^^ plain text
$ ghc -O -cpp -DFANCY main.hs
$ ./main
hello world
^^ green text (a.k.a "fancy")

I attempted to make this directly runnable by adding a shebang line of

#!/usr/bin/runghc -cpp

But unfortunately that chokes with -cpp:

$ ghc -O -cpp -DFANCY main.hs

main.hs:1:0:  error: invalid preprocessing directive #!

Change History (18)

comment:1 Changed 5 years ago by igloo

difficulty: Unknown
Milestone: 7.8.1

If you put the conditional part into a separate module with a {-# LANGUAGE CPP #-} pragma then it would work, but I suspect you don't want to do that so that it's easy to move the script around. Similarly a custom preprocessor would make moving it around harder.

I can't see a better immediate fix than:

  • When running CPP, if the file starts with #! then copy all but the first line to a temporary file and run CPP on that instead. (actually, we'd want a blank first line so that line numbers work out).

comment:2 Changed 3 years ago by thoughtpolice

Milestone: 7.8.37.10.1

Moving to 7.10.1.

comment:3 Changed 3 years ago by thoughtpolice

Milestone: 7.10.17.12.1

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

comment:4 Changed 2 years ago by thoughtpolice

Milestone: 7.12.18.0.1

Milestone renamed

comment:5 Changed 2 years ago by thomie

Component: CompilerCompiler (Parser)

comment:6 Changed 21 months ago by thomie

Milestone: 8.0.1

comment:7 Changed 20 months ago by Thomas Miedema <thomasmiedema@…>

In 0b00add0/ghc:

Add test for #6132: hash bang + CPP

comment:8 Changed 20 months ago by thomie

Resolution: fixed
Status: newclosed
Test Case: runghc/T6132

This was fixed in commit 7b0695a887c13a431f898d89938e127faa3f4585 (ghc-7.8.1):

Author: Austin Seipp <aseipp@pobox.com>
Date:   Mon Jun 17 06:12:08 2013 -0500

    Use assembler-with-cpp mode when running CPP.
    
    This is needed because Clang is very strict about C99 macro rules, which
    dictate that '#' in a body must have a token immediately following it for
    string-ification. In practice we break this all the time, because we do
    very weird stuff like:
    
        #define FOOBAR(xyz) \
        {-# SOME PRAGMA #-} \
        baz :: (xyz) \
        baz = ...
    
    where the leading '#' in in the macro body clearly breaks this rule.
    
    Signed-off-by: Austin Seipp <aseipp@pobox.com>

Hurray Austin!

I added a test.

comment:9 Changed 16 months ago by mpickering

This test always fails for me on OSX.

=====> T6132(normal) 4 of 4 [0, 0, 0] 
cd "/var/folders/3z/_vqy7kmx4pd90sg_v80zpk340000gn/T/ghctest-UHP1ob/test   spaces/1/2/3/./T6132" &&  "/Users/matt/Documents/haskell/ghc/inplace/test   spaces/ghc-stage2" -c T6132.hs -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-warn-tabs -fno-warn-missed-specialisations -fshow-warning-groups -fno-ghci-history   > T6132.comp.stderr 2>&1
Compile failed (status 256) errors were:

T6132.hs:1:2: error: parse error on input ‘#!/’

Result of --info

[("Project name","The Glorious Glasgow Haskell Compilation System")
 ,("GCC extra via C opts"," -fwrapv -fno-builtin")
 ,("C compiler command","gcc")
 ,("C compiler flags"," -m64 -fno-stack-protector")
 ,("C compiler link flags"," -m64")
 ,("Haskell CPP command","gcc")
 ,("Haskell CPP flags","-E -undef -traditional -Wno-invalid-pp-token -Wno-unicode -Wno-trigraphs")
 ,("ld command","/usr/bin/ld")
 ,("ld flags"," -arch x86_64")
 ,("ld supports compact unwind","YES")
 ,("ld supports build-id","NO")
 ,("ld supports filelist","YES")
 ,("ld is GNU ld","NO")
 ,("ar command","/usr/bin/ar")
 ,("ar flags","clqs")
 ,("ar supports at file","NO")
 ,("touch command","touch")
 ,("dllwrap command","/bin/false")
 ,("windres command","/bin/false")
 ,("libtool command","libtool")
 ,("perl command","/usr/bin/perl")
 ,("cross compiling","NO")
 ,("target os","OSDarwin")
 ,("target arch","ArchX86_64")
 ,("target word size","8")
 ,("target has GNU nonexec stack","False")
 ,("target has .ident directive","True")
 ,("target has subsections via symbols","True")
 ,("Unregisterised","NO")
 ,("LLVM llc command","llc")
 ,("LLVM opt command","opt")
 ,("Project version","8.1.20160611")
 ,("Project Git commit id","5895f5c51c36d445360ced3af61a650cfb1ad899")
 ,("Booter version","8.0.1")
 ,("Stage","2")
 ,("Build platform","x86_64-apple-darwin")
 ,("Host platform","x86_64-apple-darwin")
 ,("Target platform","x86_64-apple-darwin")
 ,("Have interpreter","YES")
 ,("Object splitting supported","YES")
 ,("Have native code generator","YES")
 ,("Support SMP","YES")
 ,("Tables next to code","YES")
 ,("RTS ways","l debug thr thr_debug thr_l  dyn debug_dyn thr_dyn thr_debug_dyn l_dyn thr_l_dyn")
 ,("RTS expects libdw","NO")
 ,("Support dynamic-too","YES")
 ,("Support parallel --make","YES")
 ,("Support reexported-modules","YES")
 ,("Support thinning and renaming package flags","YES")
 ,("Requires unified installed package IDs","YES")
 ,("Uses package keys","YES")
 ,("Uses unit IDs","YES")
 ,("Dynamic by default","NO")
 ,("GHC Dynamic","YES")
 ,("GHC Profiled","NO")
 ,("Leading underscore","YES")
 ,("Debug on","False")
 ,("LibDir","/Users/matt/Documents/haskell/ghc/inplace/lib")
 ,("Global Package DB","/Users/matt/Documents/haskell/ghc/inplace/lib/package.conf.d")
 ]

comment:10 Changed 13 months ago by bgamari

Milestone: 8.0.2
Resolution: fixed
Status: closednew

Indeed this still seems to be broken on OS X. I can confirm the behavior seen by mpickering in comment:9.

comment:11 Changed 13 months ago by Ben Gamari <ben@…>

In 3630ad3/ghc:

Mark #6132 as broken on OS X

It currently fails with,

    =====> T6132(normal) 1 of 1 [0, 0, 0]
    cd "./runghc/T6132.run" && "/Users/bgamari/ghc/inplace/test
    spaces/ghc-stage2" -c T6132.hs -dcore-lint -dcmm-lint
    -no-user-package-db -rtsopts -fno-warn-missed-specialisations
    -fshow-warning-groups -dno-debug-output
    Compile failed (exit code 1) errors were:

    T6132.hs:1:2: error: parse error on input ‘#!/’

    *** unexpected failure for T6132(normal)

comment:12 Changed 13 months ago by rwbarton

It's because clang's CPP inserts a space before the # and then GHC no longer recognizes it as a shebang line. See #10044 for a related clang whitespace oddity.

comment:13 Changed 13 months ago by bgamari

Thanks Reid! Yet another reason to move to hpp, I suppose.

comment:14 Changed 12 months ago by bgamari

Milestone: 8.0.28.0.3

Sadly it looks like this won't be fixed for 8.0.2.

comment:15 Changed 12 months ago by thomie

Keywords: cpp added
Operating System: Unknown/MultipleMacOS X

comment:16 Changed 8 months ago by bgamari

Milestone: 8.0.38.2.1

At this point it is rather unlikely that there will be an 8.0.3. Re-milestoning.

comment:17 Changed 7 months ago by bgamari

Milestone: 8.2.18.4.1

Given that 8.2.1-rc1 is imminent, I'm bumping these off to the 8.4

comment:18 Changed 6 weeks ago by lelf

Cc: lelf added
Note: See TracTickets for help on using tickets.