using Shake to compile c++

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

using Shake to compile c++

Roger Mason
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
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: using Shake to compile c++

David McBride
The easy option is to just use command instead of cmd.  Variadic
functions are always a little weird to type check.

command_ [] "pkg-config" ["glib-2.0","--cflags"]

That will *probably* solve the ambiguity in both lines, but I haven't tested.

On Sat, Jul 8, 2017 at 7:19 AM, Roger Mason <[hidden email]> wrote:

> 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
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: using Shake to compile c++

David McBride
Sorry that should have been command, not command_ which is very different.

On Sat, Jul 8, 2017 at 7:37 AM, David McBride <[hidden email]> wrote:

> The easy option is to just use command instead of cmd.  Variadic
> functions are always a little weird to type check.
>
> command_ [] "pkg-config" ["glib-2.0","--cflags"]
>
> That will *probably* solve the ambiguity in both lines, but I haven't tested.
>
> On Sat, Jul 8, 2017 at 7:19 AM, Roger Mason <[hidden email]> wrote:
>> 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
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: using Shake to compile c++

Roger Mason
David McBride <[hidden email]> writes:

> Sorry that should have been command, not command_ which is very different.
>
> On Sat, Jul 8, 2017 at 7:37 AM, David McBride <[hidden email]> wrote:
>> The easy option is to just use command instead of cmd.  Variadic
>> functions are always a little weird to type check.
>>
>> command_ [] "pkg-config" ["glib-2.0","--cflags"]
>>
>> That will *probably* solve the ambiguity in both lines, but I haven't tested.

Thank you for your replies.

This is what I have now:

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

That produces:

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

Build.hs:30:15: error:
    * No instance for (Development.Shake.Command.Arg [Action r0])
        arising from a use of `cmd'
    * 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 = command ... "pkg-config" ...;
             () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i];
             .... }
      In the second argument of `(%>)', namely
        `\ out
           -> do { let ...;
                   let ...;
                   .... }'

Thanks again,
Roger
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Fwd: using Shake to compile c++

David McBride
Sorry this should have been sent to the list.

---------- Forwarded message ----------
From: David McBride <[hidden email]>
Date: Sat, Jul 8, 2017 at 8:49 AM
Subject: Re: [Haskell-beginners] using Shake to compile c++
To: Roger Mason <[hidden email]>


There's three errors here.  pkg-config is an IO action and thus in
order to use its output, you must use <- instead of a let binding.
Then you must choose what you want to save from that command.  You
could get the exit result, stderr or stdout or both stdout and stderr.
We want stdout.  And lastly, Stdout is parameterized over a type a,
and you have to decide which.

You can either do the following

Stdout i <- cmd "pkg-config glib-2.0 --cflags"
() <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i :: String]

Or you can enable ScopedTypeVariables and go
Stdout (i :: String) <- cmd "pkg-config glib-2.0 --cflags"

I don't really understand why Stdout is parameterized, rather than
just being forced to be a string like Stdin, that's a question for the
shake authors.

On Sat, Jul 8, 2017 at 7:57 AM, Roger Mason <[hidden email]> wrote:

> David McBride <[hidden email]> writes:
>
>> Sorry that should have been command, not command_ which is very different.
>>
>> On Sat, Jul 8, 2017 at 7:37 AM, David McBride <[hidden email]> wrote:
>>> The easy option is to just use command instead of cmd.  Variadic
>>> functions are always a little weird to type check.
>>>
>>> command_ [] "pkg-config" ["glib-2.0","--cflags"]
>>>
>>> That will *probably* solve the ambiguity in both lines, but I haven't tested.
>
> Thank you for your replies.
>
> This is what I have now:
>
>  "objects//*.o" %> \out -> do
>         let c = dropDirectory1 $ out -<.> "cxx"
>         let m = out -<.> "m"
>         let i = command [] "pkg-config" ["glib-2.0","--cflags"]
>         () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i]
>         needMakefileDependencies m
>
> That produces:
>
> Build.hs:29:17: error:
>     * Ambiguous type variable `r0' arising from a use of `command'
>       prevents the constraint `(CmdResult r0)' from being solved.
>       Relevant bindings include i :: Action r0 (bound at Build.hs:29:13)
>       Probable fix: use a type annotation to specify what `r0' should be.
>       These potential instances exist:
>         instance CmdResult CmdLine
>           -- Defined in `Development.Shake.Command'
>         instance CmdResult CmdTime
>           -- Defined in `Development.Shake.Command'
>         instance CmdResult Exit -- Defined in `Development.Shake.Command'
>         ...plus 9 others
>         ...plus two instances involving out-of-scope types
>         (use -fprint-potential-instances to see them all)
>     * In the expression:
>         command [] "pkg-config" ["glib-2.0", "--cflags"]
>       In an equation for `i':
>           i = command [] "pkg-config" ["glib-2.0", "--cflags"]
>       In the expression:
>         do { let c = dropDirectory1 $ out -<.> "cxx";
>              let m = out -<.> "m";
>              let i = command ... "pkg-config" ...;
>              () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i];
>              .... }
>
> Build.hs:30:15: error:
>     * No instance for (Development.Shake.Command.Arg [Action r0])
>         arising from a use of `cmd'
>     * 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 = command ... "pkg-config" ...;
>              () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i];
>              .... }
>       In the second argument of `(%>)', namely
>         `\ out
>            -> do { let ...;
>                    let ...;
>                    .... }'
>
> Thanks again,
> Roger
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Fwd: using Shake to compile c++

Roger Mason
David McBride <[hidden email]> writes:

> Sorry this should have been sent to the list.
>
> ---------- Forwarded message ----------
> From: David McBride <[hidden email]>
> Date: Sat, Jul 8, 2017 at 8:49 AM
> Subject: Re: [Haskell-beginners] using Shake to compile c++
> To: Roger Mason <[hidden email]>
>
>
> There's three errors here.  pkg-config is an IO action and thus in
> order to use its output, you must use <- instead of a let binding.
> Then you must choose what you want to save from that command.  You
> could get the exit result, stderr or stdout or both stdout and stderr.
> We want stdout.  And lastly, Stdout is parameterized over a type a,
> and you have to decide which.
>
> You can either do the following
>
> Stdout i <- cmd "pkg-config glib-2.0 --cflags"
> () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i :: String]
>
> Or you can enable ScopedTypeVariables and go
> Stdout (i :: String) <- cmd "pkg-config glib-2.0 --cflags"
>
> I don't really understand why Stdout is parameterized, rather than
> just being forced to be a string like Stdin, that's a question for the
> shake authors.

For the record, I have currently

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

and get

Build.hs:31:59: error:
    * Couldn't match type `[Char]' with `Char'
      Expected type: String
        Actual type: [FilePath]
    * In the expression: i :: String
      In the 7th argument of `cmd', namely `[i :: String]'
      In a stmt of a 'do' block:
        () <- cmd "c++ -c" [c] "-o" [out] "-MMD -MF" [m] [i :: String]

I thank you very much for your help but it is clear that the use of
Shake requires rather more Haskell knowledge than is implied by the
docs.  Given that this is just the easy part of the build the prospects
for early success look scant so I will move on and try something else.

Thanks again,
Roger
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Loading...