Not finding the library files directed to in Makefile - c

I am trying to compile this tool. Below is the beginning of its Makefile:
CC = gcc
CFLAGS = -Wall -O2 -D TRACES
DFLAGS = -g -Wall -o0
CPPFLAGS= $(INCLUDES:%=-I %)
LDFLAGS = $(LIBRARIES:%=-L %)
LDLIBS = $(USED_TOOLS:%=-l%)
MY_FILES =
INCLUDE_DIR = ~/include
TOOLBOX_INC = $(INCLUDE_DIR)/tools
TOOLBOX_LIB = $(TOOLBOX_INC)
USED_TOOLS = std_io stringutils
INCLUDES = $(TOOLBOX_INC)
LIBRARIES = $(TOOLBOX_LIB)
I also have ~/include/tools which after compiling includes std_io.o, libstd_io.a, stringutils.o and libstringutils.a
I am getting the following error:
gcc -L ~/include/tools rank.o counterexample.o -lstd_io -lstringutils -o rank
ld: library not found for -lstd_io
collect2: ld returned 1 exit status
make: *** [rank] Error 1
I am not sure if things are not included correctly, and why it is not finding the library files.
Edit: turns out I accidentally left a space between the -L and -I options. Also, the paths had to be expanded I guess. It's working now, thanks!

The problem is the use of the tilde to mean "Home directory". A shell will do tilde expansion only if the tilde is the first nonquoted character in a word. Makefiles never do tilde expansion. Thus, in
gcc -L~/include ...
the shell does not perform tilde expansion and gcc will look for a directory named "~/include" in the current directory. But in
gcc -L ~/include ...
the shell does perform tilde expansion and gcc sees
gcc -L /usr/username/include ...
instead, which works as expected. The right thing to do is to never use tilde expansion for the home directory, but simply use $HOME appropriately in the Makefile, e.g.
INCLUDE_DIR = $$HOME/include

Related

How to add a new header file location in the compiler

Various resources have mentioned about the -I option of gcc , but have not mentioned its syntax. I want to add a header file which is not present in the default directory which are taken into consideration by the compiler for adding the header files at the compile time. How can I achieve it?
Just as the man page says, follow the argument directly with the path.
gcc ... -I/path/to/headers ...
You can use the -I option:
gcc -o foobar -I/path/to/headers -I/path/to/other foobar.c
You can also use the C_INCLUDE_PATH environment variable. You could set this up in your makefile:
C_INCLUDE_PATH = /path/to/headers:/path/to/other
foobar: foobar.c
gcc -o foobar foobar.c
You can either add a -I option to the command line to tell the compiler to look there for header files. If you have header files in include/ directory, then this command should work for you.
gcc -Iinclude/
There shouldn't be any space between -I compiler option and directory location.
If, you are using makefile, you can include this option in CFLAGS macro in your makefile.
CFLAGS = -Iinclude/ -c -Wall
OR
You can include header files using #include "../include/header.h".
Have a look at this answer.

Cannot including files with GCC

I am working in this project that requires me to use some software that was written a long time ago and is now open sourced and can be found at http://www.wotug.org/occam/compilers/oc/oc-src.tar.gz. The software is basically a compiler for Occam.
When I unpack the tar.gz I find a source folder that has a csh script to build the software.
#!/bin/csh -f
#
# Quick build script for occam compiler and libraries
#
# You will need to redefine these
set gccinclude = "/u/products/toolset/release/build/include/gcc"
set inmos_occam = /inmos/prod/d4205a
# These should be ok
set base_dir = $cwd
set path = ($inmos_occam/tools $base_dir/preocc $path)
setenv ISEARCH "$base_dir/libs/ $base_dir/include/ $gccinclude/"
set buildlibs = (arglib extlib tcofflib)
foreach buildlib ($buildlibs)
echo --- $buildlib
cd $buildlib
make -f [Mm]akefile.s4 COMMON=$base_dir GCCINCLUDE=$gccinclude TLIB=
cd ..
end
... some other stuff...
I believe the lines:
set gccinclude = "/u/products/toolset/release/build/include/gcc"
set inmos_occam = /inmos/prod/d4205a
specify where the .h files are stored for the compilation process and the inmos_occam variable tells where I would like the final binary to be stored, so I changed them to:
set gccinclude = "/usr/include"
set inmos_occam = ./bin
The problem is that when I run the script I get the following errors:
--- arglib
gcc -I./ -nostdinc /usr/include ./arg.c -c -o arg.o -ansi -DSUN4
./arg.c:9:19: fatal error: ctype.h: No such file or directory
#include <ctype.h>
^
compilation terminated.
make: *** [arg.a] Error 1
--- extlib
gcc -c -msoft-float -Wall -ansi -pedantic -nostdinc /usr/include I/home/andres/Documents/T2015-Compiler/src/include -DGNU extconv.c
In file included from /home/andres/Documents/T2015-Compiler/src/include/extlib.h:8:0,
from extconv.c:1:
/home/andres/Documents/T2015-Compiler/src/include/imsstd.h:30:19: fatal error: stdio.h: No such file or directory
#include <stdio.h>
....and a lot more....
I dont know much about GCC, but I believe the problem is that the argument '-nostdinc' tells the compiler to not look in the standard include directories (where the files are in my ubuntu system) and that is why it is not working. However, I do not how to overwrite this behaviour. I would greatly appreciate help so that I can compile this, also if you believe this is not the cause of the problem, please do let me know.
Thanks!
-nostdinc means that you are ignoring the standard include path, which I'm guessing you don't want. However I can see:
gcc -I./ -nostdinc /usr/include ./arg.c -c -o arg.o -ansi -DSUN4
/usr/include should be like -I/usr/include in order to include that to the include path.
Later you have
I/home/andres/Documents/T2015-Compiler/src/include
which should be
-I/home/andres/Documents/T2015-Compiler/src/include

