0% found this document useful (0 votes)
75 views13 pages

Lab 2 C Programming On Linux, Mac OS X Course: Operating Systems

The document provides instructions for Lab 2 of an Operating Systems course, which focuses on practicing C programming on Linux and Mac OS X. The lab helps students review basic shell commands using vim text editor, and practice C programming through compiling and running a program using Makefiles. After completing the lab, students will be able to write programs without a GUI using vim, and compile and run programs with Makefiles on Linux/Mac OS X.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
75 views13 pages

Lab 2 C Programming On Linux, Mac OS X Course: Operating Systems

The document provides instructions for Lab 2 of an Operating Systems course, which focuses on practicing C programming on Linux and Mac OS X. The lab helps students review basic shell commands using vim text editor, and practice C programming through compiling and running a program using Makefiles. After completing the lab, students will be able to write programs without a GUI using vim, and compile and run programs with Makefiles on Linux/Mac OS X.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

HCMC University Of Technology

Faculty of Computer Science & Engineering

Lab 2
C Programming on Linux, Mac OS X
Course: Operating Systems

October 14, 2020

Goal: The lab helps student to

• Review basic shell commands and practice with vim on Linux, Mac OS X.

• Review C programming with compiling and running a program on Linux, Mac OS


X.

Content:

• Practice with vim - text editor.

• Programming with C language.

• Compile a program with Makefile.

Result:

• After doing the lab, student can type a program without GUI on Linux/Mac OS
C by vim.

• Student can compile and run a program using Makefile.

1
1 Introduction
1.1 Vim
Vim is the editor of choice for many developers and power users. It‘s a “modal” text
editor based on the vi editor written by Bill Joy in the 1970s for a version of UNIX. It
inherits the key bindings of vi, but also adds a great deal of functionality and extensibility
that are missing from the original vi.
Vim has two modes for users:

• Command mode: allows user to do functions such as find, undo, etc.

• Insert mode: allows user to edit the content of text.

To turn the Insert mode to Command mode, we type ESC key or Crtl − C. Otherwise,
to enter the Insert mode, type i or I, a, A, o, O. Some of basic commands in V im:

• Save: enter :w

• Quit without Save and discard the change: enter :q!

• Save and Quit: enter :wq

• Move the cursor to the top of file: gg

• Move to the bottom: G

• Find a letter/string by going forward: enter /[letter/string] <Enter>

• Find a letter/string by going backward: enter ?[letter/string] <Enter>

• Repeat the previous finding: enter n

• Repeat the previous finding by going backward: enter N

• Delete a line: enter dd

• Undo: enter u

• Redo: enter Ctrl-R

Furthermore, V im has a mode called “visual” that allows user to chose a paragraph for
copying or, moving. To enter this mode, we need to turn the editor into Command
mode and press “v”. After that, user use “arrow” keys to chose the paragraph, and then
use the following commands:

• Copy: enter y

• Cut: enter d

• Paste: enter p

2
1.2 C programming on Linux/Mac OS X
GNU C Coding Standards

• Keep the length of source lines to 79 characters or less, for maximum


readability in the widest range of environments.

• Put a comment on each function saying what the function does, what sorts of
arguments it gets, and what the possible values of arguments mean and are used
for.

• Please explicitly declare the types of all objects. For example, you should explicitly
declare all arguments to functions, and you should declare functions to return int
rather than omitting the int.

Reference: http://www.gnu.org/prep/standards/standards.html. Formatting your


source code

Compiling process: It is important to understand that while some computer lan-


guages (e.g. Scheme or Basic) are normally used with an interactive interpreter (where
you type in commands that are immediately executed). C source codes are always com-
piled into binary code by a program called a "compiler" and then executed. This is
actually a multi-step process which we describe in some detail here.

source
code executable
(.c, .cc, .h) binaries
Preprocessor Compiler Assembler Linker

Figure 1.1: C Compiling scheme

Steps in compiling process:

• Preprocessor: takes the source code, the preprocessor directives and then expand
the source code.

