Creating a makefile C using all, clean, and other - c

My professor gave me a code that he already wrote and we had to fill in the rest. Now our task is to create a makefile using multiple targets. These are the directions:
"3. Create a Makefile to create your project. Your makefile should have the following targets (put all at the top)
a.).all Creates all object files and executable files
b.).Wall.o Builds the Wall.o object file from Wall.c
c.).Maze.o Builds the Maze.o object file from Maze.c
d.).DisjointSetADT.o Builds theDisjointSetADT.o object file from DisjointSetADT.c
e.).MazeBuilder.o Builds the MazeBuilder.o object file fromMazeBuilder.c
f.).MazeBuilder Builds the MazeBuilder executable from all object files
g.).clean Deletes all object files and executable files."
This is what I have so far:
all: MazeBuilder
Wall.o: Wall.c
gcc -c -Wall Wall.c
Maze.o: Maze.c
gcc -c -Wall Maze.c
DisjointSetADT.o: DisjointSetADT.c
gcc -c -Wall DisjointSetADT.c
MazeBuilder.o: MazeBuilder.c
gcc -c -Wall MazeBuilder.c
MazeBuilder: MazeBuilder.o Wall.o Maze.o DisjointSetADT.o
gcc MazeBuilder.o Wall.o Maze.o DisjointSetADT.o -o MazeBuilder
clean:
rm -f *.o MazeBuilder
I have no idea why my auto grader says the makefile doesn't work. There are tabs under each target already, not sure why they are not popping in when I copy my code over.

We must proceed in small steps.
Start in a directory that contains the various source files (Wall.c, DisjointSetADT.c and so on) and the makefile. This is essential.
1) Compiling from the command line. Try this command (in the command line, instead of "make"):
gcc -c -Wall Wall.c
This should build Wall.o; if it doesn't then tell us (in a comment to this Answer) exactly what the result was. If it works, remove Wall.o and proceed to...
2) Compiling with Make. Try this:
make Wall.o
This should do exactly the same thing as step 1. If it works, try make clean to remove Wall.o.
3) Build all the object files:
make MazeBuilder.o Wall.o Maze.o DisjointSetADT.o
4) Linking the objects by hand:
gcc MazeBuilder.o Wall.o Maze.o DisjointSetADT.o -o MazeBuilder
5) The whole shebang:
make clean
make MazeBuilder
6) Using the default rule:
make clean
make
Tell us where and how this sequence fails, and we'll try to fix it.

Related

Script to create a static library from all .c file in my working directory

I am trying to write a script that create a static library call libwork.a in the working directory from all the .c files in the directory:
#!/bin/bash
gcc -c *.c | ar cr libwork.a *.o
But as I run my script, it only creates the object files. The libwork.a does not get created. I tried both sourcing and executing my script but it still only creates object files only.
Why is it not creating the archive?
You are piping the messages printed by gcc (most surely none) to ar (which does not read anything). This is nonesense, ar should run after gcc.
The file listing generated by "*.o" is passed before "gcc" finished.
The solution is to remove that pipe and simply run the commands one after the other.
#!/bin/sh -e
gcc -c *.c
ar cr libwork.a *.o
Note the "-e". This tells the shell to abort if one of the commands fails, so if gcc fails ar will not execute.
Also, have a look at this one:
#!/bin/bash
gcc -Wall -pedantic -Werror -Wextra -c *.c
ar -rc libwork.a *.o
ranlib libwork.a

How to create a makefile in gcc

