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.
Related
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.
I have three files, posl.h, state.c and main.c. What I plan on doing is adding functions that are used throughout the project in posl.h, and then I call it to test the function with main.c, and then make the function in state.c. The problem I am having is that I keep getting an error of undefined reference to init_poslState() even though I have it defined in posl.h
main.c
#include <posl.h>
int main(int argc, char * argv[]) {
pState poslState = init_poslState();
return 0;
}
posl.h
#ifndef POSL_LANGUAGE_H
#define POSL_LANGUAGE_H
#define POSL_MAJOR_VERSION 1
#define POSL_MINOR_VERSION 0
#define POSL_RELEASE_VERSION 0
// State
typedef struct POSL_STATE {
// ...
} pState;
pState init_poslState();
void free_poslState(pState poslState);
#endif
state.c
#include "state.h"
#include <posl.h>
pState init_poslState() {
pState newState;
return newState;
}
Makefile
CFLAGS=-g -Wall -Wextra -I./include
CC=gcc $(CFLAGS)
CORE_O_FILES=./src/Core/lexer.o ./src/Core/parser.o ./src/Core/state.o
CLI_O_FILES=
O_FILES=$(CORE_O_FILES)
# Making CLI Tool
posl: $(CLI_O_FILES) libposl.a ./src/CLI/main.c
$(CC) -o posl -L./ -lposl ./src/CLI/main.c $(CLI_O_FILES)
# Making Library
libposl.a: $(O_FILES) ./include/posl.h
ar rcs libposl.a $^
# Core Files
./src/Core/lexer.o: ./src/Core/lexer.c ./src/Core/lexer.h
$(CC) -o $# -c ./src/Core/lexer.c
./src/Core/parser.o: ./src/Core/parser.c ./src/Core/parser.h
$(CC) -o $# -c ./src/Core/parser.c
./src/Core/state.o: ./src/Core/state.c ./src/Core/state.h
$(CC) -o $# -c ./src/Core/state.c
# PHONY List
.PHONY: all
all:
make update-libs
make libposl.a
make posl
make pcc
# Post-Compile Clean
.PHONY: pcc
pcc:
rm -rf ./src/Core/*.o
rm -rf ./src/CLI/*.o
.PHONY: clean
clean:
make pcc
rm -rf ./libposl.a ./posl*
The order of compiler and (especially) linker options is significant. With this command ...
$(CC) -o posl -L./ -lposl ./src/CLI/main.c $(CLI_O_FILES)
... the linker will not attempt to resolve any function references from main.c against functions in libposl.a. It will look only to objects and libraries appearing after main.c on the command line.
Therefore, rewrite that recipe to
$(CC) -o posl -L. ./src/CLI/main.c $(CLI_O_FILES) -lposl
Welp, #user17732522 answered my question. I had the -l flag messed up, and it wasn't after my source files. ~Thank you guys!~
I want to have Makefile for my static library where I can conditionally build it as program to perform simple self-test. My current Makefille looks like follows:
OBJECTS = sm3.o ./core/sm3_internal.o
INCLUDES = -I. -I./core
CFLAGS = -g -Wall -O3
CC = c99
OUT = libsm3.a
%.o: %.c
$(CC) -c -o $# $< $(CFLAGS) $(INCLUDES)
$(OUT): $(OBJECTS)
ar rcs $(OUT) $(OBJECTS)
At my main library file I have:
#ifdef TEST
main(int argc, int* argv[])
{
//my self-test logic here
}
#endif
Where should I add -DTEST flag? If I add it to CFLAGS and then add line:
test: $(OBJECTS)
library also would be build with main, which obviously is not something I want.
I would suggest that you compile main.c conditionally instead:
$(TESTOUT): $(OBJECTS) $(TESTOBJ)
$(CC) -o $# $<
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>
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 *~