Setting Up for Mono Development in Linux Mint/Ubuntu

Posted on October 19 2014 06:08 PM by jatten in Linux, Learning Linux, C#   ||   Comments (5)

follow-the-yerllow-mint-roadI recently needed to create a cross-platform C# library which needs to work across Windows, OSX, and Linux. Obviously, getting a .NET library running on Windows presented no great difficulties. Getting the same library working under Mono on a Linux platform was a little more involved.

The folks at Xamarin have brought Mono, and the development tools available for Mono, a long ways. Xamarin Studio is a beautiful IDE which, while it differs from Visual Studio in some important ways, is a joy to work with. Xamarin's focus is building mobile application development tools. However, Xamarin Studio and Mono both lend themselves fairly well to working with C# code on either Windows or OSX.

Image by Neil Fowler  | Some Rights Reserved

There are some notable things missing (you can't work directly with Windows Forms, for example, nor is there significant support for ASP.NET), but overall, working with strictly library code presented only minor hurdles (not the least of which is a different workflow and navigation scheme from VS).

However, Xamarin Studio is only available for Windows and OSX - there is not currently any support for direct Linux platforms (yes, I know a shiny veneer on top of what amounts to Linux under the hood).

Getting things working on my Linux machine took a little more work.

Mono Development on Linux Using MonoDevelop

Xamarin Studio represents a "Super-Set" of the original, cross-platform Mono IDE, MonoDevelop. The Xamarin team have generously pushed a good number of improvements back to the MonoDevelop source. However, the most recent changes are not directly available as packages to all Linux distros.

Specifically, while the most recent version of MonoDevelop is 5.0.1.3, the most recent package available to Ubuntu, and Ubuntu-based systems from the MonoDevelop site is version 2.6.0.1.

In this article, we will look at how to get a proper Mono development environment set up on Ubuntu-based systems, including the most recent (as of this writing) release of MonoDevelop. We will also look at getting Nuget, and Nuget package restore, working properly in this environment.

Got Linux?

If you don't have a Linux box, set up a VM to work through this post. I prefer using Linux Mint for my Linux-based activity. I found that all of the following steps worked fine in the most recent version of Ubuntu. However, I DON'T like Ubuntu itself. I prefer Linux mint. The last version of Mint I was using (Mint 13 with the KDE desktop) did not work very well with the most recent version of MonoDevelop. I found the the most recent stable release of Mint 17, using the Cinnamon desktop, worked great, with none of the bloat I found with Ubuntu.

See the following for detailed instructions if you need to set up a Linux VM:

For the purpose of this post, we will assume you are starting with a reasonably fresh VM, and do not already have Mono or MonoDevelop Installed.

As mentioned previously, the links on the MonoDevelop download site don't get you the most recent Mono release for Ubuntu-based systems. Fortunately, there are some great Personal Package Archives out there which DO.

Install Mono

Your machine may or may not already have Mono installed. Either way, we are going to pull down the most recent, complete version.

Open a terminal in your home folder, and do the following:

Update Everything:
$ sudo apt-get update

 

Install Mono:
$ sudo apt-get install mono-complete

Once the Mono Installation completes, update again before moving forward:

Update Everything Again:
$ sudo apt-get update

 

The most recent Mono release is now installed on your machine. Now, let's get all the goodness of the most recent MonoDevelop release.

Add the Personal Package Archive (PPA) for Latest Stable MonoDevelop Release

To get the most recent stable release of MonoDevelop, we can thank Eberhard Beilharz for making the Stable Version of MonoDevelop PPA at Launchpad.Net.

To get the most recent version of MonoDevelop on our machine, we simply need to add the PPA to our Synaptic Package Manager's list of sources, and then use synaptic to pull it down.

Add the MonoDevelop PPA to Synaptic:
$ sudo add-apt-repository ppa:ermshiperete/monodevelop

 

Update to refresh Synaptic:

Update Everything Yet Again:
$ sudo apt-get update

 

Install MonoDevelop

Now that we have added the PPA, we can use Synaptic just like any other package:

Install MonoDevelop from PPA:
$ sudo apt-get install monodevelop-current

 

Again, update everything:

Update Everything One More Time:
$ sudo apt-get update

 

Now, as indicated on the MonoDevelop PPA site, the install we just completed placed a shell script at /opt/monodevelop/bin/monodevelop-launcher.sh

Let's add an alias for this, so that we don't have to deal with that big long path every time we want to open MonoDevelop.

If this is a fresh install of Mint 17 on your machine, you will need to add a .bashrc file. If you already have a .bashrc file (or a .bash_profile file - in Mint they are functionally the same), add one:

Add a .bashrc File in your Home Directory:
$ touch .bashrc

 

Next, add an alias to .bashrc pointing to and executing the shell script:

Add Alias to Execute MonoDevelop-Launcher Script:
$ echo >> .bashrc "alias monodev=Exec=\"sh /opt/monodevelop/bin/monodevelop-launcher.sh\""

 

Close the terminal, and open a new terminal instance. You should now be able to open MonoDevelop from the terminal by typing, simply "monodev"

With that, we have successfully installed the most recent release of MonoDevelop on our Mint 17 or Ubuntu machine. However, we are likely to find that Nuget, and Nuget package restore, give us difficulties in this out-of-the box scenario.

Making Nuget Package Restore Work in MonoDevelop

Out-of-the-box, Nuget works a little differently in MonoDevelop than we are accustomed to in Visual Studio (this is true of much about MonoDevelop, actually…).

To see what I mean, use your new terminal alias and open MonoDevelop. Then, create a new Console project. Once that's done, take a moment to get oriented.

We can add Nuget packages by right-clicking on individual projects within the solution in the tree to the left:

Add Nuget Packages in MonoDevelop:

add-nuget-packages

However, if we try to add Nuget packages right now, we get a big FAIL:

Add Nuget Packages Fails in MonoDevelop:

add-packages-fail

WAT?

What's equally confounding is that, if we were to open and build an existing project which required Nuget Package Restore, the Package Manager would is not always able to connect to Nuget to pull down the packages, and an error would result.

This doesn't affect all packages, but enough to be annoying. In particular, several NUnit-related packages and a few others, appear to be affected, and your project can't be properly built.

As it turns out, we are missing some important SSL certificates. The fix is simple, and we can do it from our terminal.

Add Required SSL Certificates for Nuget to Work in MonoDevelop

Since we are using our current terminal instance to run MonoDevelop, we will either need to quit MonoDevelop, or open a new terminal instance, and then execute the following to import a number of important SSL certificates:

Import SSL Certificates from mozroots:
$ mozroots --import --sync

 

Once we have run this command, we should be able to add Nuget packages at will. Also, Update Packages, and Restore Packages commands from the Solution context menu both should work with no problems.

Additional Resources and Items of Interest

 

Posted on October 19 2014 06:08 PM by jatten     

Comments (5)

Setting Up Linux in a Virtual Machine for Windows Users

Posted on October 19 2014 10:04 AM by jatten in Linux, Learning Linux   ||   Comments (0)

photozel-linux-mint-18142If you have spent most of your computing life using Windows, odds are good you may find yourself in unfamiliar territory when if comes to setting up a Linux box. Even for some experienced technical folks, the differences between the platforms can have you feeling like a noob from the very start.

Setting Linux up in a virtual machine can save some time and pain, but comes with the added overhead of understanding how the particular virtualization software works.

In this post, we will look at setting up a basic Linux environment in a virtual machine, and look at some of the trouble-shooting you may need to do along the way.

Image by Photozel  |  Some Rights Reserved

Note, I am not a Linux expert. I have been learning my way through Linux for most of the past year or so, but there is a lot to learn. I find I really, really enjoy using Linux, and once I got past the initial learning curve, things began to make sense rather quickly.

Learn Linux the Hard Way

Most of the recommended introductory Linux distributions ("distro's") feature a GUI to varying degrees. It is possible to do much of what you set out to do without cracking open a terminal. However, when I started down the golden Linux path, a determined to use the terminal wherever possible, and patiently become proficient with this OS in the terms under which, ultimately, it was designed to be used.

I strongly recommend you do the same. Not only will you gain a deeper, better understanding of Unix-based systems, but of how your machine works in general. Unlike the Windows world in which I grew up, Linux/Unix is first and foremost a command-line driven platform, and is optimized as such. In fact, it's fair to say that, unlike Windows, in *nix OS's, anything you can do from the GUI, you can also do from the terminal, usually more efficiently (once you know how, and depending on your typing proficiency).

If you are stuck on how to do something from the terminal, Google is you friend. If your are still stuck, you can probably do it from the GUI until you find an answer. As I said, though, I strongly recommend using the terminal for everything you can. It will feel incredibly clumsy at first, but like all things, the more you do, the better you get.

The article linked below was focused on getting to know Git for folks with a Windows background, but there are a number of handy bash references you may find helpful:

Virtualization Software

Before we can set up a virtual machine, we need some virtualization software. I tend towards the free and open source VirtualBox solution. Despite lacking some of the polish associated with VMWare, I find that VirtualBox meets my needs nicely.

In this article we will be using VirtualBox as our virtualization environment.

Download and Install the appropriate VirtualBox package for your PC from the VirtualBox Downloads page.

Linux Mint

While Ubuntu is the most popular "beginner" Linux distro, I prefer Linux Mint. Newer releases of Ubuntu seem slow and bloated to me, and oriented more directly at desktop users, with many of the more advanced tools well hidden. Also note that Linux Mint is derived from Ubuntu.

Mint seems to more effectively consider both desktop/GUI users, as well as more technical folk. While the full desktop GUI is available (and well-done, compared to some), the terminal is a short context menu away.

At the time of this writing, Linux Mint 17 is the most recent stable release, and is targeted for long-term support.

Downloading the Linux Mint ISO

Linux Mint is available with a number of different desktop options. Until recently, I have been using Mint with the KDE desktop, but have just switched to the newer Cinnamon desktop to check it out. Also, I had issues getting MonoDevelop working in the KDE implementation.

You can download the stable Linux Mint release with the Cinnamon desktop from one of the mirrors on this page:

Once you have downloaded the Linux Mint ISO, save the file somewhere safe. You will need this shortly.

Configure a new Virtual Machine in VirtualBox

Once you have installed VirtualBox on your PC, select the "New" button from the top menu. You should be greeted with the Create Virtual Machine window like so:

VirtualBox Configuration - The Create Virtual Machine Window

create-virtual-machine

Choose a unique and descriptive name for the VM you intend to create. I tend to follow a convention of OS-RAM-HDD specs, but how you do it may depend on what you plan to do with the VM.

Next choose the type (Linux), and the version. In this case, Linux Mint is not one of the options. However, Mint is a descendant of Ubuntu, so Ubuntu will work here.

Allocating Resources to the Virtual Machine

Once you click next, you will be asked to select how much RAM your virtual machine will have. Note that your VM will be sharing RAM with your physical host machine. VirtualBox will offer up a "recommended" amount of RAM to allocate. However, I tend to push this up, as I have physical RAM in abundance on my PC. You can see here I selected 4Gb of RAM, which is likely more than I will ever need.

Allocate RAM to the Virtual Machine:

allocate-ram

Clicking next again, you will be asked if you want to create a virtual hard drive. The default (VDI) is the best bet here. You will also be asked if you want this to be fixed size, or dynamically allocated. I generally go with dynamically allocated.

Once you select these parameters, you will have the opportunity to specify the "size"  and location of the disk to be created. The recommended size if 8Gb. I generally bump this up to 20Gb, which is probably overkill. However, you will want to consider your intended use for the VM, and allocate disk space accordingly. If you plan to be working with lots of images or video, for example, you will want more disk space than if you plan to simply play with the terminal and familiarize yourself with Linux.

Allocate Disk Space to the Virtual Machine:

allocate-hdd

Once we hit the Create button, we are returned to the VirtualBox Management window. However, we are not done preparing our VM.

Other VM Settings

Now that we are back in the VirtualBox Management window, we can adjust the various settings for individual VM's by clicking on the appropriate heading to the right.

We want to change a few of the default settings here before we proceed.

Enable 3D Video Acceleration

If we click on the "Display" heading, we are greeted with the Display settings window. Here, we may want to increase the amount of Video RAM available to our VM. I generally push this up to 32 Mb.

Also, in order to get acceptable graphics performance, we will enable 3D acceleration.

Adjust Display Settings:

display-settings

Share Folder(s) Between the VM and Physical Host

We may want to share files between our host machine (our physical PC) and our VM. We can do this by specifying a folder on the host to be shared. I generally have a dedicated folder named "VM Share" that I use for this.

To set up a folder to be shared between the host and your VM(s), select the "Shared Folders" header in the settings window. Then, click the folder icon (top right) to select/create a folder to share.

add-shared-folder

For our purposes, the other settings for network, USB, and such are generally good with the default settings.

Start the VM and Install Linux Mint

The first time you start your VM, you will be prompted to select a startup disk. At this point, navigate to the Linux Mint ISO you downloaded previously. Click on the folder icon to the right of the drop-down list to navigate your file system.

Select Startup Disk:

select-startup-disk

The system will boot into the Linux Mint OS on the ISO. When Mint is done loading, note the CD icon on the Mint desktop:

Mint Desktop when Booted from ISO:

mint-boot-from-iso

Double click the CD icon, and follow the installation instructions to install Linux Mint on your VM.

NOTE: Linux will only accept lower-case user names, but the password you enter during set-up is case-sensitive.

If you enter a mixed-case username, it will be down-cased when it is saved.

When the installation completes, you will be asked to re-start the VM. Do this. If your VM hangs during the shutdown process (mine did), Simply close the VM window. When you are prompted to indicate how you want the machine to shut down, select the simple "Power Down the Machine" option.

Now, start the machine again using the "Start" icon in the VirtualBox Manager window. As soon as the window comes up, go to the "Devices" menu, eject the Mint Installation ISO:

Startup and Eject the Mint Installation ISO:

remove-disk-from-virtual-drive

If everything has worked properly to this point, you should be greeted with a login screen to log in to Linux Mint.

Enter the user name and password you specified during installation (remember, your username will be all lower-case), and you should be off and running.

Additional Resources and Items of Interest

 

Posted on October 19 2014 10:04 AM by jatten     

Comments (0)

Creating A Basic Make File for Compiling C Code

Posted on July 6 2014 02:30 PM by jatten in Linux, Education, CodeProject, Learning   ||   Comments (3)

binary-blanket-240I recently began taking a Harvard computer science course. As pretentious as that sounds, it's not as bad as it seems. I am taking Harvard CS50 on-line, for free, in an attempt to push my knowledge and expand my understanding of this thing I love so much, programming.

The course uses Linux and C as two of the primary learning tools/environments. While I am semi-capable using Linux, and the syntax of C is vary familiar, the mechanics of C compilation, linking, and makefiles are all new.

Image by quimby  |  Some Rights Reserved

If you are an experienced C developer, or if you have worked extensively with Make before, there is likely nothing new for you here. However, if you wanted to let me know if and when I am passing bad information, please do! This article will (hopefully) be helpful to those who are just getting started compiling C programs, and/or using the GNU Make utility.

In the post, we discuss some things that are specific to the context of the course exercises. However, the concepts discussed, and the examples introduced are general enough that the post should be useful beyond the course specifics.

The course makes available an "appliance" (basically, a pre-configured VM which includes all the required software and files), which I believe can be downloaded by anyone taking even the free on-line course. However, since I already know how to set up/configure a Linux box (but can always use extra practice), I figured my learning would be augmented by doing things the hard way, and doing everything the course requires manually.

For better or for worse, this has forced me to learn about Make and makefiles (this is for the better, I just opened the sentence that way to sound good).

Make File Examples on Github

In this post we will put together a handful of example Make files. You can also find them as source at my Github repo:

Compiling and Linking - The Simple

This is by no means a deeply considered resource on compiling and linking source code. However, in order to understand how make works, we need to understand compiling and linking at some level.

Let's consider the canonical "Hello World!" program, written in the C programming language. Say we have the following source file, suitably named hello.c:

Basic Hello World Implementation in C:
#include <stdio.h>
  
int main(void)
{
    printf("Hello, World!\n");
}

 

In the above, the first line instructs the compiler to include the C Standard IO library, by making reference to the stdio.h header file. This is followed by our application code, which impressively prints the string "Hello World!" to the terminal window.

In order to run the above, we need to compile first. Since the Harvard course is using the Clang compiler, the most basic compilation command we can enter from the terminal might be:

Basic Compile Command for Hello World:
$ clang hello.c -o hello

 

When we enter the above command in our terminal window, we are essentially telling the Clang compiler to compile the source file hello.c, and the -o flag tells it to name the output binary file hello.

This works well enough for a simple task like compiling Hello World. Files from the C Standard Library are linked automatically, and the only compiler flag we are using is -o to name the output file (if we didn't do this, the output file would be named a.out, the default output file name).

Compiling and Linking - A Little More Complex

When I say "Complex" in the header above, it's all relative. We will expand on our simple Hello World example by adding an external library, and using some additional important compiler flags.

The Harvard CS50 course staff created a cs50 library for use by students in the course. The library includes some functions to ease folks into working with C. Among other things, the staff have added a number of functions designed to retreive terminal input from the user. For example, the cs50 library defines a GetString() function which will accept user input as text from the terminal window.

In addition to the GetString() function, the cs50 library also defines a string data type (which is NOT a native C data type!).

We can add the cs50 library to our machine by following the instructions from the cs50 site. During the process, the library will be compiled, and the output placed in the /usr/local/lib/ directory, and the all-important header files will be added to our usr/local/include/ directory.

NOTE: You don't need to focus on using this course-specific library specifically here - this is simply an example of adding an external include to the compilation process.

Once added, the various functions and types defined therein will be available to us.

We might modify our simple Hello World! example as follows by referencing the cs50 library, and making use of the GetString() function and the new string type:

Modified Hello World Example:
// Add include for cs50 library:
#include <cs50.h>
#include <stdio.h>
  
int main(void)
{
    printf("What is your name?");
    // Get text input from user:
    string name = GetString();
      
    // Use user input in output striing:
    printf("Hello, %s\n", name);
}

 

Now, if we try to use the same terminal command to compile this version, we will see some issues:

Run Original Compile Command:
$ clang hello.c -o hello

 

Terminal Output from Command:
/tmp/hello-E2TvwD.o: In function `main':
hello.c:(.text+0x22): undefined reference to `GetString'
clang: error: linker command failed with exit code 1 
    (use -v to see invocation)

 

From the terminal output, we can see that the compiler cannot find the GetString() method, and that there was an issue with the linker.

Turns out, we can add some additional arguments to our clang command to tell Clang what files to link:

$ clang hello.c -o hello -lcs50

 

By adding the -l flag followed by the name of the library we need to include, we have told Clang to link to the cs50 library.

Handling Errors and Warnings

Of course, the examples of using the Clang compiler and arguments above still represent a very basic case. Generally, we might want to direct the compiler to add compiler warnings, and/or to include debugging information in the output files. a simple way to do this from the terminal, using our example above, would be as follows:

Adding Additional Compiler Flags to clang Terminal Command:
clang hello.c -g -Wall -o hello -lcs50

 

Here, we have user the -g flag, which tells the compiler to include debugging information in the output files, and the -Wall flag. -Wall turns on most of the various compiler warnings in Clang (warnings do not prevent compilation and output, but warn of potential issues).

A quick skimming of the Clang docs will show that there is potential for a great many compiler flags and other arguments.

As we can see, though, our terminal input to compile even the still-simple hello application is becoming cumbersome. Now imagine a much larger application, with multiple source files, referencing multiple external libraries.

What is Make?

Since source code can be contained in multiple files, and also make reference to additional files and libraries, we need a way to tell the compiler which files to compile, which order to compile them, and how a link to external files and libraries upon which our source code depends. With the additional of various compiler options and such required to get our application running, combined with the frequency with which we are likely to use the compile/run cycle during development, it is easy to see how entering the compile commands manually could rapidly become cumbersome.

Enter the Make utility.

GNU Make was originally created by Richard M. Stallman ("RMS") and Roland McGrath. From the GNU Manual:

"The make utility automatically determines which pieces of a large program need to be recompiled, and issues commands to recompile them."

When we write source code in C, C++, or other compiled languages, creating the source is only the first step. The human-readable source code must be compiled into binary files in order that the machine can run the application.

Essentially, the Make utility utilizes structured information contained in a makefile in order to properly compile and link a program. A Make file is named either Makefile or makefile, and is placed in the source directory for your project.

An Example Makefile for Hello World

Our final example using the clang command in the terminal contained a number of compiler flags, and referenced one external library. The command was still doable manually, but using make, we can make like much easier.

In a simple form, a make file can be set up to essentially execute the terminal command from above. The basic structure looks like this:

Basic Makefile Structure:
# Compile an executable named yourProgram from yourProgram.c
all: yourProgram.c
<TAB>gcc -g -Wall -o yourProgram yourProgram.c

 

In a makefile, lines preceded with a hash symbol are comments, and will be ignored by the utility. In the structure above, it is critical that the <TAB> on the third line is actually a tab character. Using Make, all actual commands must be preceded by a tab.

For example, we might create a Makefile for our hello program like this:

Makefile for the Hello Program:
# compile the hello program with compiler warnings, 
# debug info, and include the cs50 library
all: hello.c
	clang -g -Wall -o hello hello.c -lcs50

 

This Make file, named (suitably) makefile and saved in the directory where our hello.c source file lives, will perform precisely the same as the final terminal command we examined. In order to compile our hello.c program using the makefile above, we need only type the following into our terminal:

Compiling Hello Using Make:
$ make

 

Of course, we need to be in the directory in which the make file and the hello.c source file are located.

A More General Template for Make Files

Of course, compiling our Hello World application still represents a pretty simplistic view of the compilation process. We might want to avail ourselves of the Make utilities strengths, and cook up a more general template we can use to create make files.

The Make utility allows us to structure a makefile in such a way as to separate the compilation targets (the source to be compiled) from the commands, and the compiler flags/arguments (called rules in a make file). We can even use what amount to variables to hold these values. 

For example, we might refine our current makefile as follows:

General Purpose Makefile Template:
# the compiler to use
CC = clang
  
# compiler flags:
#  -g    adds debugging information to the executable file
#  -Wall turns on most, but not all, compiler warnings
CFLAGS  = -g -Wall
  
#files to link:
LFLAGS = -lcs50
  
# the name to use for both the target source file, and the output file:
TARGET = hello
  
all: $(TARGET)
  
$(TARGET): $(TARGET).c
	$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c $(LFLAGS)

 

As we can see in the above, we can make assignments to each of the capitalized variables, which are then used in forming the command (notice that once again, the actual command is preceded by a tab in the highlighted line). While this Make File is still set up for our Hello World application, we could easily change the assignment to the TARGET variable, as well as add or remove compiler flags and/or linked files for a different application.

Again, we can tell make to compile our hello application by simply typing:

Compile Hello.c Using the modified Makefile:
$ make

 

A Note on Tabs Vs. Spaces in Your Editor

If you, like me, follow the One True Coding Convention which states:

"Thou shalt use spaces, not tabs, for indentation"

Then you will have a problem with creating your make file. If you have your editor set to convert tabs to spaces, Make will not recognize the all-important Tab character in front of the command, because, well, it's not there.

Fortunately, there is a work-around. If you do not have tabs in your source file, you can instead separate the compile target from the command using a semi-colon. With this fix in place, our Make file might look like this:

Makefile with no Tab Characters:
# Compile an executable named yourProgram from yourProgram.c
all: yourProgram.c
<TAB>gcc -g -Wall -o yourProgram yourProgram.c
# compile the hello program with spaces instead of Tabs
  
# the compiler to use
CC = clang
  
# compiler flags:
#  -g    adds debugging information to the executable file
#  -Wall turns on most, but not all, compiler warnings
CFLAGS  = -g -Wall
  
#files to link:
LFLAGS = -lcs50
  
# require that an argument be provided at the command line for the target name:
TARGET = hello
  
all: $(TARGET)
$(TARGET): $(TARGET).c ; $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c $(LFLAGS)

 

In the above, we have inserted a semi-colon between the definition of dependencies definition of the target and the command statement structure (see highlighted line).

Passing the Compilation Target Name to Make as a Command Line Argument

Most of the time, when developing an application you will most likely need a application-specific Makefile for the application. At least, any substantive application which includes more than one source file, and/or external references.

However, for simple futzing about, or in my case, tossing together a variety of one-off example tidbits which comprise the bulk of the problem sets for the Harvard cs50 course, it may be handy to be able to pass the name of the compile target in as a command line argument. The bulk of the Harvard examples include the cs50 library created by the program staff (at least, in the earlier exercises), but otherwise would mostly require the same sets of arguments.

For example, say we had another code file, goodby.c in the same directory.

We could simply pass the target name like so:

Passing the Compilation Target Name as a Command Line Argument:
make TARGET=goodbye.c

 

As we can see, we assign the target name to the TARGET variable when we invoke Make. In this case, if we fail to pass a target name, by simply typing make as we have done previously, Make will compile the program hard-coded into the Makefile - in this case, hello. Despite our intention, the wrong file will be compiled.

We can make one more modification to our Makefile if we want to require that a target be specified as a command line argument:

Require a Command Line Argument for the Compile Target Name:
# compile the hello program with spaces instead of Tabs
  
# the compiler to use
CC = clang
  
# compiler flags:
#  -g    adds debugging information to the executable file
#  -Wall turns on most, but not all, compiler warnings
CFLAGS  = -g -Wall
  
#files to link:
LFLAGS = -lcs50
  
# require that an argument be provided at the command line for the target name:
TARGET = $(target)
  
all: $(TARGET)
$(TARGET): $(TARGET).c ; $(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c $(LFLAGS)

 

With that change, we can now run make on a simple, single-file program like so:

Invoke Make with Required Target Name:
$ make target=hello

 

Of course, now things will go a little haywire if we forget to include the target name, or if we forget to explicitly make the assignment when invoking Make from the command line.

Only the Beginning

This is one of those posts that is mainly for my own reference. As I become more fluent with C, compilation, and Make, I expect my usage may change. For now, however, the above represents what I have figured out while trying to work with the examples in the on-line Harvard course.

If you see me doing anything idiotic in the above, or have suggestions, I am all ears! Please do comment below, or reach out at the email described in my "About the Author" blurb at the top of this page.

Additional Resources and Items of Interest

 

Posted on July 6 2014 02:30 PM by jatten     

Comments (3)

About the author

My name is John Atten, and my "handle" on many of my online accounts is xivSolutions. I am Fascinated by all things technology and software development. I work mostly with C#, JavaScript/Node, and databases of many flavors. Actively learning always. I dig web development. I am always looking for new information, and value your feedback (especially where I got something wrong!). You can email me at:

jatten at typecastexception dot com

Web Hosting by