• Compiler: converts the expanded code into assembly code.

• Assembler: converts the assembly code into object code by using an assembler

• Linker: combines the object code of library files with the object code of our pro-
gram.

3
Compilers and Libraries: Apple provides a customized/optimized GNU CC, with
backends for C, C++, Objective-C and Objective-C++. Compilers for many other lan-
guages are available either precompiled (such as the XL Fortran Advanced Compiler from
IBM), or can be compiled from source, which is not any harder in general than compiling
the same source on, say, Linux or FreeBSD. The LLVM compiler is the next-generation
compiler, introduced in Mac OS X. In Xcode of Mac OS X, the LLVM compiler uses the
Clang front end to parse source code and turn it into an interim format.

Figure 1.2: Clang in Mac OS X

Figure below shows a C program compiled in step by step.


1 % P r e p r o c e s s e d source f i l e
2 $ g c c −E [−o h e l l o . cpp ] h e l l o . c // output h e l l o . i
3
4 % Assembly code
5 $ g c c −S [−o h e l l o . S ] h e l l o . c // output h e l l o . s
6
7 % Binary f i l e
8 $ g c c −c [−o h e l l o . o ] h e l l o . c // output h e l l o . o
9
10 % Executable f i l e
11 $ g c c [−o h e l l o ] h e l l o . c

4
2 Practice
2.1 Compile and run a program
Steps for creating a program

In general, the compiling progress includes these steps:


1. Create source code file hello.c
1 #include < s t d l i b . h>
2 #include <s t d i o . h>
3
4 int main ( int argc , char ∗∗ argv ) {
5 p r i n t f ( " H e l l o , ␣World ! \ n" ) ;
6 return 0 ;
7 }

2. Create object file:


$ g c c −c s o u c e _ c o d e _ f i l e . c
# Example :
$ g c c −c h e l l o . c
# or
$ g c c −c −o h e l l o . o h e l l o . c

3. Create executable file:


$ g c c −o e x e c u t a b l e _ f i l e o b j e c t 1 . o o b j e c t 2 . o . . .
# Example :
$ g c c −o h e l l o h e l l o . o

We can compile the program directly from the source code file without the step of
creating object file. However, this way can cause the difficulty when identifying
errors.

4. Create executable file:


$ g c c −o e x e c u t a b l e _ f i l e s r c 1 . c s r c 2 . c . . .
# Example :
$ g c c −o h e l l o h e l l o . c

5. Run the program:


$ ./ executable_file
# Example : t o l i s t t h e c r a t e d e x e c u t a b l e b i n a r y f i l e
$ ls

5
hello hello . c hello . o
# To e x e c u t e t h e b i n a r y f i l e
$ ./ hello

• During compiling a program, the source code can make some errors. The compiler
provides debuggers that show the information of errors. The structure of showing
errors: <file>:<row>:<column_letter>:<type>:<detail>

• For example, error 1:


$ g c c −o h e l l o . o −c h e l l o . c
h e l l o . c : 1 : 1 8 : f a t a l e r r o r : s t d o . h : No such f i l e ...
compilation terminated .

• From the example of error 1:


– Error file: hello.c
– Error line: 1
– The column of error letter: 18
– Type of error: error
– Detail info: stdo.h not found

2.2 Makefile
A makefile is a file containing a set of directives used with the make build automation
tool. Most often, the makefile directs make on how to compile and link a program. Using
C/C++ as an example, when a C/C++ source file is changed, it must be recompiled.
If a header file has changed, each C/C++ source file that includes the header file must
be recompiled to be safe. Each compilation produces an object file corresponding to the
source file. Finally, if any source file has been recompiled, all the object files, whether
newly made or saved from previous compilations, must be linked together to produce
the new executable program.[1] These instructions with their dependencies are specified
in a makefile. If none of the files that are prerequisites have been changed since the last
time the program was compiled, no actions take place. For large software projects, using
Makefiles can substantially reduce build times if only a few source files have changed. A
makefile consists of “rules” in the following form:
# comment
# ( n o t e : t h e <tab > i n t h e command l i n e
# i s n e c e s s a r y f o r make t o work )

