Can't get my C program to compile. Makefile error - c

I am trying to create a new C program, but I can't get the program to compile. This is because my makefile seems to be wrong. I keep getting "No rule to make target 'all'" and "No rule to make target 'clean'". Here is what I have so far:
Main program:
#include <stdio.h>
Sleepy() {
main (); {
printf("Hello world");
}
}
Header (Although I haven't done anything to it yet):
#ifndef SLEEPY_H_
#define SLEEPY_H_
#endif /* SLEEPY_H_ */
And the Makefile:
CC = gcc
CFLAGS = -c
Sleepy.o: Sleepy.c Sleepy.h
$(CC) $(CFLAGS) Sleepy.c
Sleepy: Sleepy.o
$(CC) -o Sleepy.exe Sleepy.o
all: Sleepy
clean:
rm -rf *.0 a.out
make = all
I've been reading all kinds of tutorials, but I can't seem to get it to work. Would someone help me with this?

To achieve your compilation, following changes are required.
Sleepy.c
#include <stdio.h>
int main (void) {
printf("Hello world");
}
Makefile
CC = gcc
CFLAGS = -c
all: Sleepy
Sleepy.o: Sleepy.c Sleepy.h
$(CC) $(CFLAGS) Sleepy.c
Sleepy.exe: Sleepy.o
$(CC) -o Sleepy.exe Sleepy.o
clean:
rm -rf *.o Sleepy.exe
Please note the change in clean rule of your Makefile. You will have to remove the executable which is Sleepy.exe
NOTE: The rules for Sleepy.o and Sleepy should be offset by a TAB and not space. Else, you will run into this error: makefile:5: *** missing separator. Stop

try this one,
All: sleepy
sleepy: sleepy.c sleepy.o sleepy.h
gcc sleepy.c -o sleepy
clean:
rm -f *.o

Related

Getting 'undefined reference to' function although I have clearly included the files

I have 3 files:
main.c
#include "fle.h"
int main(int argc, char **argv) {
FILE *fptr = checkFile(argv[1]);
}
fle.c
#include "fle.h"
FILE *checkFile(char *path)
{
...
}
fle.h
#include <stdio.h>
#include <stdlib.h>
#ifndef FLE_H_
#define FLE_H_
FILE *checkFile(char *path);
#endif
My makefile looks like this
CC = gcc
CFLAGS = -g -Wall
TARGET = main
all: $(TARGET)
$(TARGET): $(TARGET).c
$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c
clean:
$(RM) $(TARGET)
As a minimal (non)working example, it throws an error
/main.c:4: undefined reference to `checkFile'
I'm curious why the checkFile function is surrounded by backtick from the left and apostrophe from the right, it doesn't seem right, but I don't think that's the problem.
I'd appreciate any help regarding this issue, it might be something trivial, but clearly I'm not skilled enough to resolve it myself.
EDIT: I have renamed the names from file to fle everywhere to prevent some collisions with the system libraries, but it didn't change a thing.
While you include the declaration you need to link in the definition. The easiest thing is to change the Makefile as follows:
CC = gcc
CFLAGS = -g -Wall
TARGET = main
all: $(TARGET)
$(TARGET): $(TARGET).c fle.c
clean:
rm -f $(TARGET)

Undefined reference to function that is already defined in my header file

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!~

Trouble Writing My First Makefile

So here is my Makefile:
# My First Makefile
HEADERS = stdio.h
all: main.o input.o output.o
cc -o all main.o input.o output.o
main.o: main.c $(HEADERS)
cc -c main.c -o main.o
input.o: input.c $(HEADERS)
cc -c input.c -o input.o
output.o: output.c $(HEADERS)
cc -c output.c -o output.o
clean:
-rm -f *.o
-rm -f all
And below is input.c:
#ifndef __STDIO_H__
#define __STDIO_H__
#include <stdio.h>
void getChar()
{
getchar();
}
#endif
Below is output.c:
#ifndef __STDIO_H__
#define __STDIO_H__
#include <stdio.h>
void putChar(char c)
{
putchar(c);
}
#endif
Below is main.c:
#ifndef __STDIO_H__
#define __STDIO_H__
#include <stdio.h>
int main()
{
char c;
while ((c = etChar()) != '\n')
{
putChar(c);
}
}
#endif
Yet whenever I press "make" command in Terminal,
I get:
make: *** No rule to make target `stdio.h', needed by `main.o'. Stop.
cc refers to clang
What is it that I am doing wrong here?
I was trying to get used to $(ARGS) by using $(HEADERS)
but it seems that the clang compiler does not accept this.
Do you think I should use gcc instead?
It is unnecessary to write stdio.h in your Makefile. GCC will automatically search it in DEFAULT PATH (/usr/include, ....). Write header files as targes in Makefile only if you use your own header files.
# Makefile
# define CC
CC := gcc
# define final targets
TARGETS := main
# just trigger $(TARGETS)
all: $(TARGETS)
# build main from main.o, input.o, output.o
main: main.o input.o output.o
$(CC) -o $# $^
# build main.o/input.o/output.c from main.c/input.c/output.c
%.o: %.c
$(CC) -c -o $# $<
# trigger $(TARGETS), then run ./main
run: $(TARGETS)
./main
clean:
-rm $(TARGETS)
-rm *.o
# define targets which are not bound to file
.PHONY: all clean run
In your case:
"make" will look for stdio.h in the current directory, and is complaining that the header is not found.
Just to fix this, you should mention the full path where stdio.h is located, for example:
HEADERS = /usr/include/stdio.h
Ideally, if you want to check for the presence of standard headers like stdio.h, you should use tools like automake and autoconf, which generate the Makefile automatically. Here's a link which points to the autoconf documentation:
https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html

Makefile with multiple files always builds everything

I am writing a Makefile which compiles a number of C files, some in the same directory as the Makefile and others in parent directories (must be there for historic reasons). I want to put all *.o files in a single directory (objdir in my case). This seems to work, but for some reason, this Makefile always builds everything, even if nothing has changed. Where am I going wrong in my rules/dependecies?
UPDATE: I've distilled my Makefile and sources down to the bare minimum (see below for source file contents. To be clear, this does compile and link. The problem is that it does the compilation and linking every time I run make, even if nothing has changed. This is not typical make behavior.
Makefile contents:
CC = gcc
CFLAGS = -g -Wall -Werror -I..
SRCS = main.c ../a.c
OBJS = $(patsubst %.c, objdir/%.o, $(SRCS))
LN_OBJS = $(patsubst %.c, objdir/%.o, $(notdir $(SRCS)))
MAIN = foo
.PHONY: clean
default: objdir $(MAIN)
#echo Done
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) -o $(MAIN) $(LN_OBJS )
objdir/%.o: %.c
$(CC) $(CFLAGS) -c $< -o objdir/$(notdir $#)
objdir:
#mkdir -p objdir
clean:
#$(RM) -rf objdir $(FDP) $(DK)
main.c contents
#include "stdlib.h"
#include "stdio.h"
#include "a.h"
int main(int argc, char**argv)
{
printf("Hello\n");
a();
}
../a.c contents
#include <stdio.h>
void a()
{
printf("Hi from a\n");
}
../a.h contents
#ifndef __a__
#define __a__
void a();
#endif
Your rule for objdir/%.o: is expanded to objdir/../a.o: ../a.c, but you then go and create objdir/$(notdir $#), violating rule 2 of the Rules of Makefiles.
One way to fix this is with vpath (also note that objdir should be a (order-only) dependency of the objects):
SRCS = main.c a.c
vpath %.c ../
# [...]
objdir/%.o: %.c | objdir
$(CC) $(CFLAGS) -c $< -o $#

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