Makefiles giving the compiler files that dont/shouldnt exist - c

I have a basic Makefile setup for C OpenGL programming but when running there are 2 files passed to clang that shouldnt exist and i have no idea why. The problem happened after i added glad and glfw to the project.
code:
CC = clang
`CCFLAGS = -lGL -lglfw -std=c++20 -v -Wall -Wextra -Wepedantic -g -lgdi32
LDFLAGS = lib/glad/src/glad.o lib/glfw/src/libglfw3.a -lgdi32 -lm
SRC = $(wildcard src/*.c)
OBJ = $(SRC:.c=.o)
BIN = bin
all: libs build
libs:
cd lib/glad && $(CC) -o src/glad.o -Iinclude -c src/glad.c
cd lib/glfw && cmake . -G 'Unix Makefiles' && make
build: $(OBJ)
$(CC) -o $(BIN)/build $^ $(LDFLAGS)
%.o %.c:
$(CC) -o $# -c $< $(CCFLAGS)
run:
./bin/build.exe
ERROR:
clang: error: no such file or directory: 'all.o'
clang: error: no such file or directory: 'libs'
clang: error: no such file or directory: 'build'

When asking questions please include the command you typed, the command make printed, plus at least the first and last few lines of error messages (properly formatted as code blocks).
I'm assuming that the extra quote character is an error in your cut and paste; please take a moment to review your question after you post it (or even better, using the preview before you post it). You are writing this one time, but tens or hundreds of people will spend their time reading it. Please be considerate enough to make it easy for them.
Your problem is this:
%.o %.c:
$(CC) -o $# -c $< $(CCFLAGS)
You want to say "build a .o file from a .c file using this rule", but %.o %.c: says instead, "build both a .o and a .c file, from nothing, using this rule".
You need:
%.o: %.c
$(CC) -o $# -c $< $(CCFLAGS)

Related

Handling #include <folder/file.h> in C with makefiles

I am in the process of porting some code that was developed in the codeblocks IDE. I am transferring it to a Linux server where I can only use the command line to compile the code. The code is quite large (maybe 100 files) and I need to update the include commands in many files. For when I try to compile it errors on for instance: #include <gsl/gsl_math.h> with a file cannot be found error. I am assuming it cannot be found because the location of the gsl folder was declared in one of the search directory field options in the IDE. I could go through each file an update to the correct path, but is there a better way of doing this for use with a makefile?
Thanks!
EDIT Makefile In Question
# -c : do not link, just create object file
# -o : output file name
CFLAGS += -c -O2 -I../ctraj -I../cspice/include -I../SGP4 -I../cconj -I../GSL-1.13/include
LIBS = -L../ctraj -lctraj -L../cspice/lib -lcspice -L../SGP4 -lsgp4 -L../cconj -lcconj -L./ -lgsl-0 -lgslcblas-0 -lm
DEPS = light.h ../ctraj/ctraj.h ../cconj/cconj.h
OBJ = light.o tle.o propagator.o orbitfit.o conjunction.o light_displacement.o forces_LF.o
OUT = light.exe
%.o: %.c $(DEPS)
gcc -o $# $< $(CFLAGS)
light: $(OBJ)
cd ../ctraj/; make
gcc -o $(OUT) $(OBJ) $(LIBS)
clean:
rm *.o $(OUT)
Edit 2
Folder Structure
light->(GSL-1.13, Light, cconj, ctraj)
the makefile is inside the Light folder.
Error Message
cd ../ctraj/; make
make[1]: Entering directory `/light/ctraj'
gcc -o forces.o forces.c -c -Wall -Wno-maybe-uninitialized -Wno-unused-but-set-variable -O2 -I../cspice/include -Inrlmsise
In file included from ../Light/../cconj/cconj.h:12:0,
from ../Light/light.h:13,
from forces.c:3:
../Light/../cconj/../GSL-1.13/include/gsl/gsl_blas.h:26:28: fatal error: gsl/gsl_vector.h: No such file or directory
compilation terminated.
make[1]: *** [forces.o] Error 1
make[1]: Leaving directory /light/ctraj'
make: *** [light] Error 2
EDIT 3
Second makefile in cconj
# -c : do not link, just create object file
# -o : output file name
#-L../cconj -lcconj
CFLAGS += -c -O2 -I./ -I../GSL-1.13/include
LIBS = -L./ -lgsl-0 -lgslcblas-0 -lm
INC= -I../GSL-1.13/include
DEPS = cconj.h
OBJ = cconj_util.o ellipse_intersect.o collision_prob_real.o rcs2size.o
OUT = libcconj.a
%.o: %.c $(DEPS)
gcc -o $# $< $(CFLAGS)
cconj: $(OBJ)
ar rcs $(OUT) $(OBJ)
clean:
rm *.o $(OUT)
Try adding this line to your makefile, and tell us if it works:
CFLAGS += -I../GSL-1.13/include
In order to compile source code and produce object files, Make must use a rule. (If you don't put such a rule in the makefile, Make has a default rule for that purpose.) It looks something like this:
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Without digging too deeply into how that works, we can say that CFLAGS is a list of arguments to be passed to the compiler. When we add -I../GSL-1.13/include, we tell the compiler "if you want to #include something and can't find it elsewhere, look in ../GSL-1.13/include".
If this approach doesn't work, then there's probably a rule in the makefile we must find and alter.
EDIT:
The problem isn't in this makefile (which already contains a reference to GSL-1.13/include). In this command:
cd ../ctraj/; make
this makefile launches a second Make process, which uses the Makefile in light/cconj/. According to the compiler output (gcc -o forces.o ...), that makefile does not include the reference. So try adding the same line there, and if that doesn't work, post that makefile and we'll keep looking.
Use -I option of gcc to specify where to look for includes.

Adapt Makefile for cross-compilation

I have a makefile that works fine when I compile using /usr/bin/gcc to compile it. However I'm trying to compile it using a crosstool-ng compiler. I've changed CC to the cross-compilers location, and added a prefix to the directory that holds the compiler, but I get an error compiling.
The Makefile is here (sorry, it's long):
CFLAGS ?= -Wall -O0 -ggdb3
PREFIX = /home/me/crosstool-ng-1.18.0/x-tools/i586-system-linux-gnu/
CC = /home/me/crosstool-ng-1.18.0/x-tools/i586-system-linux-gnu/bin/i586-system-linux-gnu-gcc
ALL_CFLAGS = $(CFLAGS) -D_GNU_SOURCE
.phony: all
all: food libfood.so.1.0.0 foo_query
.phony: tools
tool tools: libfood_print foo_print
.phony: install
install: libfood.so.1.0.0
cp libfood.so.1.0.0 $(PREFIX)/lib
cd $(PREFIX)/lib ; \
ln -sf libfood.so.1.0.0 libfood.so.1 ; \
ln -sf libfood.so.1 libfood.so
cp libfood.h $(PREFIX)/include
cp foo_data.h $(PREFIX)/include
cp food $(PREFIX)/bin
cp foo_query $(PREFIX)/bin
%.o: %.c
$(CC) $(ALL_CFLAGS) -c $<
food: food.o foo.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lm -lpthread
libfood.so.1.0.0: libfood.o
$(CC) -shared -Wl,-soname,libfood.so.1 -o libfood.so.1.0.0 libfood.o
libfood_print: libfood_print.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lfood
foo_print: foo_print.o foo.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lm -lpthread
foo_query: foo_query.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lfood
food.o: food.c foo.h foo_data.h
foo.o: foo.c foo.h foo_data.h
foo_print.o: foo_print.c foo_data.h
foo_query.o: foo_query.c foo_data.h
libfood.o: libfood.c libfood.h
$(CC) $(ALL_CFLAGS) -fPIC -c $<
foo_print.o: foo_print.c foo.h
.phony:clean
clean:
rm -rf *.o *~ food libfood.so.1.0.0 foo_print libfood_print foo_query
The error message I'm getting says cannot find -lfood
collect2: ld returned 1 exit status
If anyone could suggest a fix for this I'd be very grateful.
EDIT: My Solution:
I should probably have been clearer but this Makefile was being used to build a package that was included in buildroot. I tried the suggestion by Jonatan, but unfortunately I still got the same error. My workaround was to run buildroot using make -k, and then build again using make.
An easy way to solve this would be:
ALL_CFLAGS += -L$(PREFIX)/lib
If you really want to install your lib in the toolchain, you should look for the usr/lib directory, usually the path is TOOLCHAIN_DIR/TOOLCHAIN_PREFIX/sysroot/usr/lib
Check other binaries in the $(PREFIX)/lib directory, you will notice that they were compile to run in you host, and not in your target.
The files the compiler need to check dependencies, link, and execute in your target, are installed in the sysroot directory.

C Makefile trouble: "gcc: -lm: linker input file unused because linking not done mpicc -lm 3D-ELM.o -o 3D-ELM.exe"

I'm having some trouble with a C Makefile.
Here are the contents of the Makefile:
PROJECT = 3D-ELM
MPICC = mpicc
CLAGS = -g -O3
LIBS = -lm
SRC = src_el
OBJECTS = $(PROJECT).o
$(PROJECT).exe : $(OBJECTS)
$(MPICC) $(CFLAGS) $(LIBS) $(OBJECTS) -o $(PROJECT).exe
$(PROJECT).o : $(SRC)/$(PROJECT).c
$(MPICC) $(CFLAGS) $(LIBS) -c $(SRC)/$(PROJECT).c
clean:
rm -rf *o $(PROJECT)
When I make, here is the error:
gcc: -lm: linker input file unused because linking not done
Does anyone know what's wrong?
Many thanks in advance,
EDIT: Got it. I don't need to pass libs when making the object file... Doh! bangs head off desk
Thanks for all your help guys,
The problem comes from this part of the makefile:
$(PROJECT).o : $(SRC)/$(PROJECT).c
$(MPICC) $(CFLAGS) $(LIBS) -c $(SRC)/$(PROJECT).c
At this step you are only invoking the compiler. The -c switch tells the compiler only to compile to an object file, and the linker is not involved at all. Since there is nothing to link, the $(LIBS) part is unnecessary.
The actual linking is done at the following stage:
$(PROJECT).exe : $(OBJECTS)
$(MPICC) $(CFLAGS) $(LIBS) $(OBJECTS) -o $(PROJECT).exe
This is where the individual object files are merged together with the libraries to produce an executable. The compiler itself is not invoked at this point because the source files have already been transformed into object files.

linking and compiling with Makefile

gcc 4.7.2
c89
GNU Make 3.82
I am trying compile this program I have using this Makefile. I have only 1 src file at the moment, but I will have more later to include.
I am trying to get the Makefile to create the bin directory if it doesn't exist and put the binary executable in there.
INC_PATH=-I/home/dev_tools/apr/include/apr-1
LIB_PATH=-L/home/dev_tools/apr/lib
LIBS=-lapr-1
RUNTIME_PATH=/home/dev_tools/apr/lib
CC=gcc
CFLAGS=-Wall -Wextra -g -m32 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE -O2 $(INC_PATH)
OBJECTS=timeout.o
EXECUTABLE=bin/to
all: build $(EXECUTABLE)
$(EXECUTABLE):
$(CC) -m32 -o $# -Wl,-rpath,$(RUNTIME_PATH), $(LIB_PATH) $(OBJECTS) $(LIBS)
build:
#mkdir -p bin
clean:
rm -rf *~ timeout *.o
I am getting this error:
make
gcc -m32 -o bin/to -Wl,-rpath,/home/dev_tools/apr/lib, -L/home/dev_tools/apr/lib timeout.o -lapr-1
gcc: error: timeout.o: No such file or directory
make: *** [bin/to] Error 1
When I remove the $(OBJECTS) I get the following:
gcc -m32 -o bin/to -Wl,-rpath,/home/dev_tools/apr/lib, -L/home/dev_tools/apr/lib -lapr-1
/usr/bin/ld: cannot find : No such file or directory
collect2: error: ld returned 1 exit status
make: *** [bin/to] Error 1
Not sure where I am going wrong with this.
You have not specified how to build the target timeout.o.
You need to add the following code:
timeout.o: timeout.c
$(CC) $(CFLAGS) -c -o $# $<
If you end up with more source file that you need compiled, you can use a pattern matching rule like this:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
Makefiles can be a bit tricky. Because you want to continue adding more objects to your OBJECT variable, I would actually add a prerequisite to EXECUTABLE to make sure all of your objects are compiled. From there, the automatic rule inference should take care of the rest.
Basically replace the line with:
$(EXECUTABLE): $(OBJECTS)
$(CC) -m32 -o $# -Wl,-rpath,$(RUNTIME_PATH), $(LIB_PATH) $(OBJECTS) $(LIBS)
Its showing error because make is not able to find timeout.o file in the current directory.
If you have timeout.c file then add the following to your makefile
OBJECTS: timeout.c
$(CC) -c timeout.c

Using -mno-cygwin option inside GCC 4.6

I am working on winexe project currently. winexe compiles windows C code on linux using -mno-cygwin as CFLAGS .
following is Makefile under directory winexesvc :-
CFLAGS=-mno-cygwin -Os
LDFLAGS=-mno-cygwin -s -Os
CC_WIN32 := $(shell bash -c 'which {i386,i586}-{mingw32,mingw32msvc}-gcc')
CC_WIN64 := $(shell bash -c 'which {x86_64,amd64}-{mingw32,mingw32msvc}-gcc')
all: winexesvc32_exe.c winexesvc64_exe.c
winexesvc32.exe: winexesvc32.o service32.o
$(CC_WIN32) $(LDFLAGS) -o $# $^
winexesvc64.exe: winexesvc64.o service64.o
$(CC_WIN64) $(LDFLAGS) -o $# $^
%32.o: %.c
$(CC_WIN32) -c $(CPPFLAGS) $(CFLAGS) -o $# $^
%64.o: %.c
$(CC_WIN64) -c $(CPPFLAGS) $(CFLAGS) -o $# $^
winexesvc32_exe.c: winexesvc32.exe bin2c.exe
./bin2c.exe winexesvc32_exe winexesvc32.exe > $#
winexesvc64_exe.c: winexesvc64.exe bin2c.exe
./bin2c.exe winexesvc64_exe winexesvc64.exe > $#
bin2c.exe: bin2c.c
gcc -s -o $# $^
clean:
-#rm *.exe *.o *_exe.c
The entire code compiles and run successfully when no modification is done.
But,whenever I replace winexsvc.c file or winexesvc64_exe.c file or winexesvc32_exe.c
(I need to modify these 3 files). It shows following error when I replace winexesvc.c with modified code. The modified code dosen't call any other file or any function outside the file.
So, the problem is when I do some modifications in above mentioned 3 files, I get above mentioned errors.
Any Idea why this is happening ?
P.S :- I have read other post regarding error of -mno-cygwin option in gcc.
but those are not relevant to my problem.
additional information :-
[I have got this from Makefile of winexesvc folder under winexe.]
Solved :-
I used i586-mingw32msvc-gcc command along with suitable flags to compile every file by hand then linking it accordingly.
Got , the required results.

Resources