t a r g e t : dependency1 dependency2 . . .
<tab> command

6
Where,
• target: a target is usually the name of a file that is generated by a program;
examples of targets are executable or object files. A target can also be the name
of an action to carry out, such as "clean".

• dependency1, dependency2,...: a dependency (also called prerequisite) is a file


that is used as input to create the target. A target often depends on several
files. However, the rule that specifies a recipe for the target need not have any
prerequisites. For example, the rule containing the delete command associated
with the target "clean" does not have prerequisites.

• command: Needed commands is used for performing rules.


For example, we have three source code files including main.c, hello.h, hello.c.
// F i l e : main . c
#include " h e l l o . h"

int main ( ) {
helloworld ( ) ;
return 0 ;
}

// F i l e : h e l l o . h

void h e l l o w o r l d ( void ) ;

// F i l e : h e l l o . c
#include " h e l l o . h"
#include <s t d i o . h>

void h e l l o w o r l d ( void ) {
p r i n t f ( " H e l l o , ␣ world \n" ) ;
}

In this example, we compile .c files into object files .o, and then link all of object files
into a single binary. Firstly, that is the process of compiling source code files into object
files.
• main.o: main function in main.c calls helloworld() which is declared in hello.h.
Thereby, to compile main.c, we need the information declared from hello.h. To
create main.o, we need hello.h and main.c. Therefore, the rule for creating main.o
is:
main . o : main . c h e l l o . h
g c c −c main . c

7
• hello.o: similar to the rule of main.o, we need two files named hello.c and hello.h
to create hello.o. Note that hello.c using printf() in the library stdio.h to print the
output on screen. However, this is the library integrated with GCC, so we do not
need to fill in the dependency of the rule.
hello . o : hello . c hello .h
g c c −c h e l l o . o

• hello: Because helloworld is declared in hello.h, but it is defined in hello.c and com-
piled into the binary in hello.o, therefore, if the main function calls this function,
we need to link hello.o with main.o to create the final binary. This file depends on
hello.o and main.o.
a l l : main . o h e l l o . o
g c c main . o h e l l . o −o h e l l o

• Finally, we can add the rule of clean to remove all of object files and binaries in
case of compiling an entire program.
clean :
rm −f ∗ . o h e l l o

The final result of Makefile:


# File : Makefile
a l l : main . o h e l l o . o
g c c main . o h e l l o . o −o h e l l o

main . o : main . c h e l l o . h
g c c −c main . c

hello . o : hello . c hello .h


g c c −c h e l l o . c

clean :
rm −f ∗ . o h e l l o
With this Makefile, to re-compile the whole program, we call:
$ make a l l
To remove all of object files and binaries, we call
$ make c l e a n
If we need to create an object file - main.o, we call
$ make main . o
If we only call “make”, the default rule of Makefile is executed - “make all”.

8
References

• Coding style by GNU: http://www.gnu.org/prep/standards/standards.html.

• C programming
– Brian Kernighan, and Dennis Ritchie, "The C Programming Language", Sec-
ond Edition
– Randal E. Bryant and David R. O’Hallaron, "Computer systems: A Program-
mer‘s Perspective", Second Edition

• More information about Vim: http://vim.wikia.com/wiki/Vim_Tips_Wiki

• Makefile:
– A simple Makefile tutorial http://www.cs.colby.edu/maxwell/courses/
tutorials/maketutor/
– GNU Make Manual https://www.gnu.org/software/make/manual/make.
html

9
3 Exercises
3.1 Questions
1. What are the advantages of Makefile? Give examples?

2. Is there any other automatic compilation tool besides Makefile? Give some names?
What are the reasons for creating new compilation tools?

3. In case of source code files located in different places, how can we write a Makefile?

3.2 Programming exercises


