{"id":131,"date":"2016-07-29T22:59:36","date_gmt":"2016-07-29T22:59:36","guid":{"rendered":"http:\/\/www.jacobpike.com\/blog\/?p=131"},"modified":"2016-07-29T23:49:41","modified_gmt":"2016-07-29T23:49:41","slug":"on-c-build-systems","status":"publish","type":"post","link":"https:\/\/www.jacobpike.com\/blog\/2016\/07\/29\/on-c-build-systems\/","title":{"rendered":"On C++ Build Systems"},"content":{"rendered":"<p>I&#8217;ve been thinking about C++ build systems a lot recently. \u00a0I like programming in C++ a lot (relatively speaking), but I don&#8217;t think it&#8217;s news to anyone that the build system leaves a lot to be desired (dependency management, header + .cpp files, etc.).<\/p>\n<p>It all started back when I started watching <a href=\"https:\/\/handmadehero.org\/\">Handmade Hero<\/a>. \u00a0Rather than using some complex build systems or even an IDE like Visual Studio, Casey Muratori just used a simple\u00a0<em>build.bat<\/em> file to call the compiler. \u00a0I&#8217;m certainly no fan of batch as a language, but the simplicity of the build script along with the ease of understanding exactly how your program is compiled\/linked were appealing. \u00a0He also basically just compiled 1 single .cpp file (which obviously simplifies things) &#8211; often called a &#8220;unity&#8221; or &#8220;single translation unit&#8221; build.<\/p>\n<p>The next major piece came when <a href=\"https:\/\/www.youtube.com\/playlist?list=PLmV5I2fxaiCKfxMBrNsU1kgKJXD3PkyxO\">watching videos<\/a> for Jonathan Blow&#8217;s new &#8220;Jai&#8221; language. \u00a0One critical point Jon makes is that we probably should be writing our build scripts\u00a0<em>in the language we&#8217;re programming in<\/em> &#8211; why bother learning some other (and often inferior) language just to build your program?<\/p>\n<p>There is one point where I differ from\u00a0Jon and Casey &#8211; I actually like using Visual Studio a lot. \u00a0I don&#8217;t necessarily like everything about it (notably the project files), but on the whole, I feel like the Visual Studio IDE makes me more productive compared to other alternative I&#8217;ve tried.<\/p>\n<p>Anyway, it&#8217;s probably going to be some time before &#8220;Jai&#8221; or another language supplants C++. \u00a0So I was wondering&#8230;why not try and get most of the benefits mentioned above in C++?<\/p>\n<p><strong>Goals<\/strong><\/p>\n<p>Before we go any further, let me explicitly state some of the goals for my idea for a better C++ build system\/IDE integration:<\/p>\n<ul>\n<li>Build via the command line with minimal options to remember.<\/li>\n<li>Build via Visual Studio.<\/li>\n<li>Not specify a bunch of files when building.<\/li>\n<li>Easily understand exactly how a program is built.<\/li>\n<li>Easily tweak how a program is built.<\/li>\n<li>Minimize dependencies on non-native tools (outside of the language, operating system, and Visual Studio).<\/li>\n<li>Not manually manage Visual Studio solution, project, etc. files.<\/li>\n<li>Easily find all files for a project within Visual Studio.<\/li>\n<li>Edit files within Visual Studio.<\/li>\n<li>Debug within Visual Studio.<\/li>\n<li>Simplicity.<\/li>\n<\/ul>\n<p>Prior to work put in for this blog post, I played around some with the\u00a0<em>build.bat <\/em>and\u00a0unity build ideas, both from the command line and within Visual Studio (generating solution\/project files manually using the IDE).<\/p>\n<p><strong>The Build Script<\/strong><\/p>\n<p>From the above, the simplest\u00a0idea for meeting the &#8220;build&#8221; requirements is the\u00a0<em>build.bat\u00a0<\/em>idea. \u00a0Batch files are built into Windows, and the complexity needed to call the compiler isn&#8217;t so large that it drives me crazy using the batch language.<\/p>\n<p>All we really need to do to generate such a build script is have a program write out a basic text file, with a few possible parameters tweaked. \u00a0Very simple &#8211; the text could be\u00a0easily embedded as strings in a program.<\/p>\n<p>The basic\u00a0<em>build.bat<\/em> file Casey Muratori created for Handmade Hero can be used as a starting point. \u00a0On tweak I might like to make (haven&#8217;t fully settled on this yet) is automatically calling the\u00a0<em>VCVARSALL<\/em> batch file in the build script &#8211; that way, I don&#8217;t have to worry about making sure the appropriate settings are always set. \u00a0Unfortunately, one downside to this from my experience is that sometimes you&#8217;ll get an error about a command\/path being too long if you repeatedly run the\u00a0<em>build.bat<\/em> file in the same command prompt Window. \u00a0I haven&#8217;t run into any problems with this in Visual Studio yet though.<\/p>\n<p>Deciding exactly what compiler flags\/settings or other parameters to include in the\u00a0<em>build.bat<\/em> file is tricky. \u00a0I&#8217;m not sure exactly what I personally want yet, but it might be different from what Handmade Hero has. \u00a0For now, punting and just having a basic build script for building a debug build is fine.<\/p>\n<p>I might want to actually wrap a lot of the options in the build script in a separate C++ program &#8211; that wouldn&#8217;t certainly make supporting advanced options\/features easier. \u00a0Of course, that has the trade-off of being another program people would have to download\/build.<\/p>\n<p><strong>On &#8220;Unity&#8221; Builds<\/strong><\/p>\n<p>Before moving on, just a few comments on &#8220;unity&#8221; or &#8220;single translation unit&#8221; builds. \u00a0They&#8217;re definitely an interesting idea, with a nice benefit of speeding up build times.<\/p>\n<p>One thing I definitely like about the idea is that you only have to specify 1 file when passed to the compiler &#8211; no need to manually manage a bunch of them.<\/p>\n<p>However, I&#8217;m not completely sold on the idea, as it sort of requires restructuring how you right code in an unconventional manner. \u00a0And while I have no concrete evidence for it, it seems like structuring code\/builds this way might complicate re-use\u00a0in large code bases where you want to use code across multiple projects. \u00a0I&#8217;d like to still write my code in a more &#8220;conventional&#8221; C++ way (many separate files, including the less-than-ideal header + .cpp files) to avoid risks in going all-in with a unity build.<\/p>\n<p>How can we get around these conflicts? \u00a0Well, Jonathan Blow&#8217;s idea of specifying your build in your regular programming language provides some hints. \u00a0We can create a separate file that just #includes all of the .cpp files we want to compile &#8211; no need to write the rest of your code in an odd way.<\/p>\n<p>This actually works pretty well from my testing, but it isn&#8217;t perfect. \u00a0In particular, I was hoping that this file with just a bunch of #includes could end with a file extension other than .cpp, but the Visual Studio compiler doesn&#8217;t seem to be able to compile files with other extensions (if you know a way around this, let me know). \u00a0The idea of not modifying your &#8220;other&#8221; .h\/.cpp files almost may not be 100% feasible &#8211; from my testing, I&#8217;ve had to make a few modifications\/re-order certain things &#8211; but the modifications have been relatively minimal so far to a point where it wouldn&#8217;t be much of a burden (or maybe no burden at all) if I wanted to return to a &#8220;conventional&#8221; C++ build model.<\/p>\n<p>It might be nice to generate this .cpp file with just a bunch of #includes automatically one day, but there might be some challenges, and it&#8217;s certainly not at the top of my priority list.<\/p>\n<p><strong>Visual Studio Project Files<\/strong><\/p>\n<p>As mentioned above, I&#8217;ve manually created Visual Studio solution\/project files for C++ projects using a build.bat + unity build approach. \u00a0But I don&#8217;t like having to manually add all files in my project or tweak various build settings.<\/p>\n<p>How to solve this problem? \u00a0Well, for the most part, the Visual Studio solution\/project files can basically just be copied, meaning that we can embed most of the text directly in a simple program. \u00a0There are some unique IDs in the files, but at least from my testing, re-using them doesn&#8217;t seem to be a problem.<\/p>\n<p>What remains then? \u00a0Well, basically just getting a list of files\/folders to include in the Visual Studio project and project filters files. \u00a0Recursively getting a list of files\/folders in a directory&#8230;that doesn&#8217;t seem too hard, right? \u00a0While the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa364418(v=vs.85).aspx\">Windows API<\/a> for <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa364428(v=vs.85).aspx\">doing this<\/a> isn&#8217;t super ideal in my opinion, it&#8217;s not too complicated. \u00a0So doing this should be pretty easy.<\/p>\n<p><strong>Let&#8217;s Do This&#8230;Well, Already Done&#8230;<\/strong><\/p>\n<p>I was planning to originally write this blog post\u00a0before I went and tried to implement any of it. \u00a0But feeling extra motivated about this recently, I actually went and recently implemented a lot of the basics for what I want (as described above). \u00a0And it didn&#8217;t take that long &#8211; maybe around 3-5 hours total (at night after work). \u00a0Given a folder of code and using the quick program I wrote, I can automatically generate a Visual Studio solution\/project and build.bat script\u00a0<em>that actually works\u00a0<\/em>(minus project-specific build tweaks).<\/p>\n<p>It&#8217;s far from &#8220;complete&#8221; &#8211; I&#8217;ve only tested it on one specific project so far, the build.bat script is most definitely insufficient, and there aren&#8217;t a lot of options. \u00a0I&#8217;ll add improvements as I find I need them, but it&#8217;s &#8220;good enough&#8221; now to at least put out there.<\/p>\n<p>The code is available <a href=\"https:\/\/github.com\/jpike\/VisualCppProjectGenerator\">here on GitHub<\/a>. \u00a0I hope it will be helpful to some others out there. \u00a0If you have any suggestions, feel free to forward them to me. \u00a0Although, since I&#8217;m making the code itself public domain, you&#8217;re certainly more than welcome to make your own changes to suit your needs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been thinking about C++ build systems a lot recently. \u00a0I like programming in C++ a lot (relatively speaking), but I don&#8217;t think it&#8217;s news to anyone that the build system leaves a lot to be desired (dependency management, header + .cpp files, etc.). It all started back when I started watching Handmade Hero. \u00a0Rather &hellip; <a href=\"https:\/\/www.jacobpike.com\/blog\/2016\/07\/29\/on-c-build-systems\/\" class=\"more-link\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-131","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/posts\/131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/comments?post=131"}],"version-history":[{"count":7,"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/posts\/131\/revisions"}],"predecessor-version":[{"id":138,"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/posts\/131\/revisions\/138"}],"wp:attachment":[{"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/media?parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/categories?post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jacobpike.com\/blog\/wp-json\/wp\/v2\/tags?post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}