Compiling: undefined reference to - c

I'm struggling with compiling multiple files into a common program. I'm getting an error:
undefined reference to 'pi'
Here's the skeleton of my code and Makefile. What am I doing wrong? Thanks!
File: calcPi.c
#include <stdlib.h>
#include <stdio.h>
#include <sched.h>
#include <string.h>
#include "pi.h"
int main(int argc, char* argv[]) {
long iterations = 1000000;
int policy = 2;
int numChildren = 3;
pi(iterations, policy, numChildren);
return 0;
}
File: pi.h
void pi(long iterations, int policy, int numChildren);
File: pi.c
#include "pi.h"
void pi(long iterations, int policy, int numChildren) {
//lots of code here
}
I'm compiling this using a Makefile:
CC = gcc
CFLAGS = -c -g -Wall -Wextra
LFLAGS = -g -Wall -Wextra
all: calcPi pi
calcPi: calcPi.o
$(CC) $(LFLAGS) $^ -o $# -lm
pi: pi.o
$(CC) $(LFLAGS) $^ -o $# -lm
calcPi.o: calcPi.c
$(CC) $(CFLAGS) $<
pi.o: pi.c
$(CC) $(CFLAGS) $<
clean:
rm -f pi calcPi
rm -f *.o
rm -f *~
EDIT: In response to the request for the entire error message:
In function 'main'"
calcPi.c:55: undefined reference to 'pi'
collect2: error: ld returned 1 exit status
make: * [calcPi.o] error 1

First of all, is pi really supposed to be a separate application?
You're referring the pi() function from calcPi, but it's only been compiled into pi.o, so you need to add it as a dependency.
What I think you want to do, is to create calcPi using the calcPi.o and pi.o object files.
CC = gcc
CFLAGS = -c -g -Wall -Wextra
LFLAGS = -g -Wall -Wextra
all: calcPi
calcPi: calcPi.o pi.o
$(CC) $(LFLAGS) $^ -o $# -lm
calcPi.o: calcPi.c
$(CC) $(CFLAGS) $<
pi.o: pi.c
$(CC) $(CFLAGS) $<
clean:
rm -f calc
rm -f *.o
rm -f *~

Related

Getting a C error that I have an undefined reference to function, but the function is defined

