Hello World (for windows)

57 views
Skip to first unread message

dneu...@gmail.com

unread,
Jan 8, 2015, 1:23:52 PM1/8/15
to shake-bui...@googlegroups.com
Hi,

I was wondering if there is a simple 'Hello World' style example for building using visual studio on windows?

I've run into some issues trying to implement it myself and wanted to peek at an implementation.

Thank you,
-= Dave

Neil Mitchell

unread,
Jan 8, 2015, 5:06:09 PM1/8/15
to dneu...@gmail.com, shake-bui...@googlegroups.com
Hi Dave,

Nothing public that I'm aware of, although I've certainly done it at
work, so it is possible.

When you say "visual studio", do you mean using "devenv" to compile
projects, something like "fsc" or "csc" to compile sets of managed
code files, or "cl" in a more traditional C single-file-but-headers
mode? Each of them tend to end up with very different build systems.
If you can describe some of the areas you were getting stuck on I can
tell you how I did it.

Thanks, Neil

dneu...@gmail.com

unread,
Jan 8, 2015, 7:50:42 PM1/8/15
to shake-bui...@googlegroups.com, dneu...@gmail.com
Hi Neil,

I do mean devenv with using cl.exe and link.exe. I was hoping to peek at something but since there isn't anything public I'll take another stab at it before I bug you further.

Thanks!

Neil Mitchell

unread,
Jan 9, 2015, 10:31:07 AM1/9/15
to David Neubelt, shake-bui...@googlegroups.com
Hi Dave,

So cl and link work pretty much like gcc -c and gcc respectively. The
one thing cl lacks is an equivalent to gcc -M which dumps out a
Makefile with dependencies. Either you can scan manually for #include
files as per http://shakebuild.com/manual#generated-imports, or you
can use the -showincludes flag to cl, as shown at
http://shakebuild.com/manual#include-files-with-visual-studio .
Porting the example from http://shakebuild.com/manual shouldn't take
too long with the -showincludes approach, and is probably worth
including in the manual.

Thanks, Neil

dneu...@gmail.com

unread,
Jan 12, 2015, 4:05:00 PM1/12/15
to shake-bui...@googlegroups.com, dneu...@gmail.com
Ok, I took a quick stab at this but my Haskell is pretty bad so bare with me.

With the code below I'm getting an error about the cl.exe not existing but copying and pasting the error output in windows explorer shows that the path is correct.

I suspect the problem is the createProcess call needs to have quotes around the executable name to allow for spaces in path.

What would you recommend doing? My Haskell isn't the greatest so sorry about that!

d:\work\personal\testllvm>build
# cl.exe -showincludes -c (for _build/hello.o)
Error when running Shake build system:
* _build/run.exe
* _build/hello.o
user error (Development.Shake.cmd, system command failed
Command: C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin/amd64/cl.exe -showincludes -c hello.cpp -Fo_build/hello.obj
C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin/amd64/cl.exe -showincludes -c: createProcess: does not exist (No such file or directory))



import Development.Shake
import Development.Shake.Command
import Development.Shake.FilePath
import Development.Shake.Util
import Data.List
import Data.Char

main :: IO ()
main = shakeArgs shakeOptions{shakeFiles="_build/"} $ do
want ["_build/run" <.> exe]

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

"_build/run" <.> exe %> \out -> do
cs <- getDirectoryFiles "" ["//*.c"]
let os = ["_build" </> c -<.> "o" | c <- cs]
need os
cmd "gcc -o" [out] os

"_build//*.o" %> \out -> do
let input = dropDirectory1 $ out -<.> "cpp"
let output = out -<.> "obj"

let rad_visual_studio_dir = "C:/Program Files (x86)/Microsoft Visual Studio 10.0"
let cc = rad_visual_studio_dir ++ "/VC/bin/amd64/cl.exe"
let link = rad_visual_studio_dir ++ "/VC/bin/amd64/link.exe"

