[Haskell-beginners] using Shake to compile c++

Roger Mason rmason at mun.ca
Sat Jul 8 11:19:39 UTC 2017


Hello,

I am trying the Shake build system to compile some c++.  I would
appreciate some advice on how to use the result of a call to pkg-config
in constructing a compiler command.  This is what I have currently in Build.hs:

import Development.Shake
import Development.Shake.Command
import Development.Shake.FilePath
import Development.Shake.Util

main :: IO ()
main = shakeArgs shakeOptions{shakeFiles="bin"} $ do
    want ["bin/makelist", "bin/makejpeg" <.> exe]

    phony "clean" $ do
        putNormal "Cleaning files in _build"
        removeFilesAfter "bin" ["//*"]

    "bin/makelist" <.> exe %> \out -> do
        cs <- getDirectoryFiles "" ["src/MakeList.cxx"]
        let os = ["objects" </> c -<.> "o" | c <- cs]
        need os
        cmd "c++ -o" [out] os

    "bin/makejpeg" <.> exe %> \out -> do
        cs <- getDirectoryFiles "" ["src/MakeJpeg.cxx"]
        let os = ["objects" </> c -<.> "o" | c <- cs]
        need os
        cmd "c++ -o" [out] os

    "objects//*.o" %> \out -> do
        let c = dropDirectory1 $ out -<.> "cxx"
        let m = out -<.> "m"
        let i = cmd "pkg-config glib-2.0 --cflags"
        () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i]
        needMakefileDependencies m

This is the output from 'stack runhaskell Build.sh':

Build.hs:29:17: error:
    * Ambiguous type variable `t0' arising from a use of `cmd'
      prevents the constraint `(CmdArguments t0)' from being solved.
      Relevant bindings include i :: t0 (bound at Build.hs:29:13)
      Probable fix: use a type annotation to specify what `t0' should be.
      These potential instances exist:
        instance CmdResult r => CmdArguments (IO r)
          -- Defined in `Development.Shake.Command'
        instance CmdResult r => CmdArguments (Action r)
          -- Defined in `Development.Shake.Command'
        instance (Development.Shake.Command.Arg a, CmdArguments r) =>
                 CmdArguments (a -> r)
          -- Defined in `Development.Shake.Command'
        ...plus one other
        (use -fprint-potential-instances to see them all)
    * In the expression: cmd "pkg-config glib-2.0 --cflags"
      In an equation for `i': i = cmd "pkg-config glib-2.0 --cflags"
      In the expression:
        do { let c = dropDirectory1 $ out -<.> "cxx";
             let m = out -<.> "m";
             let i = cmd "pkg-config glib-2.0 --cflags";
             () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i];
             .... }

Build.hs:30:15: error:
    * Ambiguous type variable `t0' arising from a use of `cmd'
      prevents the constraint `(Development.Shake.Command.Arg
                                  [t0])' from being solved.
      Relevant bindings include i :: t0 (bound at Build.hs:29:13)
      Probable fix: use a type annotation to specify what `t0' should be.
      These potential instances exist:
        instance Development.Shake.Command.Arg [CmdOption]
          -- Defined in `Development.Shake.Command'
        instance Development.Shake.Command.Arg [String]
          -- Defined in `Development.Shake.Command'
        instance Development.Shake.Command.Arg String
          -- Defined in `Development.Shake.Command'
    * In a stmt of a 'do' block:
        () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i]
      In the expression:
        do { let c = dropDirectory1 $ out -<.> "cxx";
             let m = out -<.> "m";
             let i = cmd "pkg-config glib-2.0 --cflags";
             () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i];
             .... }
      In the second argument of `(%>)', namely
        `\ out
           -> do { let ...;
                   let ...;
                   .... }'

I would appreciate any help in getting the output of the call to
pkg-config into the compiler invocation.

Thanks,
Roger


More information about the Beginners mailing list