I am writing a project in C using GCC 4.8 and I would like to see all the warnings (hoping to eliminate them) but the problem is I am #including some old, not maintained library which gives me huge wall of warnings in reaction to -Wall option. There is no way I fix those and I just want to ignore it focusing on code I actually write/maintain.
So can I:
gcc -Wall-excluding-OldBlackBox.c -myproject.c ?
Update your makefile so that you have a different gcc -Wxxx line for different files (or groups of files)
result.exe : xxx.o yyy.o
gcc -o result.exe xxx.o yyy.o
xxx.o : xxx.c
gcc -Wall xxx.c
yyy.o : yyy.c
gcc -W yyy.c
first create individual object files and then link them as single Executable.
//compilation with warnings and compilation without warnings
gcc -Wall file1.c file2.c -o foo.o && gcc -w file3.c file4.c -o foo1.o
gcc -o final foo.o foo1.o
Related
consider c.c a code that includes a.h and b.h, and main.c a code that includes c.h
i tried to compile it like so
gcc --std=c99 -o a.o -c a.c
gcc --std=c99 -o b.o -c b.c
gcc --std=c99 -o c.o -c c.c a.o b.o
but when I run the last one, gcc yells at me
gcc --std=c99 -o c.o -c c.c a.o b.o
gcc: warning: a.o: linker input file unused because linking not done
gcc: warning: b.o: linker input file unused because linking not done
and then when I try to compile the main.c file using gcc -o main main.c c.o it says that there are a lot of undefined references, which is predictable once the c file was not correctly compiled.
I've seen some similar questions here at stackoverflow, but I couldn't get it to work neither way.
I'm on Arch Linux running gcc v4.9.2-3
First, it is -std=c99 with a single dash.
I guess you are on Linux.
Then, you always should pass -Wall -Wextra -g (especially since you are a newbie) to gcc : -Wall ask for nearly all warnings, -Wextra for even more warnings, -g ask for debug information.
At last, you want to produce an executable myprog (don't name executables as c.o, this is supposed to be an object file) with
gcc -std=c99 -Wall -Wextra -g -o myprog c.c a.o b.o
You need to remove any -c since you want the linking to happen.
If you really mean -but that is very unusual today, better make shared libraries!- to agglomerate several object files into one all.o (to be linked later with other objects) you might try the -r linker option
gcc -std=c99 -Wall -Wextra -g -r c.c a.o b.o -o all.o
But last time I tried it was in the previous century, so details could be wrong.
There are very few reasons to agglomerate objects using the -r linker option. Unless you really know what you are doing, you are very probably wrong (in trying -r).
Perhaps you want to make a software library. These days it is much better to make a shared library. A shared library (technically an ELF shared object) should contain position independent code. So, assuming you have three translation units t1.c, t2.c, t3.c you first compile them as PIC :
gcc -std=c99 -Wall -Wextra -g -fPIC t1.c -c -o t1.pic.o
gcc -std=c99 -Wall -Wextra -g -fPIC t2.c -c -o t2.pic.o
gcc -std=c99 -Wall -Wextra -g -fPIC t3.c -c -o t3.pic.o
then you link all these PIC object files into a shared library libmyt.so
gcc -std=c99 -Wall -Wextra -g -shared \
t1.pic.o t2.pic.o t3.pic.o \
-o libmyt.so
Later you'll use this shared library e.g. as
gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . libmyt.so
or as
gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . -L. -lmyt
You might consider static linking with ar to make a static library libmyt.a but I don't recommend that.
Of course, you'll debug your program using gdb ./myprog and you could try running it with ./myprog. To use valgrind, try valgrind ./myprog
If you have several translation units, better learn how to use GNU make. Read the Program Library HowTo and this and these hints.
So given three files:
main.h
#include <stdio.h>
void printFunc(*char);
main.c
#include "main.h"
int main(){
printFunc("Hello World\n");
return 0;
}
printFunc.c
#include "main.h"
void printFunc(char *string){
printf("%s", string);
return;
}
You can compile using gcc on a linux machine as follows:
gcc -g -Wall -c file1.c //compile but do not link file
gcc -g -Wall -c file2.c //same
gcc file1.o file2.o -o main //executable "main"
or
gcc -g -Wall file1.c file2.c -o main
But I am concerned with how the header file gets included. I came across this when I was working on creating a "makefile" when I noticed that some tutorials will do something like this:
main : main.o printFunc.o
gcc -o main main.o printFunc.o
main.o : main.c
gcc -g -Wall -c -o main.o main.c
printFunc.o : printFunc.c
gcc -g -Wall -c -o printFunc.o printFunc.c
and others will include the header file as a dependent with:
main : main.o printFunc.o //main.h EDIT
//commands
main.o : printFunc.o main.h
//commands
Finally:
So, is it necessary to include the header file as a dependent to the executable? When does the include file get placed within the sources?
And also one could use this command:
executableName : dependencies.o //and a header file?
gcc -g -Wall -o executableSource.c
Which could be done with the line:
gcc -g -Wall -o executableName executableSource.c
Will the second command be run but the first is shorthand notation?
And finally, I thought the "-o" command was "send output to", if you will. If that way, it seems intuitive to run the command like:
gcc compileThisFile andSendOutputTo thisExecutableFile
gcc someSource.c -o executableFile
But with the notation listed above its more like:
gcc sendOutputTo thisExecutableFile fromThisSource
Is that correct?
main : main.o printFun.o main.h is definitely wrong. That's saying that the header is a prerequisite for linking. A header is a prerequisite for compilation.
Assuming what you really meant was to specify the header as a compilation dependency (e.g. printFunc.o : printFunc.c printFunc.h), this means that if the header changes, the object file will be automatically regenerated. If you don't, then it won't.
A dependency in Makefile is saying that whenever any of the listed files change, run the command again. It does not mean that the listed file will be included into the compilation or linking. You still need the regular #include "main.h" in your sources.
Thus, this works too:
printFunc.o : printFunc.c someReadmeFile.txt
gcc -g -Wall -c -o printFunc.o printFunc.c
Whenever printFunc.c or someReadmeFile.txt is updated, gcc -g -Wall .... will be executed again.
I hope it's clearer now.
My final executable (this is in unix though) will be proj07.
proj07: /user/cse320/Projects/project07.driver.o proj07.support.o
gcc -Wall /user/cse320/Projects/project07.driver.o proj07.support.o
proj07.support.o: proj07.support.c
gcc -c proj07.support.c
This creates proj07.support.o but no proj07 exists after compilation. I don't get an error so my mistake must be simple but I can't seem to figure it out.
Here's the output:
gcc -c proj07.support.c
gcc -Wall /user/cse320/Projects/project07.driver.o proj07.support.o
Also I am to use a static driver to test my file which is why the path is like that
You probably do have an a.out executable. Add -o $# to your first gcc occurrence and you should be fine.
I'm new to makefiles, so I apologize in advance if this is a silly question. Also I removed most variables from my makefile because they weren't working properly (gnu make tells me that $(myvar) should be completely replaces by the value of myvar, however the output of make was showing me that this was not happening), so I apologize for the ugliness and the more than 80 character lines.
acolibobj = acoLibInit acoGlobalDefs
acolibinterface: $(acolibobj).o
acoLibInit.o:
gcc -fPIC -g -c -Wall -I/usr/include/dc1394 -o acoLibinit.o acoCommands/acoLibInterface/acoLibInit.c
acoGlobalDefs.o:
gcc -fPIC -g -c -Wall -I/usr/include/dc1394 -o acoGlobalDefs.o acoCommands/acoLibInterface/acoGlobalDefs.c
When I run this makefile I get:
gcc -fPIC -g -c -Wall -I/usr/include/dc1394 -o acoLibinit.o acoCommands/acoLibInterface/acoLibInit.c
cc acoLibInit.o -o acoLibInit
gcc: acoLibInit.o: No such file or directory
gcc: no input files
make: *** [acoLibInit] Error 1
So far as I can tell, what's happening is that make is trying to compile AND link, even though I explicitly added the -c flag. When I run "gcc -fPIC -g -c..." myself (from bash), I do not get any problems at all. Why does make go on to try "cc acoLibInit.o -o acolibInit"?
make is trying to build acoLibInit. It probably has built-in rule that specifies "whatever" can be produced by linking "whatever.o", which is why you get that cc line.
This line:
acolibinterface: $(acolibobj).o
expands to:
acolibinterface: acoLibInit acoGlobalDefs.o
(note the absence of .o on the first dependency). This is why it's trying to link acoLibInit.
Try this:
acolibinterface: $(addsuffix .o,$(acolibobj))
if you want only the .o files as dependencies for that target.
$(acolibobj).o expands to acoLibInit acoGlobalDefs.o. Thus, you're really saying:
acolibinterface: acoLibInit acoGlobalDefs.o
Simply define acolibobj = acoLibInit.o acoGlobalDefs.o and use acolibinterface: $(acolibobj).
I have one directory and underneath it 4 subdirectories like so:
myDir:
myDir/Part1
myDir/Part2
myDir/Part3
myDir/shared
I want to make an executable that takes files from shared, links it to files in Part2 and puts the executable in myDir.
This is what I tried (only the lines in the makefile that are relevant):
Shared/helper.o:
gcc -ansi -pedantic-errors -c -Wall -Werror -g -o Shared/helper.o Shared/helper.c
and above it in the makefile:
Part2/part2code.o: ../Shared/helper.o
gcc -ansi -pedantic-errors -c -Wall -Werror -g -o Part2/part2code.o Part2/part2code.c
and above it in the makefile:
part2code: Part2/part2code.o ../Shared/helper.o
gcc -ansi -pedantic-errors -Wall -Werror -g -lm -o part2code Part2/part2code.o ../Shared/helper.o
(I also tried without the ../ before Shared)
I get this error:
No such file or directory.
help?
Thanks!
In this context, paths in filenames are all relative to where the makefile is. So e.g. Part2/part2code.o: ../Shared/helper.o is incorrect; it should simply be Part2/part2code.o: Shared/helper.o (and so on). Note also that you've written Shared in your makefile, but you've listed your directory as shared...
Although actually, that's still wrong. Rules such as a: b express that b is a prerequisite of a; i.e. that you cannot make a until you've made b. That is not the case for your object files; they don't depend on each other. Usually, an object file depends purely on its constituent source files (*.c and *.h). So, for example, your rule for part2code.o might be something like:
Part2/part2code.o: Part2/part2code.c
gcc -ansi -pedantic-errors -c -Wall -Werror -g -o $# $^
(Note the use of the special variables $# and $^, which substitute in for the target and the prerequisites, respectively.)