I am trying to create a makefile but facing some issues.
I installed gcc compiler in Windows 7, then created one simple helloworld example. After that compiled that C file using the following command:
gcc filename.c
After this I am getting an exe file. I am calling this project in some tool for that, tool required makefie.
As I understood makefile is a text file, which tells or consist some commands how to build, run and clean the project.
So according to this I am writing a makefile:
CC=gcc
SRCS=src/hello.c
.PHONY: all
all: clean build
#echo ========== Complete ==========
.PHONY: build
build:
#echo ========== Build ==========
$(CC) hello.c
.PHONY: run
run:
#echo ========== Run ==========
make
.PHONY: clean
clean:
#echo ========== Clean ==========
rm hello.exe
./obj:
mkdir ./obj
While calling this simple project in tool, getting error
"no rule to make target clean"
Please tell me which steps I followed those are correct for creation of makefile or not, and what mistake I am doing? How to create a makefile?
In my opinion you have not got the essence of make(1):
Make stores in the makefiles a set of dependency rules (dependencies between files) in your build directory in order to build your project.
There are dependency lines, and build lines, the dependencies start in column 0 of the line, while the buid lines start with a tab char.
the rule lines have two parts, the file that is to be built, a colon (:), and the list of files it depends on (so that if one or more of these files is modified, the rule is applied)
If the rule has to be applied, then the set of build lines below the rule (until the next rule or a variable definition rule if found) is executed in order to build the file.
Example
Your file hello.c will be compiled into hello.s to create an assembler file, and then the assembly code is assembled to generate an object code hello.o. Finally, this file is linked to generate the file hello (or hello.exe, if you are in windows).
You arrange your makefile to generate all the files, in a way that if you modify e.g. the assembler file hello.s, only the assembler pass, and the linker pass is done, but not the compiling phase that should overwrite the assembler file before assembling. This can be done with this Makefile:
# this is the linking phase. The first rule in the file is the
# default target rule, so by default, executing make will try this
# rule (but only if hello.exe was modified before hello.o)
hello.exe: hello.o
gcc -o hello.exe hello.o
# Now, the assembling phase. The hello.o file depends on the
# hello.s assembly code, so to assemble it we call the assembler
hello.o: hello.s
as -o hello.o hello.s
# now, we specify the dependency from the hello.s assembler file
# from the hello.c source code file.
hello.s: hello.c
gcc -c -S -o hello.s hello.c
Now, if it is the first time you execute make and you have only the file hello.c (and Makefile of course) the make program will generate the following sequence of commands:
$ make
gcc -c -S -o hello.s hello.c
as -o hello.o hello.s
gcc -o hello.exe hello.o
$ _
but if you later modify the file hello.s (I will touch(1) it, to change its modification date:
$ touch hello.s
$ make
as -o hello.o hello.s
gcc -o hello.exe hello.o
$ _
but if you touch hello.c, everything will be made again:
$ touch hello.c
$ make
gcc -c -S -o hello.s hello.c
as -o hello.o hello.s
gcc -o hello.exe hello.o
$ _
Make builds a dependency graph and follows it in order to build the target you have specified in the command line, so if you use make with a target, it will stop as soon as the target is built:
$ make hello.o
gcc -c -S -o hello.s hello.c
as -o hello.o hello.s
$ _
I recommend you to read a book on make. A good one is the GNU Make documentation that is online on your system as an info file: just execute:
$ info make
(and info will open a text screen to allow you to read the full documentation of make)

C Makefile compilation error - "linker input file unused because linking not done"

I'm having a problem with a C Makefile.
This is the code for the Makefile in bash:
CC=gcc
CFLAGS=-g -Wall
CCLINK=$(CC)
OBJS=flight.o runway.o airport.o main.o
RM=rm -f
# Creating the executable (airport)
airport: $(OBJS)
$(CCLINK) -o airport $(OBJS)
# Creating object files using default rules
main.o: main.c airport.h ex2.h flight.h runway.h
airport.o: airport.c airport.h ex2.h flight.h runway.h
runway.o: runway.c runway.h ex2.h flight.h
flight.o: flight.c flight.h ex2.h
# Cleaning old files before new make
clean:
$(RM) airport *.o *.bak *~ "#"* core
When I make the file, it says that:
make: `airport` is up to date.
After that - I can call "airport" in bash and it lets me enter some inputs the way I want it to be.
BUT- when I'm trying to check if "airport" is compiled by:
gcc -g -Wall -c airport
I get an error says that:
gcc: airport: linker input file unused because linking not done
Does someone know what could be the problem?
Thanks!
Gavriel.
The aim of Makefile is to avoid recompiling a file if its source is unchanged; when it happens, make says that the file is up to date.
This might be annoying if you want to check again the warnings. Then, simply call make to recompile everything, by typing
make clean ; make
Another goal of Makefile is to avoid typing the gcc commands by yourself, prone to errors. For instance, at the end of your question, you ask to make an object file from an executable (option -c), which is wrong. The good way to make an object file is to call make :
make airport.o
Finally, to produce the executable, you can either type
make airport
or, since airport: is the first target, type
make

Using LLDB for debugging C

I'm writing a small C library for some basic polygon operations and I'm trying to use LLDB from the command line for debugging. I am able to run LLDB with my compiled test runner, but I can only see assembly instructions and not C code as I step through.
I've compiled my library and test runner with the -g flag as shown here in this Makefile:
#Define compiler flags
CFLAGS = -g -Wall -Werror
#Define objects
OBJECTS = MASClip.o MASGraph.o MASClipTest.o
tests : $(OBJECTS)
cc $(CFLAGS) $(OBJECTS) -o tests
MASClip.o : MASClip.h MASClip.c
cc $(CFLAGS) -c MASClip.c
MASGraph.o : MASGraph.h MASGraph.c
cc $(CFLAGS) -c MASGraph.c
MASClipTest.o : MASClipTest.c
cc $(CFLAGS) -c MASClipTest.c
test :
make
make clean
./tests
.PHONY : clean
clean :
rm *.o
I can set breakpoints by function name so I don't understand why the code is not displayed.
I've searched around, but I don't see that I'm doing anything different from what the tutorials and other questions say. I must be missing something obvious.
Also, I realise I could just do this in Xcode, but when I write straight C I like to use VIM and it would be nice to be able to use LLDB from the command line.
How do I get LLDB to display the actual C code when debugging?
On OS X debug info is stored in .o files. The debugger refers back to the .o files using a "debug map" in the executable. Looks like you are deleting the .o files before you try to debug, so there's no debug information for the debugger.
Either leave the .o files in place when you debug, or run the dsymutil tool on the executable to produce a linked debug output file (.dSYM.) If you put the dSYM next to the executable (or anywhere that Spotlight searches) then lldb will find it automatically.
Note that if you just give the compiler a list of .c files, it will make a dSYM for you automatically - since it will delete the .o files when it is done - so that debugging is still possible.

Using makefile, LD_PRELOAD to executable file

I have two files, "abc.c" and "run"
and I want to make a executable binary file which perform below two intstructions
gcc -m32 -O2 -Wall -DRUNTIME -shared -fPIC -o a.so abc.c -ldl
LD_PRELOAD="a.so" ./run
I tried to use makefile in linux, but failed.
Can I use makefile to make executable binary file ?
Ideally, makefile should be used for compilation. For automating the shell commands, you can use a shell script.
Maybe, in your case, you can write a shell script, which will call the make -f <SomeMakeFile> command first to compile and generate the library (.so) and then run the target binary with alogwith the LD_PRELOAD instruction.
I'd do it like this:
all: a.so
test: a.so
LD_PRELOAD="a.so" ./run
a.so: abc.c
gcc -m32 -O2 -Wall -DRUNTIME -shared -fPIC -o a.so abc.c -ldl
clean:
rm -f a.so
Save this in a file called Makefile. Note that the indentations MUST be a single tab - stackoverflow ruined that in their output above.
There are now 4 targets, calling just make will generate the shared library, explicitly calling make test will run your test. If needed, make test will build the library first.
I was tempted to throw in some more flexibility, but that was not what you asked for...

Resources