let cmdline = cc ++ " -showincludes -c"
Stdout stdout <- cmd [cmdline] [input] ["-Fo" ++ output]
need [ dropWhile isSpace x
| x <- lines stdout
, Just x <- [stripPrefix "Note: including file:" x]]

Neil Mitchell

unread,
Jan 12, 2015, 4:26:07 PM1/12/15
to David Neubelt, shake-bui...@googlegroups.com
With 'cmd' each argument is treated as either a list of space
separated arguments (if it's a String) or a list of arguments (if it's
a [String]). In your case, you probably want to write:

Stdout stdout <- cmd [cc] "-showincludes -c" [input] ["-Fo" ++ output]

Specifically cc needs to be a [String] since it contains a space in
it, and you can't join -showincludes to it with ++ or that gets
interpreted as the executable too.

Can you try that and report back if it works?

Thanks, Neil

PS. Certainly no problems with the Haskell above, just the
conventions/rules Shake uses :)

dneu...@gmail.com

unread,
Jan 12, 2015, 4:58:08 PM1/12/15
to shake-bui...@googlegroups.com, dneu...@gmail.com
Hi Neil,

That does work! Thank you.

I will add the include paths and try and clean up the code a little bit more and post a full working example so if anyone comes across this post in the future they can copy paste it in to get started.

-= Dave

dneu...@gmail.com

unread,
Jan 15, 2015, 5:04:50 PM1/15/15
to shake-bui...@googlegroups.com, dneu...@gmail.com
Hi,

Just got back to playing around with this again.

I was getting an error because the compiler didn't know where a standard include was (stdio.h). This is easy to fix because you need to call vcvars.bat which sets up all includes and directories before you compile.

However, shake never reported the error and just reported that it failed to compile. I had to extract the command line and run it again in the command line to get the real error.

Shake Reports the follow
===================================================================
Error when running Shake build system:
* _build/run.exe
* _build/hello.o
user error (Development.Shake.cmd, system command failed
Command: C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/amd64/cl.exe /showIncludes /c hello.cpp /Fo_build/hello.obj
Exit code: 2
Stderr:
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

)
===================================================================


While running from the command line reports the following

===================================================================
D:\work\personal\testllvm>"C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/amd64/cl.exe" /showIncludes /c hello.cpp /Fo_build/hello.obj
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

hello.cpp
hello.cpp(1) : fatal error C1034: stdio.h: no include path set
===================================================================

Am I not extracting the output in shake correctly to display the errors to the users?

Thanks,
-= Dave

Neil Mitchell

unread,
Jan 15, 2015, 5:29:36 PM1/15/15
to David Neubelt, shake-bui...@googlegroups.com
Hi Dave,

Could it be that cl is putting the error out on Stdout, rather than
Stderr? You can tell by doing "... > nul" (drop the stdout) and "...
2> nul" (drop the stderr).

You are using Stdout capturing so you can parse it for showIncludes,
and by default capturing Stdout stops it being written to the console.
If you add (EchoStdout True) to the cmd line that overrides it, so you
can do:

Stdout stdout <- cmd (EchoStdout True) [cc] "-showincludes -c"
[input] ["-Fo" ++ output]

There is currently a WithStderr which includes the Stderr in the
exception if a command fails. If cl really is putting the errors to
stdout, I should probably add WithStdout so you can ask for the Stdout
in the exception as well.

Thanks, Neil

dneu...@gmail.com

unread,
Jan 15, 2015, 6:41:40 PM1/15/15
to shake-bui...@googlegroups.com, dneu...@gmail.com
Hi Neil,

If I add the (EchoStdout True) I do get the error. Here is what the output now looks like.

===========================================================================
D:\work\personal\testllvm>REM CALL "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"
# cl.exe (for _build/hello.o)
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

hello.cpp
hello.cpp(1) : fatal error C1034: stdio.h: no include path set
Error when running Shake build system:
* _build/run.exe
* _build/hello.o
user error (Development.Shake.cmd, system command failed
Command: C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/amd64/cl.exe /showIncludes /c hello.cpp /Fo_build/hello.obj
Exit code: 2
Stderr:
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

)
===========================================================================

