January 22, 2018
A C++ Hello World And A Glass Of Wine, Oh My !
#include <iostream>
int main() {
std::cout << "Hello, World\n";
}
Nothing to remove, nothing to add.
This is the proper “Hello World” in C++. All the others Hello World are wrong. But this is not where I rant about how using namespace std; crystallizes everything messed up with the teaching of C++. Another time perhaps.
Today we are gonna be compiling that hello world so that it can be executed on a target system.
But first, let me tell you a few things about me. I use Linux for fun and profit. I happen to think it is the best system. For me. As a developer. Sometimes, I look down on developers using Windows, wondering how the eff they manage to get anything done by clicking on things. And it is likely that a vim user on Arch looks down on me for using Ubuntu. Nobody’s perfect.
Anyway, let’s fire up a terminal
# sudo apt-get install g++
# g++ -o helloworld helloworld.cpp
# ./helloworld
Hello, World!
#
Nice, That’s simple, let’s go home and have a beer 🍻 !
But then, enters my boss. They are in the business of selling software to people who use Windows. I try to show them that I can make a cow speak and that I can resize my terminal so we should obviously move all our business to Linux at once, they say something incomprehensible about market shares and apparently, they can resize their command prompt too.
After looking down at each other for a while like we are stuck in an Escher painting, I grudgingly remember that I’m in the business of making my clients happy, and so we are going to port our hello world application to Windows. Our boss doesn’t care what environment we use to create that ground breaking app, and they don’t have an issue with me continuing working on the Linux version at the same time, so I’ve decided to develop that application for Windows, on Linux; what could possibly go wrong ?
Besides, it will then be far easier to set up a build farm and continuous integration. You could even have your CI provision fresh docker containers on the fly to build the windows app in a controlled and fresh environment. While I tend to think that Dockers is a bit of a cargo cult, Using Docker along Jenkins is actually something that makes a lot of sense. And if you like your sysadmin, don’t force them to deal with Windows servers.
We should strive to make your application as portable and platform agnostic as possible, so having a windows version of our application may actually make our code better. That’s what I try to tell myself.
As it turns out, Microsoft is nice enough to offer a compiler for windows called msvc, and I have the feeling that msvcis a better choice on windows than g++since that’s the compiler the whole ecosystem is designed around. And hopefully Microsoft knows their own tools, formats and calling convention best. I never went the extra mile to benchmark that though, and you will find proponents of either approach on internet. But, The MSVC team agrees with me. Shocker.
Anyway, for now, let’s stick to that.
# apt-get install msvc
E: Unable to locate package msvc
Surprisingly, that doesn’t work. You can’t blame a guy for trying. But to explain why, let me tell you how a compiler works.
A compiler opens a file, transforms the content of that file into something that can be executed, and writes that out to some other file. Sometime you have more than one source file, so you need a linker which is a program which opens a bunch of files and writes an executable down. An executable is a file, nothing magical about it. Sometimes you need libraries. A library is a file. And you mostly likely need tons of headers which are… you get it, files. plain old boring files. The executable is then loaded by another executable which is also a file, it’s files all the way down. Ok, maybe not, Plan 9 has more files.
To be clear, compilers are extremely complex pieces of engineering, especially C++ compilers and you should offer a cookie to all the compiler writers you meet. However, from a system-integration point-of-view, they are as trivial as it gets. Most compilers don’t even bother with threads. They let the build system deal with that. Which is unfortunate since most build systems have yet to learn how to tie their shoe laces.
Anyway…here is the list of kernel facilities you need to write a compiler:
-
Opening, Reading and Writing files
-
Reading directories content
-
Allocating memory
You may therefore be thinking that this is a reasonable enough list, and so, you wonder why msvc isn’t available on Linux. Sure, having msvc build Linux/ELF applications would be a huge and probably pointless undertaking, but all we want is to build an application for Windows, and surely Microsoft would make it easy as possible for me to do so, right?
But there is this thing. Windows is an “ ecosystem “. It means they want to sell their OS to both their users and their developers, sell their tools to developers, and make sure nobody learn about that other OS legends speak of. So if you want to build a windows application, you need Windows. Crap.
Fortunately, someone rewrote Windows on Linux and called that wine. Probably because they had to be very drunk to even think about doing it. It took merely 15 years for wine to reach 1.0. But it’s in 3.0now, so maybe we can use it ? There are minor miracles in the open source community and WINE is certainly one of them.
For a very long time, MSVC was bundled with Visual Studio. Which mean that if you wanted to compile a C++ app on windows using Qt creator, CLion, Eclipse or notepad++, you still had to have Visual Studio. Ecosystem and all that.
Things are better now, you can install the “build tools” such that you will only need to install about 5GB of… stuffs. Let’s do that.
Oh, apparently the compiler is distributed as an executable which then downloads stuffs you didn’t asked for over the internet. Maybe it’s better than a 40GB zip ?
# wine vs_BuildTools.exe
The entry point method could not be loaded
Are you surprised? My dreams are crushed. We do need a windows to do some windows development ( spoiler : it gets better ).
Let’s fire up a VM. If you want to follow along, I recommend that you use a new or cloned Windows 10 VM. We are gonna install a lot of weird things and it will be next to impossible to clean up after ourselves. Afterwards you may get rid of the VM.
Once that’s done, we can go and download the VS build tools.
Scroll down until you get carpal tunnel. The build tools is the second to last item. Download that.
I had a few issues launching the installer. I think they try to contact a server that managed to get itself in a list of ad servers so my DNS blocked it. Don’t ask.
Installers with loading screens, it’s perfectly normal. Once it’s done, it loads the main UI, slowly and painfully but then we get to check boxes. I’m having a blast.