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
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.
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
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.
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?
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.