Part A - Introduction

Compiling Modular Source Code

Workshop 1


In your first workshop, you are to sub-divide a simple program into two modules and compile the modules separately on different platforms.


Learning Outcomes

Upon successful completion of this workshop, you will have demonstrated the abilities

  • to organize source code into modules, with header and implementation files
  • to compile and run modular programs on different platforms

Original Source Code - All Groups

Save the following program as w1.cpp on your local computer:

 // Modular Programs - Workshop 1
 // w1.cpp

 #include <iostream>
 using namespace std;
 #define MAX 25

 int getPosInt(int max);

 int main() {
     int i;
     i = getPosInt(MAX);
     cout << "You entered " << i << endl;
 }

 // getPosInt returns a positive integer not greater than max
 //
 int getPosInt(int max) {
     int i;
     int keepasking;

     keepasking = 1;
     do {
         cout << "Enter a positive integer not greater than "
              << max << " : ";
         cin >> i;
         if ( i < 0 || i > max)
             cout << "Your entry is out of range.  Try again." << endl; 
         else
             keepasking = 0;
     } while ( keepasking == 1 );

     return i;
 }

Compile w1.cpp and run the executable on

  • Linux
     g++ -o w1 w1.cpp
     w1
    
  • Windows (at the command line):
     cl /EHsc w1.cpp
     w1
    

The /EHsc option suppresses the cl warning messages.


Modular Source Code - All Groups

Once w1.cpp runs successfully on each platform, sub-divide w1.cpp into

  1. a main module named w1
    • a header file named w1.h
    • an implementation file named w1.cpp
  2. a getPosInt module
    • a header file named getPosInt.h
    • an implementation file named getPosInt.cpp 

Your w1.h header file should only contain the #define directive.  Your getPosInt.h header file should only contain the getPosInt() prototype.  Add header comments to each file. 

Recompile your modularized source code and run the executable on

  • Linux
     g++ -o w1 w1.cpp getPosInt.cpp
     w1
    
  • Windows (at the command line):
     cl /EHsc w1.cpp getPosInt.cpp
     w1
    

Note the size of the executable file on each platform.

Typescript (Group X Only)

On Linux, create a typescript of your complete solution using the following commands:

 + At the prompt, type: script w1.txt
 + At the prompt, type: whoami
 + At the prompt, type: cat w1.h w1.cpp getPosInt.h getPosInt.cpp 
 + At the prompt, type: g++ w1.cpp getPosInt.cpp
 + At the prompt, type: w1
 + At the input prompt, enter some test data
 + At the prompt type: exit

These commands will produce a file named w1.txt.

Download this file to your local computer. 


Make Utility - Group Y

Complete the modularization exercise described above.  In addition, create a Makefile to automate the compilation process. 

Linux commands include a make utility that simplifies the compilation of modular programs.  This utility uses a makefile that describes the dependency structure amongst modules in terms of the rules followed in each step of the compilation process.  The make utility uses this makefile to determine the steps that eed to be executed in order to reach a specified end point in the compilation process. 

Each rule in a makefile has two or more lines: a dependency line and one or more command lines

 target: pre-requisite files
 TAB commands

TAB stands for the tab character (\t). 

Consider the files in this workshop: w1.h, w1.cpp, getPosInt.h and getPosInt.cpp.  The executable file w1 needs to be re-created everytime w1.h, getPosInt.h, w1.cpp or getPosInt.cpp change.  We express this rule as follows

w1: w1.h getPosInt.h w1.cpp getPosInt.cpp 
    g++ -o w1 w1.cpp getPosInt.cpp

The dependency line first identifies the name of the target file.  A colon follows that name.  The names of the files upon which the target depends follow the colon.  The target file is typically an executable file or a binary file for a module. 

The command line below the dependency line consists of the TAB character followed by the command to be executed in order to create (or re-create) the target file.  Note that the command line must begin with a TAB character and not a space or several spaces. 

The make utility takes as an optional argument the name of the target file to be (re-)created.  If the user does not provide any argument, the make utility uses the default target, which is the target on the first rule in the makefile. 

The make utility assumes a default makefile named Makefile.  To re-construct the program upon which we are currently working, we only need to define Makefile for our program.  Then, we can simply enter make without any argument every time we choose to re-build. 

To re-build a program that is different than that described in Makefile, we use the make command with the -f option followed by the name of the makefile that contains the set of rules for that program. 

A makefile can include rules to simplify file management.  For instance, to delete all intermediate files, we can define a dummy target named clean

clean:
    command to delete all intermediate files 

We can also introduce variables into the makefile to facilitate changes, such as switches between different compilers.  We define the values for the selected platform at the top of the makefile and use the variable identifiers throughout the makefile.

Makefile for Workshop 1

The makefile for this workshop can be

# Makefile for Workshop 1 - GCC Platform
# Makefile

#----------------------------------------------------------
# Platform Variables

# uncomment to select option
OPT=
#OPT=-std=c++0x

#----------------------------------------------------------
# Set of Rules

# links the binary components together to form the executable
w1: w1.o getPosInt.o
    g++ -o w1 w1.o getPosInt.o

# recompiles w1.cpp if any recent changes have affected it
w1.o: w1.cpp getPosInt.h w1.h
    g++ -c $(OPT) w1.cpp

# recompiles getPosInt.cpp if any recent changes have affected it 
getPosInt.o: getPosInt.cpp getPosInt.h
    g++ -c $(OPT) getPosInt.cpp

# removes intermediate files
clean:
    rm *.o

When copying the makefile, you may need to edit the copy to ensure that the command lines begin with a TAB character (not several spaces).

Linux

Open the above Makefile with a text editor and check that the command lines start with a TAB character. 

To create an executable version of your source code, enter

 make

To remove the intermediate files, enter

 make clean

To find out what make would do if executed, enter

 make -n

Typescript

On Linux, create a typescript of your complete solution using the following commands:

 + At the prompt, type: script w1.txt
 + At the prompt, type: whoami
 + At the prompt, type: cat w1.h w1.cpp getPosInt.h getPosInt.cpp 
 + At the prompt, type: cat Makefile
 + At the prompt, type: make
 + At the prompt, type: w1
 + At the input prompt, enter some test data
 + At the prompt type: exit

These commands will produce a file named w1.txt.

Download this file to your local computer. 


SUBMISSION

Moodle

Upload your typescript file to Moodle: 

  • Login to Moodle
  • Select your course code
  • Select W1 under Assignments and Tasks
  • Upload w1.txt
  • Write a short note to your instructor
    • press "Edit"
    • enter your conclusions about this workshop in the notes textbox
    • list the sizes of the executables within the notes textbox
    • press "Save Changes"
  • When ready to submit, press "Send for Marking"

Other Submissions

Submit your typescript file as your instructor has specified.







  Designed by Chris Szalwinski   Copying From This Site   
Logo
Creative Commons License