A Makefile linker error - c

I have a problem that is causing me a headache, it is assumed that the command-L searches the libraries in the current directory of the Makefile, but it's not working for me, for example I have the following command in my Makefile:
...
LDLIBS = -L/libs -lmatrix
main: main.o operations.o display.o
$(CC) $(LDLIBS) $^ -o $#
...
And when I try to compile it literally says:
gcc -L/libs -lmatrix main.o operations.o display.o -o main
/usr/bin/ld: cannot find -lmatrix
collect2: ld returned 1 exit status
make: *** [main] Error 1
But when I simply change "-L/libs" for "-L$(PWD)/libs" it compiles perfectly and my program works fine...
But using "-L$(PWD)" I get another problem, if the name of any directory has a space It doesn't work again, actually I don't know if this problem is irremediable (using $(PWD) or not), but I still have the doubt that why it doesn't work without the $(PWD) because apparently (seeing A LOT of examples on the internet) using -L, the $(PWD) shouldn't be needed.

You're wrong that it's not needed. The path /libs means the libs directory at the root of your filesystem. Just like /bin doesn't mean "the bin directory under my current directory", so /libs doesn't mean the libs directory under the current directory.
If you want to look in libs in the current directory, just use -Llibs or if you want to be more specific, -L./libs (the directory . is the current directory, so cd . changes to the current directory, just like cd .. changes to the parent directory).

The path /PATHNAME means the directory at the root of your filesystem. If you want to use $(PWD) for your current directory then you can quote the shell variables like: "$(PWD)". Do not escape the quotes.

Related

Escaping spaces in LIBS path Makefile

I'm trying to include Eclipse Mosquitto library sample mosquitto example from here
I'm trying to use a Makefile to build and compile the code.
I'm facing an issue where the compiler/linker/whatsoever cannot find the mosquitto library located at C:\Program Files\Mosquitto\devel.
Here's the error:
mqtt-hostlink> make
gcc -Wall -o main main.c -LC:\\Program ,_,Files\\Mosquitto\\devel\mosquitto.lib
gcc: error: ,_,Files\Mosquitto\devel\mosquitto.lib: No such file or directory
make: *** [Makefile:11: make] Error 1
Here's my Makefile:
CC = gcc
null :=
SPACE := $(null) $(null)
LIBS = -LC:\\Program$(SPACE),_,Files\\Mosquitto\\devel\mosquitto.lib
%.o: %.c
$(CC) -c -o $# $<
make: main.c
$(CC) -Wall -o main $^ $(LIBS)
.PHONY: clean
The "space" method I referred from : How to escape spaces inside a Makefile
You can just use the short name for tar directory. List the directories with /X option as below
C:\>dir /X p*
Directory of C:\
09/06/2021 02:24 PM <DIR> PROGRA~1 Program Files
09/06/2021 01:29 PM <DIR> PROGRA~2 Program Files (x86)
0 File(s) 0 bytes
Then just use PROGRA~1 instead of Program Files
There's some confusion here. That post is about how to escape spaces from make functions. You are not trying to invoke any make functions here, you are just trying to use a variable in a command line. There's no need to escape anything from make.
What you need to do is escape the spaces from the shell, not from make. You can do that easily, just using quotes. No need for fancy make operations. I recommend you also use forward-slashes, not backslashes. Almost all Windows programs accept both forward and backslashes. Only cmd.exe built-ins don't.
LIBS = "-LC:/Program Files/Mosquitto/devel/mosquitto.lib"

Makefile, "nothing to be done for all" error

So I have a make file, stored in a directory called "temp" the following directory has a src folder, with 2 .c files "file1.c" and "file2.c". The temp directory also holds a include folder (which is empty), and a bin folder (which is empty until the make command is so posed to be run). I'm currently to trying get a single .c file to compile (get it working),but a single file doesn't even seem to work here.
This is how the directories look:
temp
cd into temp..
bin include Makefile src
Here is my makefile:
all:
gcc -Wall -pedantic -std=c99 src/file1.c -Iinclude -o bin/runMe -lncurses
And yes, there is a tab before the gcc. Any help on this frustrating issue, would be much appreciated. Also, if possible any input on compiling the second .c file, would also be very helpful!
Nothing to be done for TARGET means that a target has no commands which, in this case, almost certainly means that you do not have a tab on that gcc line.
That being said that's only the immediate problem. This makefile is also not following good practices and will unnecessarily recompile your program (as well as ceasing to work entirely should an all file be created).
DrC had, in a currently deleted answer, very good suggestions for how to improve your makefile to avoid both of those latter issues.
Specically, your makefile should look more like this:
.PHONY: all
all: bin/runMe
bin/runMe: src/file1.c
gcc -Wall -pedantic -std=c99 $^ -Iinclude -o $# -lncurses
Which marks the all target as a .PHONY so that an all file or directory getting created won't confuse make as well as setting up a prerequisite on the source file for your built binary so that make can tell when it does (and doesn't) need to rebuild the binary.

