Opened 4 years ago

Closed 5 months ago

Last modified 6 weeks ago

#6132 closed bug (fixed)

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

Reported by: gfxmonk Owned by:
Priority: normal Milestone:
Component: Compiler (Parser) Version: 7.0.4
Keywords: Cc:
Operating System: Unknown/Multiple 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 (9)

comment:1 Changed 4 years ago by igloo

  • difficulty set to Unknown
  • Milestone set to 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 2 years ago by thoughtpolice

  • Milestone changed from 7.8.3 to 7.10.1

Moving to 7.10.1.

comment:3 Changed 19 months ago by thoughtpolice

  • Milestone changed from 7.10.1 to 7.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 11 months ago by thoughtpolice

  • Milestone changed from 7.12.1 to 8.0.1

Milestone renamed

comment:5 Changed 10 months ago by thomie

  • Component changed from Compiler to Compiler (Parser)

comment:6 Changed 6 months ago by thomie

  • Milestone 8.0.1 deleted

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

In 0b00add0/ghc:

Add test for #6132: hash bang + CPP

comment:8 Changed 5 months ago by thomie

  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to 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 6 weeks 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")
 ]
Note: See TracTickets for help on using tickets.