Getting a simple Makefile to work - c

So I'm having trouble getting even a simple Makefile to work. Heres what I have:
proj : driver.o
icc -g -O3 -openmp driver.o -o proj
driver.o : driver.c driver.h
icc -g -O3 -openmp driver.c
I feel like it's pretty straight forward. Proj only depends on driver.o which in turn depends on driver.c and driver.h. When run, the compiler fails with 'could not open source file "driver.h" ' at the include within the driver.c file. What am I missing?

You should give icc a -I. option to get it to look for include files in the current directory.
icc -I. -c -g -O3 -openmp driver.c
(I took the liberty of also adding the -c flag to prevent linking.)

Assuming you run make from the directory where all source files and headers reside, make sure you use quotes in your include directive:
#include "driver.h"
...rather than:
#include <driver.h>
The latter will search the system include path (and you will have to add the current directory to that path as larsmans suggested).

Is it in the correct folder? also the way you're compiling you might have to add -c to the command line to compile driver.o instead of trying to create a complete exectuable (only used to gcc so this might not be required).
Other than that (and the possible addition of the -I flag larsmans mentioned I can't see any other issue.

Related

C Link External Library in Makefile

I am having issues linking a library (termbox) when compiling. I get the error:
make: *** No rule to make target `termbox.h', needed by `test.o'. Stop.
Makefile:
edit: test.o
gcc -Wall -o edit test.o
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src
Include:
#include "termbox/src/termbox.h"
I have also tried using the compiled library but ran into similar issues. Do I have to use some sort of combination of specifying the header file and the location of the compiled library?
The directory of my termbox folder is in the same directory as test.c.
Thanks!
You have managed to compile and include the header file for the library, but you did not yet tell the compiler where the code (definitions) are - i.e. you did not tell it to link in the library yet.
You will need to do that next, this is done in a similar way to telling the linker what files to link, but with some extra syntax. It appears to be a static library (.a suffix) so you can link like this:
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -Itermbox/src -Lsrc -ltermbox
Where -L... specifies where libraries can be found and -l... specifies the library name to link to minus the lib prefix and the .a or .so suffix. Also note that order is important, so leave the library linkage at the end.
More on library linking order here
UPDATE
Sorry I added the linking to the wrong line! - here is the updated answer:
# The linker stage
edit: test.o
gcc -Wall -o edit test.o -Lsrc -ltermbox
# Compile stage
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src

Using a static library in C

I found a useful library on github for my project, after building this later I tried to use some predefined function on it. I couldn't compile my project because there is some header file missing like this one :
In file included from main.c:2:0:
ptask.h:11:19: fatal error: ptime.h: No such file or directory
I compiled my project using this command :
gcc main.c -L. -lptask
This is all the files in project folder :
libptask.a main.c ptask.h
This is the library content:
$ ar -t libptask.a
pbarrier.c.o
pmutex.c.o
ptask.c.o
ptime.c.o
rtmode.c.o
tstat.c.o
libdl.c.o
dle_timer.c.o
calibrate.c.o
Do I need to add all the headers of this files or just link the lib when compiling ?
Your main.c #include-s ptask.h which in turn #include-s ptime.h. Having compiled static libs alone is not enough (that's the linker's job), you still need to have all used header files (which is the compiler's job), both the ones you use and their dependencies, recursively applicable.
Normally you need to be sure that the header files are in your "include path", something that a lot of compilers define with -I as a command-line option. You'll need to include the source directory of that library, or if it has a make install option, then the place where they got installed.
regarding:
gcc main.c -L. -lptask
this is performing the compile step and the link step in one command.
It is also not enabling the warnings, which should always be enabled during the compile step.
Suggest something similar to the following to compile
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -g -c main.c -o main.o -I.
and when you have fixed all the warnings, then use something similar to the following to link
gcc main.o -o main -L. -lptask

Including headers file using GCC

Sorry. I think this question would be very easy to you guys.
I have two c files and one h file, I put those two .c files stack.c and main.c and one .h file stack.h inside a folder named "test" at Desktop.
So they are in C:\Users\user\Desktop\test
However when i try to test this code by writing
gcc -c stack.c sq_main.c -l stack.h
It continuously shows "unkown type name ..."
I think the header file is not included into those two .c files.
Actually I wrote the code
#include "stack.h"
Inside stack.c and main.c
Can anyone tell me how to include header file properly?
You are using GCC wrongly. I guess you are on Linux (or on something emulating it like MinGW ...)
If you insist on giving several commands in a terminal, you'll need to run
gcc -Wall -Wextra -g -c stack.c
gcc -Wall -Wextra -g -c sq_main.c
these two commands are building object files stack.o & sq_main.o (from stack.c & the #include-d stack.h, and sq_main.c & the #include-d stack.h, respectively). The options -Wall -Wextra are asking for all warnings and some extra warnings. The -g option asks for debugging information. The -c option asks for compiling only. Assuming that they are enough for your program, you need to link these object files to make an executable:
gcc -g stack.o sq_main.o -o myprogram
You might need to add -Iinclude-directory options to the compiling commands (the first two), and you might need to add -Llibrary-directory and -llibrary-name to the linking command. Order of arguments to gcc matters a lot. You could also add -H to ask the compiler to show which files are included. And GCC has a lot of other options. Read the Invoking GCC chapter of its documentation.
The .o suffix might be .obj on most Windows systems. You might also need myprogram.exe instead of myprogram. I never used Windows so I cannot help more.
In practice, you should use GNU make and write some Makefile; this answer might inspire you.

Error compiling C code using MinGW-w64 in Windows 7

I'm trying to compile code from a backtrace project https://code.google.com/p/backtrace-mingw/ which is written for MinGW, but using MinGW-w64.
My old install and fresh install of MinGW-w64 produce the same problem. Path is set in path variables, and also in command prompt:
C:\mingw-w64\i686-4.9.2-win32-sjlj-rt_v3-rev1\mingw32\bin
and C:\mingw-w64\i686-4.9.2-win32-sjlj-rt_v3-rev1\mingw32 although this one isn't needed.
This is the makefile of that project:
.PHONY: all clean
all : backtrace.dll test.exe
backtrace.dll : backtrace.c
gcc -O2 -shared -Wall -o $# $^ -lbfd -lintl -liberty -limagehlp
test.exe : test.c
gcc -g -Wall -o $# $^
clean :
-del -f backtrace.dll test.exe
When compiling I get the warning:
backtrace.c:23:17: fatal error: bfd.h: No such file or directory #include < bfd.h>`
Which is weird because that file exists in ../mingw32/include folder.
If I add this when compilind the dll: -IC:\mingw-w64\i686-4.9.2-win32-sjlj-rt_v3-rev1\mingw32\include it continues but stops at the directive: #error config.h must be included before this header and config.h is missing in MinGW-w64
Any ideas?
That path is definetely missing from gcc include paths in mingw. I don't know why. You have to add it yourself in any way you like: cmake recipe, autoconf recipe, CFLAGS, CPATH, gcc specs.
And, as far as I remember, it uses only HAVE_STRINGIZE macro from config.h and it is used only to define CONCAT4 macro, that's not used anywhere in bfd.h. So, it's safe to cheat a little and put
#define PACKAGE package
before including bfd.h
add this to the end of the compile statement:
-I./mingw32/include
so the whole compile statement would be:
gcc -g -Wall -o $# $^ -I./mingw32/include
so the compiler knows where to find the include files

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.

Resources