What does the -lcs50 command line argument do in clang?

Is it a combination of the -l -c and -s arguments? That is my best guess, but why would that be the case if -s only runs the preprocess and compiler when -c does all that and assembles? And what is the 50 on the end for?
-l_libname_ is a switch to tell the compiler (the linker) to include the library named _libname_ in the link phase.
-lcs50 tells the linker to include the cs50 library.

Including static library and header Makefile questions (C)

My file stacking is as follows
dir1/
mylib.a
myheader.h
file.c
executable
dir2/
dependentfile.c // depends on functions in myheader.h implemented in mylib.a
I would like to link my static library file in my Makefile WITHOUT using its name, but just indicating its path. What I have is as follows:
Makefile for dir2/
CC = gcc
CFLAGS = -g -Wall $(INCLUDES)
INCLUDES = -I../dir1
LDFLAGS = -g -L../dir1
exec: dependentfile.o
dependentfile.o: dependentfile.c
Running 'make' just gives me a bunch of implicit declaration errors, and undefined references because it's not looking in the paths I have specified with -L and -I. My dependentfile.c also has the line
#include "myheader.h"
which it can't find.
How should I modify the makefile in order to make this work? I have tried multiple things, even specifying the lib file with -l and writing the complete path to no avail.
Any help is appreciated!
#
EDIT: Figured it out!
Turns out I was forgetting LDLIBS. So for everyone else, the makefile ended up looking like:
CC = gcc
CFLAGS = -g -Wall $(INCLUDES)
INCLUDES = -I../dir1
LDFLAGS = -g -L../dir1
LDLIBS = -lmylib (my actual file was named libmylib.a, forgo the "lib")
exec: dependentfile.o
dependentfile.o: dependentfile.c
I think you should use
#include "myheader.h"
Your header file name should be quoted.

How do you set the order of libraries in automake?

How do you set the order of libraries in automake?
In my am file I have something like:
myprog_DEPENDENCIES = adhoc-target
myprog_SOURCES = myprog.c
myprog_LDADD = libmine.la
myprog_LDFLAGS = -static -L/home/user/lib -ladhoc
Now, when I compile I get this compile line similar too:
gcc -static myprog-myprog.o -o myprog -L/home/user/lib -ladhoc ./.libs/libmine.a
The problem is that libmine.a depends on libadhoc.a, therefore the compile line should be:
gcc -static myprog-myprog.o -o myprog ./.libs/libmine.a -L/home/user/lib -ladhoc
How do you set the order of libraries in automake? (Or maybe a work around; how do you repeat all the libraries in the compile line. That's what I do in my custom Makefiles.)
From the Automake manual (mostly §8.1.2 but also §8.4):
PROG_LDADD is inappropriate for
passing program-specific linker flags
(except for -l, -L, -dlopen and
-dlpreopen). So, use the
PROG_LDFLAGS variable for this
purpose.
That implies you can (but actually you should) use -l and -L in LDADD, not in LDFLAGS. In other words your Makefile.am should simply read
myprog_DEPENDENCIES = adhoc-target
myprog_SOURCES = myprog.c
myprog_LDADD = libmine.la -L/home/user/lib -ladhoc
myprog_LDFLAGS = -static
One idea from the automake book (http://sources.redhat.com/autobook/autobook/autobook_92.html): create a convenience library out of libmine and libadhoc, and link myprog against that.

Resources