This is a sample program i was trying to compile this below c program to know about the
make file.
main.c
#include<stdio.h>
#include "reciprocal.h"
int main(int argc,char **argv){
int i;
i=atoi(argv[1]);
printf("The Reciprocal of %d is %f\n ",i,reciprocal(i));
return 0;
}
reciprocal.c
#include<stdio.h>
#include<assert.h>
#include "reciprocal.h"
double reciprocal(int i){
assert(i!=0);
return 1.0/i;
}
reciprocal.h
#include<stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
extern double reciprocal(int i);
#ifdef __cplusplus
}
#endif
makefile
CFLAGS:=-o2
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o reciprocal.o main.o
main.o: main.c reciprocal.h
gcc $(CFLAGS) -c main.c -I ../include
reciprocal.o: reciprocal.c reciprocal.h
gcc $(CFLAGS) -c reciprocal.c -I ../include
clean:
rm -f *.o reciprocal
when compiled as below it throws an error.
% make
gcc -o2 -c reciprocal.c -I ../include gcc -o2 -c main.c -I ../include
gcc -o2 -o reciprocal.o main.o main.o: In function main':
main.c:(.text+0x25): undefined reference toreciprocal' collect2: ld
returned 1 exit status make: * [reciprocal] Error 1
Please help me understand what is the reason for this error.
Change your makefile:
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o reciprocal reciprocal.o main.o
^^^^^^^^^^
Alternatively:
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o $# $^
You have an insidious typo:
CFLAGS:=-o2
That should have been -O2 with a capital O, this way you redirect the output of every compilation to the file 2.
Related
I need some help writing a GNU makefile. I have a C program "main.c", which is dependent on the value of "CONSTANT" defined in the file "constants.h".
"main.c"
#include <stdio.h>
#include "constants.h"
void work(void)
{
int array[CONSTANT];
for (int i = 0; i < CONSTANT; i++) {
printf("%d\n", i);
}
}
int main(int argc, char const* argv[])
{
printf("constant=%d\n", CONSTANT);
work();
return 0;
}
"constant.h"
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define CONSTANT 4
#endif
What I'm trying to do here is to compile the program with different values for "CONSTANT". For example, "out1" is compiled with "CONSTANT=1" and with "make all", I should be able to produce all the variants ("out1", "out2" and "out4").
The problem is that "a.o" required by "main.c" also depends on the value of "CONSTANT". So "a.o" must be compiled after "sed%". However, as far as I understand, there is no way in "make" to force orders in dependencies (I guess this is the whole point of using makefiles).
What is the recommended way to address this situation?
"Makefile"
CC= gcc
CFLAGS = -std=c99 -Wall
CONSTANTS = 1 2 4
targets = $(addprefix out, $(CONSTANTS))
seds = $(addprefix sed, $(CONSTANTS))
.PHONY: $(seds)
$(seds): sed%:
sed -i 's/define CONSTANT [0-9]*/define CONSTANT $*/g' constants.h
$(targets): out%: main.c sed% a.o
$(CC) $(CFLAGS) $< a.o -o $#
a.o: a.c constant.h
$(CC) $(CFLAGS) $< a.o -o $#
.PHONY: all
all : $(targets)
Note that I'm aware that I can rewrite "main.c" so that it takes a parameter from the comman line. In practice, many other files other than "main.c" depend on "CONSTANT", so I want to avoid rewriting all these files. I'm also aware that I can do something like "gcc -DCONSTANT=n main.c", but every file dependent on "CONSTANT" must be recompiled as well.
Related Questions
How to specify Makefile target building order without put any physical dependencies?
Force order of dependencies in a Makefile
I'm ... aware that I can do something like "gcc -DCONSTANT=n main.c",
but every file dependent on "CONSTANT" must be recompiled as well.
This needn't be a hindrance if you have your makefile generate
the correct -DCONSTANT=n and distinct object file in every compilation recipe.
Here's an illustration:
constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
#ifndef CONSTANT
#define CONSTANT 4
#endif
#endif
foo.c
#include "constants.h"
int foo = CONSTANT;
main.c
#include <stdio.h>
#include "constants.h"
extern int foo;
int main()
{
printf("%d\n",CONSTANT + foo);
return 0;
}
Makefile
CC := gcc
CFLAGS := -std=c99 -Wall
CONSTANTS = 1 2 4
TARGETS = $(addprefix out, $(CONSTANTS))
SRCS := main.c foo.c
define compile =
$(basename $(1))$(2).o: $(1) constants.h
$$(CC) -c -DCONSTANT=$(2) $$(CFLAGS) $$< -o $$#
endef
.PHONY: all clean
all : $(TARGETS)
$(foreach src,$(SRCS),\
$(foreach const,$(CONSTANTS),$(eval $(call compile,$(src),$(const)))))
out%: main%.o foo%.o
$(CC) $^ -o $#
clean:
rm -f $(TARGETS) *.o
This runs like:
$ make
gcc -c -DCONSTANT=1 -std=c99 -Wall main.c -o main1.o
gcc -c -DCONSTANT=1 -std=c99 -Wall foo.c -o foo1.o
gcc main1.o foo1.o -o out1
gcc -c -DCONSTANT=2 -std=c99 -Wall main.c -o main2.o
gcc -c -DCONSTANT=2 -std=c99 -Wall foo.c -o foo2.o
gcc main2.o foo2.o -o out2
gcc -c -DCONSTANT=4 -std=c99 -Wall main.c -o main4.o
gcc -c -DCONSTANT=4 -std=c99 -Wall foo.c -o foo4.o
gcc main4.o foo4.o -o out4
And the resulting programs run like:
$ for i in 1 2 4; do ./out$i; done
2
4
8
I have created a new makefile
CC = /usr/bin/gcc
MQM_HOME = /opt/mqm
CFLAGS = -g -Wall \
-I$(MQM_HOME)/inc \
-I/usr/include
#IBM_LIBPATH=-L/usr/vacpp/lib
IBM_LIBS= -liconv
MQ_LIBPATH=-L$(MQM_HOME)/lib64
MQLIB = $(MQ_LIBPATH) -lmqm -lmqmcs -lmqmzse
LIBS = $(IBM_LIBS) $(MQLIB) -lpthreads
#LDFLAGS = -q64 $(IBM_LIBPATH) $(MQ_LIBPATH)
SOURCE=/home/avalanche/oleg
default: ctm_mq_con_ex
ctm_mq_con_ex: ctm_mq_con_ex.o
# Compilation rules
EXE = $(SOURCE)/ctm_mq_con_ex
MAIN = $(SOURCE)/ctm_mq_con_ex.c
OBJS = $(SOURCE)/ctm_mq_con_ex.o
.c.o:
$(CC) $(CFLAGS) -c $(MAIN)
$(CC) $(CFLAGS) -o $(EXE) $(OBJS)
clean:
\rm -f $(OBJS)
\rm -f $(EXE)
Now it shows errors
make -f ./ctm_mq_con_ex.mk
/usr/bin/gcc -g -Wall -I/opt/mqm/inc -I/usr/include -c /home/avalanche/oleg/ctm_mq
/usr/bin/gcc -g -Wall -I/opt/mqm/inc -I/usr/include -o /home/avalanche/oleg/ctm_mq
/home/avalanche/oleg/ctm_mq_con_ex.o: In function `main':
/home/avalanche/oleg/ctm_mq_con_ex.c:67: undefined reference to `MQCONNX'
/home/avalanche/oleg/ctm_mq_con_ex.c:86: undefined reference to `MQOPEN'
/home/avalanche/oleg/ctm_mq_con_ex.c:114: undefined reference to `MQINQ'
/home/avalanche/oleg/ctm_mq_con_ex.c:142: undefined reference to `MQCLOSE'
/home/avalanche/oleg/ctm_mq_con_ex.c:163: undefined reference to `MQDISC'
collect2: ld returned 1 exit status
But in my C program I put header files
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/* includes for WebSphere MQ */
#include <cmqc.h> /* For regular MQI definitions */
#include <cmqxc.h> /* For MQCD definition */
Did I miss something?
I just started learning about makefiles: i created a simple tutorial by myself but it seems I am mistaken somewhere and i don't know where; my mini-tutorial is formed by a main.c script that recalls a function named kernel.c; within this last function 2 more functions are called: add.c (which adds 2 numbers together) and mul.c (which multiplies the result of the previous sum); i then created the headers kernel.h and functions.h which contain the prototypes of the functions defined above; this two header are contained in a folder created within the same one of the main.c script: common/inc
Here are the files:
//main
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"
int main(){
int a = 5, b = 4, c = 0;
int *pa, *pb, *pc;
pa = &a; pb = &b; pc = &c;
kernel(pa, pb, pc);
printf("c = %d\n", c);
return 0;
}
here is kernel.c
#include "kernel.h"
#include "functions.h"
void kernel(int* a, int*b, int* c){
int x = add(*a,*b);
*c = mul(x);
}
here is add.c
#include "functions.h"
int add(int a, int b){
return a + b;
}
here is mul.c
#include "functions.h"
int mul(int a){
return a*2;
}
here is kernel.h
void kernel(int* a, int*b, int* c);
here is functions.h
int add(int a, int b);
int mul(int a);
The make file i wrote looks like this:
#===========================Makefile================================#
CC=gcc
IDIR = common/inc
CFLAGS=-c -Wall -I$(IDIR)
all: eseguibile
eseguibile: main.o
$(CC) $(CFLAGS) main.o -o eseguibile
main.o: main.c kernel.o
$(CC) $(CFLAGS) main.c kernel.o
kernel.o: kernel.c add.o mul.o
$(CC) $(CFLAGS) kernel.c add.o mul.o
add.o: add.c
$(CC) $(CFLAGS) add.c
mul.o: mul.c
$(CC) $(CFLAGS) mul.c
clean:
rm -rf *o eseguibile
I know the program works because if i type gcc main.c kernel.c add.c mul.c -I common/inc/ in the terminal everything works fine.
Can anyone tell me what I a doing wrong?`
The error that i get is this:
gcc -c -Wall -Icommon/inc add.c
gcc -c -Wall -Icommon/inc mul.c
gcc -c -Wall -Icommon/inc kernel.c add.o mul.o
gcc: warning: add.o: linker input file unused because linking not done
gcc: warning: mul.o: linker input file unused because linking not done
gcc -c -Wall -Icommon/inc main.c kernel.o
gcc: warning: kernel.o: linker input file unused because linking not done
gcc -c -Wall -Icommon/inc main.o -o eseguibile
gcc: warning: main.o: linker input file unused because linking not done
I prefer to build the objects separately, and then combine them all at the end. I think the problem is that you are including a -c flag on the final executable. Try this:
#===========================Makefile================================#
CC=gcc
IDIR = common/inc
CFLAGS=-Wall -I$(IDIR)
OBJS = main.o kernel.o add.o mul.o
all: eseguibile
eseguibile: $(OBJS)
$(CC) $(CFLAGS) $^ -o eseguibile
main.o: main.c kernel.h
$(CC) -c $(CFLAGS) main.c
kernel.o: kernel.c kernel.h functions.h
$(CC) -c $(CFLAGS) kernel.c
add.o: add.c functions.h
$(CC) -c $(CFLAGS) add.c
mul.o: mul.c functions.h
$(CC) -c $(CFLAGS) mul.c
clean:
rm -rf *.o eseguibile
I have 4 .c files hello.c,here.c,bye.c and main.c.
One header file mylib.h
The contents are as follows
hello.c
#include<stdio.h>
void hello()
{
printf("Hello!\n");
}
here.c
#include<stdio.h>
void here()
{
printf("I am here \n");
}
bye.c
#include<stdio.h>
void bye()
{
printf("Bye,Bye");
}
main.c
#include<stdio.h>
#include "mylib.h"
int main()
{
hello();
here();
bye();
return 1;
}
mylib.h
#ifndef _mylib_
#define _mylib_
void hello();
void here();
void bye();
#endif
The makefile for creating a static lib is :
Makefile
all: myapp
#Macros
#Which Compiler
CC = gcc
#Where to install
INSTDIR = /usr/local/bin
#Where are include files kept
INCLUDE = .
#Options for developement
CFLAGS = -g -Wall -ansi
#Options for release
#CFLAGS = -O -Wall -ansi
#Local Libraries
MYLIB = mylib.a
myapp: main.o $(MYLIB)
$(CC) -o myapp main.o $(MYLIB)
$(MYLIB): hello.o here.o bye.o
ar rcs $# $^
main.o: main.c mylib.h
hello.o: hello.c
here.o: here.c
bye.o: bye.c
clean:
-rm main.o hello.o here.o bye.o $(MYLIB)
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else \
echo "Sorry, $(INSTDIR) does not exist";\
fi
Problem: When I execute the command
make -f Makefile all
I get the error:
gcc -o myapp main.o mylib.a
main.o: In function `main':
/home/usr/molly/main.c:7: undefined reference to `hello()'
/home/usr/molly/main.c:8: undefined reference to `here()'
/home/usr/molly/main.c:9: undefined reference to `bye()'
main.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
make: *** [myapp] Error 1
Questions : How do I resolve this? Why is there an undefined reference
This actually works for me. Try rm mylib.a and then make
This works for me with the caveot that you are not specifying an 'all' target:
xxxx#xxxx-desktop:~/Desktop$ make -f Makefile
cc -g -Wall -ansi -c -o main.o main.c
cc -g -Wall -ansi -c -o hello.o hello.c
cc -g -Wall -ansi -c -o here.o here.c
cc -g -Wall -ansi -c -o bye.o bye.c
ar rcs mylib.a hello.o here.o bye.o
cc -o myapp main.o mylib.a
xxxx#xxxx-desktop:~/Desktop$ ./myapp
Hello!
I am here
Bye,Byexxxx#xxxx-desktop:~/Desktop$
I am new to g++ and Makefile. I am trying to link this BeBOP SMC library, which is in my lib directory. Under the lib directory are bebop_util and sparse_matrix_converter, both of which have already been built without errors. I see libbebop_util.a, libbebop_util.so under bebop_util and libsparse_matrix_converter.a, libsparse_matrix_converter.so under sparse_matrix_converter. Below is the source:
Makefile
CC=g++
CFLAGS=-c -Wall
test.out: test.o
$(CC) -o test.out -Ilib/sparse_matrix_converter/include -Llib/bebop_util \
-Llib/sparse_matrix_converter -lbebop_util -lsparse_matrix_converter test.o
test.o: test.cpp
$(CC) $(CFLAGS) -Ilib/sparse_matrix_converter/include test.cpp
clean:
rm -f test.o test.out
test.cpp
#include <bebop/smc/sparse_matrix.h>
#include <bebop/smc/sparse_matrix_ops.h>
int main(int argc, const char* argv[])
{
struct sparse_matrix_t* A = load_sparse_matrix (MATRIX_MARKET, "sample_input");
destroy_sparse_matrix(A);
return 0;
}
Output:
login3% make
g++ -c -Wall -Ilib/sparse_matrix_converter/include test.cpp
g++ -o test.out -Ilib/sparse_matrix_converter/include -Llib/bebop_util -Llib/sparse_matrix_converter -lbebop_util -lsparse_matrix_converter test.o
test.o: In function `main':
test.cpp:(.text+0x1a): undefined reference to `load_sparse_matrix(sparse_matrix_file_format_t, char const*)'
test.cpp:(.text+0x27): undefined reference to `destroy_sparse_matrix(sparse_matrix_t*)'
collect2: ld returned 1 exit status
make: *** [test.out] Error 1
Please note that test.cpp depends on sparse_matrix_converter, which depends on bebop_util. Would you please let me know what mistakes I may have made? Thanks.
Tom
The BeBOP code looks to be C code but hasn't add the correct C++ guards. Surround your includes with extern "C" to fix that:
extern "C" {
#include <bebop/smc/sparse_matrix.h>
#include <bebop/smc/sparse_matrix_ops.h>
}