Two header files named factorial.h and readline.h have the following contents:
// f a c t o r i a l . h
#i f n d e f FACTORIAL_H
#define FACTORIAL_H

char∗ f a c t o r i a l ( const int aNumber ) ;

#endif

// r e a d l i n e . h
#i f n d e f READ_LINE_H
#define READ_LINE_H

int r e a d _ l i n e ( char ∗ s t r ) ;

#endif

1. Write factorial.c to implement function factorial(): the function get an integer and
return an array of char containing digits of the result. For example factorial(10) returns
char[10]={3 6 2 8 8 0 0}

2. Write readline.c to implement read_line(): read_line() gets data from stdin (key-
board), line-by-line. The content from stdin will be recorded on the parameter of this
function named str. The result of read_line() indicates that whether the line is an
integer or not. For example, with the input string below:
H e l l o , world
O p er a t i n g system
Computer S c i e n c e and E n g i n e e r i n g
123

10
After calling the function, read_line() writes “Hello,world” into str and returns 0. The
second calling will write “Operating system” into str and return 0. The third calling will
write “Computer Science and Engineering” into str and return 0. The last call will write
“123” into str and return 1.

3. Write main.c to create an executable file named myfactorial that reads input from
stdin line by line and compute factorial if the line is an integer (each line does not exceed
50 letters). Then print factorial if the line is an integer else print -1. Write a Makefile
to compile the program at least two targets:

• all: create myfactorial from other files.

• clean: remove all of object files, binaries.

// main . c
#include <s t d i o . h>
#include " r e a d l i n e . h"
#include " f a c t o r i a l . h"

int main ( int argc , char ∗ argv [ ] ) {


// Implement m y f a c t o r i a l
}

#endif

Note: As these exercises are graded automatically, thereby, student need to implement
the program by the requirements mentioned above. Student compress all of files .txt (
answers of $3.1 ), .c, .h, Makefile in a zip file named: lab2-<studentID>.zip.

11
Makefile example
1 FC=g f o r t r a n
2 CC=g c c
3 CP=cp
4
5 .PHONY: a l l c l e a n
6
7 OBJS = mylib . o mylib_c . o
8
9 # Compiler f l a g s
10 FFLAGS = −g −t r a c e b a c k −heap−a r r a y s 10 \
11 −I . −L/ u s r / l i b 6 4 −lGL −lGLU −lX11 −l X e x t
12
13 CFLAGS = −g −t r a c e b a c k −heap−a r r a y s 10 \
14 −I . −lGL −lGLU −lX11 −l X e x t
15
16 MAKEFLAGS = −W −w
17
18 PRJ_BINS=h e l l o
19 PRJ_OBJS = $ ( a d d s u f f i x . o , $ (PRJ_BINS ) )
20
21 o b j e c t s := $ (PRJ_OBJS) $ (OBJS)
22
23 a l l : myapp
24
25 %.o : %. f 9 0
26 $ (FC) −D_MACHTYPE_LINUX $< −c −o $@
27
28 %.o : %.F
29 $ (FC) −D_MACHTYPE_LINUX $< −c −o $@
30
31 %.o : %. c
32 $ (CC) −D_MACHTYPE_LINUX $< −c −o $@
33
34 myapp : o b j e c t s
35 $ (CC) $ (CFLAGS) $^ $ ( o b j e c t s ) −o $@
36
37 clean :
38 @echo " C l e a n i n g ␣up . . "
39 rm −f ∗ . o
40 rm −f $ (PRJ_BINS)

12
Revision History

Revision Date Author(s) Description


1.0 11.03.15 PD Nguyen created
1.1 11.09.15 PD Nguyen add introduction and exercise section
2.0 25.02.16 PD Nguyen Restructure the content to form an tutorial
2.1 20.08.16 DH Nguyen Update C and Vim to Appendix
3.0 12.02.19 TK Pham Change Exercises, edit Makefile explain
3.0 13.10.20 TV Le Update compiling process

13

You might also like