{"id":176,"date":"2015-11-12T22:51:00","date_gmt":"2015-11-12T22:51:00","guid":{"rendered":"http:\/\/blog.paranoidprofessor.com\/?p=176"},"modified":"2018-11-15T21:03:04","modified_gmt":"2018-11-15T21:03:04","slug":"becoming-a-developer-makefiles","status":"publish","type":"post","link":"https:\/\/blog.paranoidprofessor.com\/index.php\/2015\/11\/12\/becoming-a-developer-makefiles\/","title":{"rendered":"Becoming a developer &#8211; makefiles"},"content":{"rendered":"<p>Each programming language has its own set of commands for turning source code into a executable program.\u00a0 Back in the olden days this was done using an old and by today&#8217;s standards a tool with limited functionality.\u00a0 This tool as call make and when combined with a configuration file called the Makefile it would perform a number of steps utilizing any of the programs installed on your computer to generate your executable.for<\/p>\n<p>Usually, the steps are easy to transform source code into programs, at least in theory.<\/p>\n<h3>hello.h<\/h3>\n<pre><code>#define TEXT \"hello world!\"\r\n<\/code><\/pre>\n<h3>hello.c<\/h3>\n<pre><code>#include \r\n#include \"hello.h\"\r\n\r\nint main(int argc, char **args)\r\n{\r\nprintf(\"%s\\n\", TEXT);\r\nreturn 0;\r\n}<\/code><\/pre>\n<p>You invoke the name of the compiler to read the source code and output the finished program.<\/p>\n<blockquote><p>gcc hello.c -o helloworld<\/p><\/blockquote>\n<p>The compiler reads in hello.c and creates the program with the name helloworld.<\/p>\n<p>Yet, that is too simplistic for pretty much all commercial programs in the world.\u00a0 For programs\u00a0 more complicated than this the code base is usually split across possibly dozens or even hundreds of files.\u00a0 It would be too much work just to type all the names on the command line each time.\u00a0 One possibility, which is pretty inefficient, is to have a script to compile all files every time it is executed.\u00a0 This is inefficient as it will compile all files even if only a single file has changed.<\/p>\n<p>The goal of the make utility is to allow us to define relationships between the various source files.\u00a0 Thus only the minimum subset of files are rebuilt when a change occurs.<\/p>\n<p>The two important concepts is that of dependencies and and targets.\u00a0 You simply define a target, ie a set of rules to be executed, whenever one of the dependencies is newer.<\/p>\n<p>&nbsp;<\/p>\n<h3>Anatmony of a Makefile<\/h3>\n<pre><code>CFLAGS = -Wall -I.\r\nHEADER = hello.h\r\nSOURCE = hello.c\r\nTARGET = helloworld\r\n\r\nall:    $(TARGET)\r\n\r\n$(TARGET): $(SOURCE) $(HEADER)\r\n        gcc $(CFLAGS) $(SOURCE) -o $@ \r\n<\/code><\/pre>\n<p>Make has variables called macros.\u00a0 There are a few special predefined macros which when are evaluated return either a file or rule name.<\/p>\n<table width=\"100%\">\n<tbody>\n<tr>\n<td width=\"10%\">$@<\/td>\n<td align=\"left\" width=\"90%\">name of the target rule name<\/td>\n<\/tr>\n<tr>\n<td width=\"10%\">$?<\/td>\n<td align=\"left\" width=\"90%\">list of dependencies more recent than target<\/td>\n<\/tr>\n<tr>\n<td width=\"10%\">$^<\/td>\n<td align=\"left\" width=\"90%\">all dependencies regardless of if they are more recent than target<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>These predefined macros are very convenient but it is also possible to define any user defined macros to hold any values.\u00a0 These user defined macros are used to help make the process as generic as possible but also when setting up special or unique rules.\u00a0 Macros are usually used for the same reason variables are used in programs, it is possible to define the value at one location and use it in many.<\/p>\n<h3>Makefile new rule<\/h3>\n<pre><code>clean:\r\n        rm -f $(TARGET)\r\n<\/code><\/pre>\n<p>Of course the make command is used for transform source code into programs but it is possible to define any\u00a0 arbitrary set of commands as part of the build process.\u00a0 It is possible to have rules setup to perform certain pre-processing steps prior to the build or other rules that are helpful during development.\u00a0 These rules might even be to install the program or create a environment.<\/p>\n<h2>Has make&#8217;s time has come, and gone?<\/h2>\n<p>A makefile is a very useful tool to run a compiler to generate object code.\u00a0 As previously mentioned, it is possible to take any command line program and execute it as part of a target.\u00a0 This program could be like lint which is used to analyze source code for programming errors.\u00a0 Yet it is possible to create your own scripts or programs designed to perform other &#8220;special&#8221; tasks that are unique to your own company.<\/p>\n<p>Although make is a nice lightweight tool other solutions such as <a href=\"https:\/\/maven.apache.org\/\" target=\"_blank\" rel=\"noopener\">Maven<\/a>, <a href=\"https:\/\/ant.apache.org\/\" target=\"_blank\" rel=\"noopener\">Ant <\/a>or <a href=\"https:\/\/gradle.org\/\" target=\"_blank\" rel=\"noopener\">Gradle <\/a>can\u00a0 offer more than just building a program.\u00a0 Maven for example is built around a life-cycle of the program.<\/p>\n<ol>\n<li>compile the source code<\/li>\n<li>compile the unit tests<\/li>\n<li>run the unit tests<\/li>\n<li>package up the program or library<\/li>\n<li>deploy it<\/li>\n<\/ol>\n<p>Not only that but Maven actually stores all of the Maven known dependencies. Not only that just stores but will retrieve them as needed.\u00a0 This is not just a single version of a jar file but can actually internally maintain several versions of this same jar.<\/p>\n<p>Not only that but Maven also can be used to create a template of your project.\u00a0 This is both convenient for junior developers and helps to ensure a certain level of consistency within the organization.<\/p>\n<p>Make is only limited by your imagination however if you want to support the same level of functionality (described in last two paragraphs) would require special effort by the developers and no matter how good they are the ability to download and keep track of different dependency versions would not be as good.<\/p>\n<p>Each tool has its own uses and for small projects with no dependencies that have unique steps may be a great task for Make.\u00a0 That said, there does not seem to be a great clambering in the market for people with makefile knowledge but rather those familiar with a fresher toolset such as Maven.\u00a0 I have a few brief blog posts for anyone interested in getting their feet wet on this topic.<\/p>\n<p><a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/10\/03\/installing-maven-on-linux\/\" target=\"_blank\" rel=\"noopener\">Maven installation<\/a><\/p>\n<p><a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/10\/10\/maven-the-alternative-build-tool\/\" target=\"_blank\" rel=\"noopener\">Maven alternative build tool\u00a0<\/a><\/p>\n<p><a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/10\/20\/maven-simple-example\/\" target=\"_blank\" rel=\"noopener\">Maven simple example<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Each programming language has its own set of commands for turning source code into a executable program.\u00a0 Back in the olden days this was done using an old and by today&#8217;s standards a tool with limited functionality.\u00a0 This tool as &hellip; <a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2015\/11\/12\/becoming-a-developer-makefiles\/\">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":[],"categories":[20],"tags":[35,22,36],"_links":{"self":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/176"}],"collection":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/comments?post=176"}],"version-history":[{"count":9,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/176\/revisions"}],"predecessor-version":[{"id":3074,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/176\/revisions\/3074"}],"wp:attachment":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/media?parent=176"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/categories?post=176"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/tags?post=176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}