I am trying to take a binary to decimal function out of my main.c file and into its own file, but when I compile the files with my makefile I get the error:
undefined reference to `btod'
Here is my main.c file:
#include "btod.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n;
printf("\nEnter a binary number: ");
char c[100];
scanf("%s",c);
printf("Number converted to decimal: %d\n\n\n",btod(strlen(c),c));
return 0;
}
Here is my btod.c file:
#include <stdlib.h>
#include <string.h>
int btod(int size,char inputBin[size])
{
int i,num=0;
for(i=0;i<size;i++)
{
num=num*2+(inputBin[i]-48);
}
return num;
}
Here is my btod.h file:
int btod(int size,char inputBin[size]);
And lastly, here is my makefile:
CC = gcc
INCLUDE = -I.
CFLAGS = -g -Wall
LDFLAGS = -L. \
-L/usr/lib
LDLIBS = \
-lc -lm
.c.o:
$(CC) $(INCLUDE) $(CFLAGS) -c $<
all: main
main: main.o
$(CC) -o $# $^ $(LDFLAGS) $(LDLIBS)
btod: btod.o
$(CC) -o $# $^ $(LDFLAGS) $(LDLIBS)
clean:
rm -f *.o
rm -f main
I am thinking it might have to do with the btod.c file not being compiled properly within the makefile but I cannot figure out what is incorrect about it.
The error is because you don't link in btod.o when building main. If you use GNU Make, you can simplify your Makefile to just a few lines:
.PHONY: all clean
CFLAGS = -g -Wall
all: main
clean:
rm -f *.o main
main: btod.o main.o
In btod.c use '0' instead of 48. In main.c remove the line int n.

make: *** No rule to make target 'main.c', needed by 'main.o'. Stop

I have 3 .c files in my src directory and i have a Makefile in the parent directory of src. All my c files just use standard header files.
The error i am getting while using make command is
make: *** No rule to make target 'main.c', needed by 'main.o'. Stop.
I tried all the tweaks that people have mentioned here and there but could not solve the problem. help please.
i tried including vpath directive too.
Makefile
vpath src
vpath inc
CFLAGS=-I inc
output: main.o helloExec.o execDemo.o
$(CC) -o $(CFLAGS) $<
main.o: main.c
$(CC) -c $(CFLAGS) $< $(CFLAGS)
helloExec.o: helloExec.c
$(CC) -c $(CFLAGS) $< $(CFLAGS)
execDemo.o: execDemo.c
$(CC) -c $(CFLAGS) $< $(CFLAGS)
clean:
rm -f *.o output
main.c
#include<stdio.h>
int main()
{
printf("hello\n");
return 0;
}
execDemo.c
#include<stdlib.h>
#include<unistd.h>
int main()
{
printf("execDemo with pid = %d\n", getpid());
return 0;
}
helloExec.c
#include<stdlib.h>
#include<unistd.h>
int main()
{
printf("helloExec with pid = %d\n", getpid());
return 0;
}
VPATH is a variable.
So, it should be in upper case, and set to a list of directories:
VPATH=src:inc
The output build line $(CC) -o $(CFLAGS) $< is incorrect:
what follows the -o option is the output (executable) file.
CFLAGS=-Iinc
output: main.o helloExec.o execDemo.o
$(CC) $< -o output
main.o: main.c
$(CC) -c $(CFLAGS) $< $(CFLAGS)
helloExec.o: helloExec.c
$(CC) -c $(CFLAGS) $< $(CFLAGS)
execDemo.o: execDemo.c
$(CC) -c $(CFLAGS) $< $(CFLAGS)
clean:
rm -f *.o output

How to link multiple .c files

I know that you have to create a header file and #include it in your main. I have done that and when I compile my code for some reason it is unable to figure out where one of my functions are.
The layout of my project is a: threads.c makeCityFromInput.h and makeCityFromInput.c
I have the threads.c #including the makeCityFromInput.h
This is what happens when I try to compile:
make
gcc -ggdb -std=c99 -Wall -Wextra -pthread -c threads.c
gcc -ggdb -std=c99 -Wall -Wextra -pthread -o threads threads.o -lm -lncursesw -pthread
threads.o: In function `main':
/home/project3/threads.c:183: undefined reference to `readConfig'
collect2: error: ld returned 1 exit status
Makefile:71: recipe for target 'threads' failed
make: *** [threads] Error 1
It is unable to find my readconfig file even though it is in my header file
my threads.c file
#define _DEFAULT_SOURCE
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <strings.h>
#include <string.h>
#include <ncurses.h> //displays the cars
#include <pthread.h> //threading
#include <unistd.h>
#include "makeCityFromInput.h"
#define MAX 2048
int main(int argc, char *argv[]){
//Expected input: Name of config file
// If the config file is not given; or too many config files are given
if (argc != 2){
endwin();
fprintf(stderr, "Usage: Enter a configuration file");
exit( EXIT_FAILURE );
}
FILE *fp = NULL;
fp = fopen(argv[1], "r");
assert( fp );
readConfig(fp);
fclose( fp );
return 0;
}
my makeCityFromInput.h file:
#ifndef _MAKECITYFROMINPUT_H
#define _MAKECITYFROMINPUT_H
void readConfig(FILE *fp);
int *parse_line(char *line, int *numInts);
void create_skyline(int *ground, int size, int maxMissiles);
#endif
my makeCityFromInput.c file:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <strings.h>
#include <string.h>
#include <ncurses.h> //displays the cars
#include <pthread.h> //threading
#include <unistd.h>
void readConfig(FILE *fp){
...
}
My make file
#
# Created by gmakemake (Ubuntu Jul 25 2014) on Wed Nov 14 20:05:05 2018
#
#
# Definitions
#
.SUFFIXES:
.SUFFIXES: .a .o .c .C .cpp .s .S
.c.o:
$(COMPILE.c) $<
.C.o:
$(COMPILE.cc) $<
.cpp.o:
$(COMPILE.cc) $<
.S.s:
$(CPP) -o $*.s $<
.s.o:
$(COMPILE.cc) $<
.c.a:
$(COMPILE.c) -o $% $<
$(AR) $(ARFLAGS) $# $%
$(RM) $%
.C.a:
$(COMPILE.cc) -o $% $<
$(AR) $(ARFLAGS) $# $%
$(RM) $%
.cpp.a:
$(COMPILE.cc) -o $% $<
$(AR) $(ARFLAGS) $# $%
$(RM) $%
CC = gcc
CXX = g++
RM = rm -f
AR = ar
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c
CPP = $(CPP) $(CPPFLAGS)
########## Flags from header.mak
CFLAGS = -ggdb -Wall -Wextra -pedantic -std=c99 -pthread
# program uses pthreads and curses libraries
CLIBFLAGS = -lncursesw -lpthread -lrt
########## End of flags from header.mak
CPP_FILES =
C_FILES = pt-cruisers.c racer.c
PS_FILES =
S_FILES =
H_FILES = racer.h
SOURCEFILES = $(H_FILES) $(CPP_FILES) $(C_FILES) $(S_FILES)
.PRECIOUS: $(SOURCEFILES)
OBJFILES = racer.o
#
# Main targets
#
all: pt-cruisers
pt-cruisers: pt-cruisers.o $(OBJFILES)
$(CC) $(CFLAGS) -o pt-cruisers pt-cruisers.o $(OBJFILES) $(CLIBFLAGS)
#
# Dependencies
#
pt-cruisers.o: racer.h
racer.o: racer.h
#
# Housekeeping
#
Archive: archive.tgz
archive.tgz: $(SOURCEFILES) Makefile
tar cf - $(SOURCEFILES) Makefile | gzip > archive.tgz
clean:
-/bin/rm -f $(OBJFILES) pt-cruisers.o core
realclean: clean
-/bin/rm -f pt-cruisers
It looks like this
gcc -ggdb -std=c99 -Wall -Wextra -pthread -c threads.c
gcc -ggdb -std=c99 -Wall -Wextra -pthread -c makeCityFromInput.c
gcc -ggdb -std=c99 -Wall -Wextra -pthread -o threads threads.o makeCityFromInput.o -lm -lncursesw -pthread
If you show your make file we can also help with that...
I guess what you are actually asking is "What is wrong with my makefile?". As you have not provided it I can only take an educated guess. Here is a GNUmake snippet to build your program:
.PHONY: default
default: threads
CC := ...
LD := ...
CFLAGS := ...
LDFLAGS := ...
LIBS := ...
SRCS := threads.c makeCityFromInput.c
OBJS := $(SRCS:%.c=%.o)
$(OBJS): %.o: %.c
$(CC) $(CFLAGS) -o $# -c $<
threads: $(OBJS)
$(LD) $(LDFLAGS) -o $# $^ $(LIBS)

How to include clock_gettime in a c make file

I know that in order to use the clock_gettime(2) function, you have to include -lrt in the makefile but I have no idea where it goes. Where would I put it in the example makefile.
CFLAGS = -g -Wall -std=c99
CC = gcc
objects = example.o
example: $(objects)
$(CC) $(CFLAGS) -o example $(objects)
example.o: example.c
$(CC) $(CFLAGS) -c example.c
clean:
rm test $(objects)
Edit: how my lrt looks.
What my code is:
#include "stdio.h"
#include "stdlib.h"
#include <time.h>
int main(int argc, char *argv[]) {
struct timespec starttime, endtime;
double elapsed;
clock_gettime(CLOCK_REALTIME, &starttime);
/// work to be timed
clock_gettime(CLOCK_REALTIME, &endtime);
elapsed = ((endtime.tv_sec-starttime.tv_sec)*1000000000.0 + (endtime.tv_nsec - starttime.tv_nsec))/1000000000;
// elapsed time can also be calculated as
if (endtime.tv_nsec < starttime.tv_nsec) {
// borrow a second
elapsed = (endtime.tv_sec - starttime.tv_sec - 1) + (1000000000.0 + endtime.tv_nsec - starttime.tv_nsec)/1000000000;
}
else {
elapsed = (endtime.tv_sec - starttime.tv_sec ) + (endtime.tv_nsec - starttime.tv_nsec)/1000000000;
}
}
You want to put it on the line that links the executable. Namely, the line that specifies the -o option. That's where the linker phase is carried out.
example: $(objects)
$(CC) $(CFLAGS) -o example $(objects) -lrt
CFLAGS = -g -Wall -std=c99
CC = gcc
LDFLAGS = -lrt
objects = example.o
example: $(objects)
$(CC) $(CFLAGS) -o example $(objects) $(LDFLAGS)
example.o: example.c
$(CC) $(CFLAGS) -c example.c
clean:
rm test $(objects)
As this is linker option, so its best to use as LDFLAGS variable which is common practice in Makefiles.
The other answers are correct, but your problem seems to be that you're not including the necessary header files.
Add this in your source code:
#include <time.h>

SHA1 library link not found using makefile

I'm having trouble linking the sha library with my makefile while compiling.
Here is my makefile:
CFLAGS= -g -Wall -Werror -std=c99 -pedantic
LDFLAGS=-lssl -lcrypto
CC = gcc
LD = gcc
OBJS = dhtnode.o
PROG = dhtnode
.c.o:
gcc $< -o $# $(CFLAGS)
all: $(PROG)
$(PROG): $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -o $(PROG)
dhtnode.o: dhtnode.c dhtpackettypes.h
$(CC) $(CFLAGS) $(LDFLAGS) dhtnode.c
clean:
/bin/rm -f *.o dhtnode
My function using the lcrypto library is here:
#include <openssl/sha.h>
#include <stdlib.h>
#include <stdin.h>
//there are other includes but not concerning this part of the code
char sha() {
char *ibuf = malloc(sizeof(char));
ibuf ="172.0.0.1:11112";
char *obuf = malloc(SHA_DIGEST_LENGTH);
SHA1((unsigned char*)ibuf, strlen(ibuf), (unsigned char*)obuf);
int i;
for (i = 0; i < 20; i++) {
printf("%x" , (unsigned char)obuf[i]);
}
printf("\n");
return *ibuf;
}
Here is the error I get when building with Eclipse:
C/p2p/dhtnode.c:107: undefined reference to `SHA1'
Can anybody tell my what is wrong with my makefile or possible eclipse settings?
Thx in advance!
When compiling the object file, you don't need the LDFLAGS. You'll also need the -c compiler flag to produce an object file instead of linking a binary:
dhtnode.o: dhtnode.c dhtpackettypes.h
$(CC) $(CFLAGS) -c dhtnode.c
After making this change, the program compiles and links successfully for me.

Resources