Makefile C in linux - c

I have 3 functions separated in .c files and the main.c I would like to make the make file, I wrote in the file:
# Indicate that the compiler is the gcc compiler
CC=gc
# Indicate to the compiler to include header files in the local folder
CPPFLAGS = -I
main: method1.o
main: method2.o
main: method3.o
main: method4.o
main.o: main.h
Whereas method 1,2,3,4 is the functions of the main .c and I have the following problem when I type make in the shell:
make
gcc -I -c -o method1.o method1.c
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [method1.o] Error 1

if your project contains the following files: method1.c method2.c method3.c method4.c and main.c
you can use the following make file
CPPFLAGS=-I/path/to/header/files
CC=gcc
all: main
%.o: %.c
$(CC) $(CPPFLAGS) -c -o $# $^
main: method1.o method2.o method3.o method4.o main.o
$(CC) -o $# $^

The issue is in your CPPFLAGS definition:
# Indicate to the compiler to include header files in the local folder
CPPFLAGS = -I
According to the comment above it, it misses a .:
CPPFLAGS = -I.
Otherwise, gcc will treat the -c that comes after -I in your command line as the name of a directory where it can search for headers. Thus, as far as gcc is concerned there's no -c option, and it will attempt to link method1.c as a complete application, hence the error message complaining that there's no main function.

CC=gcc
CPPFLAGS=-I include
VPATH=src include
main: main.o method1.o method2.o method3.o method4.o -lm
$(CC) $^ -o $#
main.o: main.c main.h
$(CC) $(CPPFLAGS) -c $<
method1.o: method1.c
$(CC) $(CPPFLAGS) -c $<
method2.o: method2.c
$(CC) $(CPPFLAGS) -c $<
method3.o: method3.c
$(CC) $(CPPFLAGS) -c $<
method4.o: method4.c
$(CC) $(CPPFLAGS) -c $<
it worked like this

Related

Include header files from another directory using makefile (C code)

I have a directory structure like:
Current directory: within it there are two sub-directories (Directory1 and Directory2).
-Directory1: has a sub-directory with header files(.h) and .c files which are the implemnetations of the .h files in the sub-directory. (.c Files are not within sub-directory but Directory1)
-Directory2: has .c files and Makefile.
My Makefile is:
CC = gcc
OBJS = latency.o utils.o
out: $(OBJS)
HEADER = ../Directory1/include/
CFLAGS = -c -Wall -Iinclude
out: $(OBJS)
$(CC) -o out $(OBJS)
latency.o: latency.c include/utils.h $(HEADER)
$(CC) $(CFLAGS) $< -o $#
utils.o: utils.c include/utils.h $(HEADER)
$(CC) $(CFLAGS) $< -o $#
run:
./out
But i got :
gcc -c -Wall -Iinclude utils.c -o utils.o
gcc -o out latency.o utils.o
/usr/bin/ld: latency.o: in function `main':
latency.c:(.text+0x1b4): undefined reference to 'function_name'
/usr/bin/ld: latency.c:(.text+0x1bc): undefined reference to 'function_name'
/usr/bin/ld: utils.o: in function `get_timing':
utils.c:(.text+0x20c): undefined reference to `function_name'
What mistakes have i made ?

Make different executables one library used by all

I have a project with the following structure:
- main1.c
- main2.c
- main3.c
- lib.h
- lib.c
All the mains use the import lib.
How can I write a Makefile that creates 3 executables (one per each main)?
First Approach
I created a Makefile that does that, but you'd need to append the name of the executable after calling the make command (i.e. make main1, make main2, etc), However if I try using only make (without arguments), it only makes the first main (main1).
CC=gcc
CFLAGS=-g -O2 -Wall
LDFLAGS=-framework OpenCL
DEPS=lib.h
OBJS=main1.o main2.o main3.o
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
main1: lib.o main1.o
$(CC) $(CFLAGS) -o $# $^
main2: lib.o main2.o
$(CC) $(CFLAGS) -o $# $^
main3: lib.o main3.o
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
clean:
rm -f *.o main1 main2 main3
Makefile
https://www.gnu.org/software/make/manual/html_node/Goals.html
By default, the goal is the first target in the makefile (not counting
targets that start with a period). Therefore, makefiles are usually
written so that the first target is for compiling the entire program
or programs they describe.
So just add the below line as the first target in your makefile:
all: main1 main2 main3

Link .so file into an executable file

I have object code that I have compiled using -fPIC switch in clang that also used the -shared switch. I have then linked all of these into a single .so shared object. Now I want to link this into a single executable file, I'm told by the man page that I should be able to do this using the
ld command and the -l switch. But when I do this, I get the following error:
ld -r -L./ -l:libmymath.so simpleone
ld: attempted static link of dynamic object `libmymath.so'
make: *** [simpleone] Error 1
I have tried doing the same thing with the -dy switch, but it gives me the same error.
I really don't understand why this wouldn't be working.
Here is the makefile I am using to do all of this.
CC= clang
LD= ld -r
CFLAGS= -std=gnu99 -g -Oz -c
CSECFL= -fPIC -I -L
CFLAG3= -shared
RM= /bin/rm -f
OBJ= math.o my*.o
SO= libmymath.so
all: math my_add my_mul
math: math.c
$(CC) $(CFLAGS) $#.c $(CSECFL)
my_add: my_add.c
$(CC) $(CFLAGS) $#.c $(CSECFL)
my_mul: my_mul.c
$(CC) $(CFLAGS) $#.c $(CSECFL)
simplemath: $(OBJ)
$(CC) $(OBJ) -o $#
simplemath.o: $(OBJ)
$(LD) $(OBJ) -o $#
lib1: my_add.o
$(CC) $(CFLAG3) my_add.o -o $(SO)
lib2: $(OBJ)
$(CC) $(CFLAG3) my_mul.o -o $(SO)
lib3: $(OBJ)
$(CC) $(CFLAG3) math.o -o $(SO)
simpleone: $(OBJ)
$(LD) -L./ -l:libmymath.so $#
clean:
$(RM) *.o simplemath* *.t $(SO)
You need to link the objects (*.o) into a static executable, not the shared lib (.so) .so can be opened by the run-time dynamic linker or via a dlopen() call.

