I am getting compilation errors when building my project with a makefile which I don't see when building using console.
I am using the prebuilt GNU toolchain for PowerPC.
Here is my makefile,
GCC_Assembler = powerpc-eabi-as
GCC_Compiler = powerpc-eabi-gcc
Directory_Application :=$(argument)/Source_Files
Directory_Bootloader :=$(argument)/Source_Files
Directory_RAMBootloader :=$(argument)/Source_Files
Application_Source_Files := $(wildcard $(Directory_Application)/*.C)
Application_Source_Files_Objecs=$(Application_Source_Files:.C=.O)
default: Build_Application
all: Build_Application
Build_Application: $(Application_Source_Files_Objecs)
$(Application_Source_Files_Objecs) : %.O: %.C
$(GCC_Compiler) -c $< -o $# -O1 -Wall -Wfatal-errors
It builds without errors when I try to build it using these commands.
CD %WORKSPACE%\Source Files
powerpc-eabi-gcc debug.c -c -odebug.o -O1 -Wall -Wfatal-errors
powerpc-eabi-gcc io.c -c -oio.o -O1 -Wall -Wfatal-errors
...
...
So, when building using makefile, I get an error for a function that is not declared correctly. See the image below
Error( Makefile )
/Debug.C: infunction 'void display_task_table()':
/Debug.C:627:18: error: 'task_wait' was not declared in this scope
task_wait(100*2);
I only get warning for the same function when compiling without makefile.
Warning( Console )
Debug.C: in function 'display_task_table':
Debug.c:627:3: warning: implicit declaration of function 'task_wait' [- Wimplicit-function-declaration]
task_wait(100*2);
I can fix the error by including the proper header file, but I would like to know why?
Please let me know if I need to include anything else
Well, you are using .C extension when compiling with the Makefile, so the compiler is interpreting the file as a C++ source file and in C++, not having a prototype is an error (and only a warning in C) Just rewrite the line
$(Application_Source_Files_Objecs) : %.O: %.C
to
$(Application_Source_Files_Objecs) : %.o: %.c
and try again (and don't use an Operating System that doesn't distinguish case of letters :) <--- this was a joke, don't flame, please)
EDIT
Please, do the same with all the lines that specify .C and .O files also to .c and .o instead. The operating system doesn't bother with the case of characters, but make(1) and gcc(1) do.
Related
When I say very simple I mean it. I have a main.c and a header file called input_error.h.
main.o : main.c input_error.h
gcc -c main.c
When I run the command "make" gcc -c main.c is executed but it's not updating any changes I make to my main.c file. When I manually type in "gcc main.c" it works fine.
EDIT: It seems like I need to add another rule but I'm not sure what that entails
At the moment your makefile only builds the .o file. You can build your binary in 2 ways. Note that make requires the indentation in the targets statements to be a tab and not 4 spaces, as it may have been converted to by the browser.
build .o separately then link binary. Note that using the -c switch causes gcc to build only the object file.
main: main.o
gcc main.o -o main
main.o : main.c input_error.h
gcc -c main.c -o main.o
build in one step
main: main.c input_error.h
gcc main.c -o main
You can also avoid repetition in your makefile by using special variables to denote the target ($#), the first dependency ($<) and all (#^) the dependencies.
e.g. one of the above lines could become
main.o : main.c input_error.h
gcc -c $< -o $#
Which seems a bit cryptic at first but you get used it. The implicit rules in #kaylums answer will also help to cut down on typing.
The Makefile you have only has a single rule to compile the .o file. That is, it does not have any rule to link the final executable.
make has implicit rules for building many common targets. So your Makefile could be as simple as the following:
all: main
main.o : input_error.h
For further explanation:
all: main: Since this is the first target it is the one that will be built by default if no explicit target is provided to the make command line. It depends on a single target main.
There is no explicit rule for main but make has an implicit rule which will build it from main.c.
main.o : input_error.h: Tells make that main.o needs to be rebuilt if input_error.h changes. There is no need to put main.c here as make has that implicit knowledge. There is also no need for an explicit command as make also has that implicit.
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
I'm probably forgetting something obvious that'll solve this. While there's other questions on SO with the same issue, none of the solutions have been applicable to my situation.
I have a main file, sim.c, a header file net.h, a header file friends.h, and a file with the functions, net.c. I have a makefile, which I created with gmakemake > Makefile, and its contents are very basic.
Header.mak (makefile template):
CFLAGS = -Wall -Wextra -pedantic -std=c99 -ggdb
LFLAGS = -ggdb
LDFLAGS =
Makefile relevant contents:
CPP_FILES =
C_FILES = net.c sim.c
PS_FILES =
S_FILES =
H_FILES = net.h friends.h
SOURCEFILES = $(H_FILES) $(CPP_FILES) $(C_FILES) $(S_FILES)
.PRECIOUS: $(SOURCEFILES)
OBJFILES =
#
# Main targets
#
all: net sim
net: net.o $(OBJFILES)
$(CC) $(CFLAGS) -o net net.o $(OBJFILES) $(CLIBFLAGS)
sim: sim.o $(OBJFILES)
$(CC) $(CFLAGS) -o sim sim.o $(OBJFILES) $(CLIBFLAGS)
#
# Dependencies
#
net.o: net.h
sim.o: net.h
My sim.c file contains:
#include "net.h"
#include "friends.h"
My header file contains the functions in net.c and defines them all as stubs. I copied and pasted them to create the function headers, so there shouldn't be any typos.
My net.c file contains:
#include "net.h"
Yet any time a function in sim.c tries to call a function in net.c, it errors on that line with:
"undefined reference to `function_name`".
How can I make sim.c able to access the functions in net.c?
The message undefined reference to 'function_name' implies that of all the object files you're giving to the linker, none of them has a definition for function_name. That means that either
You're not linking with net.o
net.c (as compiled) does not contain a definition for function_name -- by 'as compiled' I mean with all of the various preprocessor options you use on it.
Since you show neither your link command line nor the contents of net.c, we can't tell which is the problem.
edit
with your edit, we can see clearly that you have the first problem -- when you try to link sim, you do not include net.o on the link command line. Most commonly, you would link sim with a makefile entry like:
sim: sim.o net.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LDLIBS)
or more simply just:
sim: sim.o net.o
relying on the default make actions for linking object files
For the two functions "see" each other make sure that:
Both c/cpp files are included in the makefile
Both definition(c/cpp) and declaration (h) files contains the same definition of the function: name/params/return value
The function being called must not be static.
Make sure you don't declare (or include) the same type with different structure in the source files.
That should do, unless you are using a very old complier with even more evil things that can go wrong ;)
On the PI, I needed the i2c.so library using this git: https://github.com/silentbobbert/pi_sensors. When running makefile from this git to get the i2c.so, i received this error:
Here are the .c and the .h files:
https://github.com/silentbobbert/pi_sensors/tree/master/Info/LinuxInterface
For reference, here is the contents of makefile:
SHELL = /bin/sh
CC = gcc
FLAGS = -c -Wall -Werror -fpic
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG
TARGET = i2c.so
SOURCES = $(shell echo *.c)
HEADERS = $(shell echo *.h)
OBJECTS = $(SOURCES:.c=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all:
$(CC) $(FLAGS) $(RELEASEFLAGS) $(SOURCES)
$(CC) -shared -o $(TARGET) $(OBJECTS)
as others have said, this is C code not C#.
Anyhow, you have two errors (and they do not relate directly) to the makefile but rather your compilation environment and the code itself.
OK, so how to approach something like this. First notice the first line in your screen-capture, that is the command that is being executed that is generating the error messages, I'll reproduce it here for you;
gcc -c -Wall -Werror -fpic -O2-D NDEBUG i2c_get.c i2c_set.c i2cbusses.c i2cset.c util.c
With this command we are compiling (note the -c flag) a bunch of source files into a single object file, the presence of the `c' flag implies that no linking is performed here. This is relevant so we know where along the tool-chain we are, and the type of errors we can expect (typically either syntax errors or missing header files).
The first error;
i2cset.c: In function 'check_funcs'
i2cset.c:56:2 error: implicit declaration of function 'iotcl' [-Werror=implicit-function-declaration]
is kinda saying, "hey, I can see that ioctl is a function, but you haven't told me anything about it so I'm going to assume that its signature is int ioctl() — a function with an indeterminate (but fixed, not variadic) argument list that returns an int". Given that you are compiling on a Linux-based system, adding #include <sys/ioctl.h> to the top of the file should fix this error.
The second error;
i2cset.c:63:7: error: 'I2C_SMBUS_BYTE' undeclared (first use in this function)
is related to the first error; and it is kinda saying 'hey, you haven't told me anything about I2C_SMBUS_BYTE'. Again, the most common reason for seeing this error is a missing header file. Looking at the source files you've provided a link to, it seems that I2C_SMBUS_BYTE is defined in
the header file i2c-dev.h, which however appears to be included in i2cset.c by: #include <linux/i2c-dev.h>.
At this point I'd insure that your compiler (gcc) can find the header file. From the error messages you are getting, I'm guessing that it is not, but you should be seeing an error message from the compiler about not being able to find the file. Also, if the file is on your system check to see if has the appropriate contents as compared to the git site.
Finally, the remain errors that you are seeing should be fixed as well as they are all basically the same thing.
To clarify things, let's suppose I'm compiling a program (prg) with 3 files, main.c, person.h and person.c.
If I use a concise way of writing the makefile, like this (more specifically the two last lines):
prg : main.o person.o
gcc -Wall -o prg -c $^
main.o : person.h
person.o : person.h
Will the -Wall be applied to main.o and person.o automatically? Or that doesn't even matter?
I know that, as the file says, if person.o needs to be re-compiled, prg will need a re-build too. But, I don't know if specifying -Wall only in the main goal is enough to enable it the other targets so warnings are emitted as the others are compiled.
Maybe I'm missing something really important, or I'm saying something that makes no sense; but take it easy, I'm just a beginner :P
Since you apply the -Wall to the link phase (when collecting the object files into an executable), but the option applies to the compilation phase (converting the source files into object files), it provides no benefit where it is written.
You should modify the compilation by setting macros.
Normally, the rule for compiling an C source file to an object file looks something like:
${CC} ${CFLAGS} -c $*.c
There could be other bits in there, and the notation might use something other than $*.c to identify the source file - there are similar (roughly equivalent) methods for specifying that, but it is tangential to the point I'm making. The $(CC) notation is equivalent to ${CC} too.
So, to change the compiler, you specify 'CC=new_c_compiler' and to change to compilation options, you (cautiously) specify 'CFLAGS=-Wall'.
This can be done in the makefile, or on the command line. The command line overrides the makefile.
Hence:
CFLAGS = -Wall
prg : main.o person.o
${CC} ${CFLAGS} -o prg -c $^
main.o : person.h
person.o : person.h
Why cautiously? Because in more complex situations, there may be a complex definition of CFLAGS which build it up from a number of sources, and blithely setting CFLAGS = -Wall may lose your include paths, macro definitions, and all sorts. In your case, it looks like you can simply set it as shown.
If you use GNU Make, you can simply add -Wall to CFLAGS:
CFLAGS += -Wall
This does not necessarily work with all varieties of make.
Your link line may eventually need to collect some library-related options too.
No, the flags will not magically be applied to other targets.
Add a line like this to the top of your Makefile, above the rules:
CFLAGS=-Wall
Then try without the explicit line for prg.