In there it does show the hello.cpp(1) : fatal error c1034: stdio.h: no include path set.

I wonder if we can parse the std output so we can find the relevant error message so users have an easier time finding what exactly failed. There is a lot of extra things in stdout that clutter it.

Neil Mitchell

unread,
Jan 16, 2015, 2:00:06 AM1/16/15
to David Neubelt, shake-bui...@googlegroups.com
> I wonder if we can parse the std output so we can find the relevant error message so users have
> an easier time finding what exactly failed. There is a lot of extra things in stdout that clutter it.

That's exactly the reason compilers are mean't to use stderr, rather
annoying that cl doesn't follow the convention.

You can certainly do (Stdout x, Stderr y, Exit i) <- cmd ...; when (i
/= 0) $ error $ show $ myFilter (x ++ y)

It's a bit of a hassle though, and the risk is you might hide the
important bit. I suggest you pass -nologo to the compiler, to strip
out the copyright message.

There's also a chance that Shake has messed this up, and is displaying
the Stdout not the Stderr (they look 100% reversed to me, so either cl
is wrong or Shake is) so I'll have a quick check of that.

Ryan

unread,
Jan 16, 2015, 11:51:05 AM1/16/15
to Neil Mitchell, David Neubelt, shake-bui...@googlegroups.com
I think it's a cl issue.
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
Check out my website: http://kirbyfan64.github.io/

dneu...@gmail.com

unread,
Jan 16, 2015, 1:46:23 PM1/16/15
to shake-bui...@googlegroups.com, ndmit...@gmail.com, dneu...@gmail.com
According to the documentation of /showIncludes the option emits to stderr, not stdout.

http://msdn.microsoft.com/en-us/library/hdkef6tk.aspx

Also, testing cl.exe on the command line we get this

1) Normal
========================================================================
d:\work\personal\testllvm>"C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/amd64/cl.exe" /showIncludes /c hello.cpp /Fo_build/hello.obj
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

hello.cpp
hello.cpp(1) : fatal error C1034: stdio.h: no include path set
========================================================================

2) Discard the standard output 1> nul and leave only standard error
========================================================================
d:\work\personal\testllvm>"C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/amd64/cl.exe" /showIncludes /c hello.cpp /Fo_build/hello.obj 1> nul
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.


========================================================================

3) Discard the standard error stream 2> nul and only leave standard output
========================================================================
d:\work\personal\testllvm>"C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/amd64/cl.exe" /showIncludes /c hello.cpp /Fo_build/hello.obj 2> nul
hello.cpp
hello.cpp(1) : fatal error C1034: stdio.h: no include path set
========================================================================

Neil Mitchell

unread,
Jan 18, 2015, 2:01:13 PM1/18/15
to David Neubelt, shake-bui...@googlegroups.com
Weird, it does seem like cl gets Stdout and Stderr completely wrong!
I've raised https://github.com/ndmitchell/shake/issues/205 which will
give you enough control to reverse them. I think these subtleties mean
that a cl based example as part of the manual is a very good idea.

dneu...@gmail.com

unread,
Jan 18, 2015, 2:41:23 PM1/18/15
to shake-bui...@googlegroups.com, dneu...@gmail.com
On Sunday, January 18, 2015 at 11:01:13 AM UTC-8, Neil Mitchell wrote:
> Weird, it does seem like cl gets Stdout and Stderr completely wrong!
> I've raised https://github.com/ndmitchell/shake/issues/205 which will
> give you enough control to reverse them.
Awesome, great! I subscribed and will give shake a try again when you've added that flag.

> I think these subtleties mean
> that a cl based example as part of the manual is a very good idea.

Yah that would definitely help. I've got two example windows batch files that compile and link a hello world with visual studio 13 (free download). One batch file uses vcvars.bat to setup the environment and include/lib directories. Another batch file that is more explicit and sets all the lib/include directories explicitly. If you need them to help make your example let me know.

-= Dave
Reply all
Reply to author
Forward
0 new messages