Makefile Error: No such file or directory, no input files

I'm having some issues with the makefile I made:
CC=gcc # Compiler variable
CFLAGS=-Wall -m32 # Options passed to the compiler
DEPS =
# Generic Rule for .o files
%.o: %.c $(DEPS)
$(CC) -o $# $< $(CFLAGS)
program: source1.o
$(CC) -o program source1.o
#program: source1.o source2.o
# $(CC) -o source1.o source2.o
source1.o: source1.c
$(CC) -o source1 source1.c $(CFLAGS)
#source2.o: source2.c
# $(CC) -o source2 source2.c $(CFLAGS)
I changed my file names to things like "source1" and "program" for generalization purposes.
Right now I'm trying to get the makefile work with one source code. I hope to add more source code down the line, which I will implement via the commented out code.
This is what happens when I run "make" in the terminal:
[terminal] (2)$ make
gcc -o source1 source1.c -Wall -m32
gcc -o program source1.o
gcc: source1.o: No such file or directory
gcc: no input files
make: *** [program] Error 1
I don't know why I'm getting an error, does anyone have any ideas on what I did wrong?
Here:
source1.o: source1.c
$(CC) -o source1 source1.c $(CFLAGS)
You have specified the output file as source1 when you meant source1.o. This should be:
source1.o: source1.c
$(CC) -c -o source1.o source1.c $(CFLAGS)
You can use automatic variables like $# (for the target) and $< (for the first prerequisite) to avoid silly typos like that.

How to create two C executable with different -D variable=value using makefile

My code uses one macro which I am defining during the build as follows.
gcc -D VAR=1000 main.c -0 main
But I want to create two executable, one with VAR=1000 and other with VAR=2000. Lets say executable names would be main_1000 and main_2000.
How can I do that using Makefile.
My attempt to do that is as follows. But it does not work and gives me an error.
gcc -g -c -o main.o main.c
main.c: In function ‘main’:
main.c:5:16: error: ‘VAR’ undeclared (first use in this function)
main.c:5:16: note: each undeclared identifier is reported only once for each function it appears in
make: *** [main.o] Error 1
Makefile:
CC=gcc
CFLAGS=-g
all: main_1000 main_2000
main_1000: main.o
$(CC) -D VAR=1000 -o main_1000 main.o $(CFLAGS)
main_2000: main.o
$(CC) -D VAR=2000 -o main_2000 main.o $(CFLAGS)
main_1000: main.o
This implies that you already expect main.o to be there. Since there's no rule for compiling a c file to an o file, make uses its implicit rule, which doesn't include the definition. What you want instead is this:
CC=gcc
CFLAGS=-g
all: main_1000 main_2000
main_1000: main.c
$(CC) -D VAR=1000 -o $# $^ $(CFLAGS)
main_2000: main.c
$(CC) -D VAR=2000 -o $# $^ $(CFLAGS)

Resources