gcc doesn't find header file in static library I made

I made a static library.
This not have error, library file too.
So, I tried use that library.
gcc -o hash_gen main.c -L../ -lhashbundle
Library file exist in that directory ../, library file name is libhashbundle.a.
So, I thought not have problem in this command.
but I tried compile with gcc, but gcc print this error.
main.c:4:10: fatal error: 'hash.h' file not found
#include "hash.h"
^
I don't understand. I made library make, and this is Makefile
all : libhashbundle.a
libhashbundle.a : hash.o
ar rscv libhashbundle.a hash.o
hash.o : src/hash.c
gcc -c src/hash.c
clean:
rm -rf hash.o
I thought this code many times, but I didn't found error.
and this is directory tree
tree
Makefile
libhashbundle.a
|src
|hash.c
|hash.h
|test
|main.c
So, I ask to you.
How could solve this problem?
You only specified a library search path (-L).
If you want a header search path, you need to use -I.
gcc -o hash_gen main.c -I.. -L.. -lhashbundle
The problem is the fact that you're running your build from your "root" directory, not from /src/. So when the compiler sees #include "hash.h" it will try to open the file in the current directory, which will be / rather than /src/ (where the files are).
To fix this, just add your source directory to the include search paths using -Isrc:
gcc -o hash_gen main.c -Isrc -lhashbundle
Note that I omitted -L since the library file is in your current working directory and should be found there anyway.

Unable to understand the errors given by running make

My directory structure is /home/akshayaj/Desktop/System Programs/dictionary/
Inside dictionary I have 3 files:
libdictionary.c (implements all the functions except main),
libentrypoint.c (contains main()),
libdictionary.h (contains declaration of all the functions)
Both C files include the header file
Now I wrote a make file for the above project. It goes like this:-
CFLAGS=-I /home/akshayaj/Desktop/System Programs/dictionary/
libdict: libentrypoint.o libdictionary.o
cc $(CFLAGS) -o libdict libentrypoint.o libdictionary.o
libentrypoint.o: libentrypoint.c libdictionary.h
cc $(CFLAGS) -c libentrypoint.c
libdictionary.o: libdictionary.c libdictionary.h
cc $(CFLAGS) -c libdictionary.c
Now when I ran it, I got these errors:-
cc -I /home/akshayaj/Desktop/System Programs/dictionary/ -c libentrypoint.c
cc: error: Programs/dictionary/: No such file or directory
make: *** [libentrypoint.o] Error 1
Where am I going wrong?
Note:- In CFLAGS I have given the whole path because I saw it in a similar question, but that didn't work. Here is the link to that question.
C Compile Error (No such file or directory, compilation terminated)
Try to use path /home/akshayaj/Desktop/System\ Programs/dictionary/, where \ handles the space.
Think about how that command line would be parsed...
cc -I /home/akshayaj/Desktop/System Programs/dictionary/ -c libentrypoint.c
^^ ^------------------------------^ ^------------------^ ^-----------------^
| | | |
Command -I arg BAD ARG -c arg
As you can see, the space between "System" and "Programs" is read as a separator between two command args.
Your options are either:
Change the path so that the space is removed (recommended). e.g. /home/akshayaj/Desktop/System-Programs/dictionary/.
Add a backslash before the space to escape it. e.g.:
/home/akshayaj/Desktop/System\ Programs/dictionary/
As a general rule, it's not wise to use paths with spaces in them when building stuff using make, or just building stuff in general. It makes ambiguities like this hard to solve.

makefile not finding the .o file

I have the strangest problem.
when I run : make tests
in the console I get the following error:
gcc: album_test.o: No such file or directory
sorry for attaching the content as a pic,
the site kept giving me a: "Your post appears to contain code that's not properly formatted
as code"
when I change this line :
album_test.o: ./tests/album_test.c album.h
to be :
album_test.o: album_test.c album.h
and place the album_test.c in the same directory as the makefile
everything compiles!
It's very important that the file will be in a separate tests directory.
any ideas?
Thanks!
You're trying to use make's built-in implicit rules to build your object files. That works when make can find the source file in the current directory, but not otherwise. Update this rule:
album_test.o: ./tests/album_test.c album.h
To include a recipe:
album_test.o: ./tests/album_test.c album.h
$(CC) $(CFLAGS) -c -o $# $<

Resources