C compilation errors: undeclared (first use in this function) - c

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.

Related

Getting errors when compiling code using makefile. Works using console

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.

How does gcc handle local included files?

This really shouldn't be something I have to ask, but somehow I can find absolutely nothing by searching to answer my question.
In order to ask another question, I made three files: main.c, sub.c and sub.h. main.c has the 'main' function, while sub.c contains only function definitions.
Initially, main.c had '#include "sub.h"' as its only include statement.
Trying 'gcc main.c -O3 -o test' resulted in an error, saying that the function f() (declared in sub.h, defined in sub.c, and referenced in main.c) was unreferenced.
Trying 'gcc main.c sub.c -O3 -o test' resulted in expected behaviour.
I then modified test.c, removing the #include and references to f. 'gcc main.c -O3 -o test2' worked as expected.
I then re-added the references to f, and forgot to re-add the #include. Despite this, 'gcc main.c sub.c -O3 -o test3' worked as expected.
I noticed the mistake, and re-added the include intentionally as '#include sub.c'. 'gcc main.c sub.c -O3 -o test4' resulted in an error, saying f() was defined multiple times. 'gcc main.c -O3 -o test4 returned to working as expected.
The only conclusion I can draw from this is that as far as local files are concerned, if the file is a source code file then include it and don't add it to the command, else add its source to the command and don't bother including it, because apparently it doesn't matter whether you include it or not. I guess?
Basically my question is, is the behaviour above intended, and if so is it documented, and where, so I can read it and make better informed decisions about how to handle my included files in the future.
I then re-added the references to f, and forgot to re-add the #include. Despite this, 'gcc main.c sub.c -O3 -o test3' worked as expected.
For suitably loose definitions of "worked"; I'm going to bet that f() returns an int, and that gcc was defaulting to C89 mode.
Prior to C99, if the compiler encountered a function call before it saw a function definition or declaration, it assumed that the called function returned an int. Thus, as long as f() actually returns an int, your code will compile and run successfully. If f() doesn't return an int the code will still compile, but you will have a runtime problem. All the linker cares about is that the symbol is there; it doesn't care about type mismatches.
C99 did away with implicit int typing, so under a C99 compiler your code would fail to compile if you didn't have a declaration for f() in scope (either by including sub.h or adding the declaration manually).
The only conclusion I can draw from this is that as far as local files are concerned, if the file is a source code file then include it and don't add it to the command, else add its source to the command and don't bother including it, because apparently it doesn't matter whether you include it or not. I guess?
That is the exact wrong conclusion to draw. You do not want to include a .c file within another .c file as a regular practice, as it can lead to all kinds of mayhem. Everything in main.c is visible to sub.c and vice versa, leading to potential namespace collisions - for example, both files could define a "local" helper function named foo(). Normally such "local" functions aren't visible outside of the source file, but by including one source file within the other, both versions of foo() are visible and clash with each other. Another problem is that if a .c file includes another .c file which includes another .c file, etc., you may wind up with a translation unit that's too large for the compiler to handle. You will wind up recompiling both files every time you change one or the other where it isn't necessary. It's just bad practice all the way around.
The right thing to do is compile main.c and sub.c separately and make sure sub.h is included in both (you want to include sub.h in sub.c to make sure your declarations line up with your definitions; if they don't, the compiler will yak while translating sub.c).
Edit
Answering the following question in the comments:
When you say to compile main.c and sub.c separately, I'm assuming you mean to make object files out of them each individually and then link them (3 commands total)? Is there any way to do that with a single command?
The command gcc -o test main.c sub.c does the same thing, it just doesn't save the respective object files to disk. You could also create a simple Makefile, like so:
CC=gcc
CFLAGS=-O3 -std=c99 -pedantic -Wall -Werror
SRCS=main.c sub.c
OBJS=$(SRCS:.c=.o)
test: $(OBJS)
$(CC) -o $# $(CFLAGS) $(OBJS)
clean:
rm -rf test $(OBJS)
Then all you need to do is type make test:
[fbgo448#n9dvap997]~/prototypes/simplemake: make test
gcc -O3 -std=c99 -pedantic -Wall -Werror -c -o main.o main.c
gcc -O3 -std=c99 -pedantic -Wall -Werror -c -o sub.o sub.c
gcc -o test -O3 -std=c99 -pedantic -Wall -Werror main.o sub.o
There are implicit rules for building object files from .c files, so you don't need to include those rules in your Makefile. All you need to do is specify targets and prerequisites.
You may need to drop the -pedantic flag to use some platform-specific utilities, and you may need to specify a different standard (c89, gnu89, etc.) as well. You will definitely want to keep the -Wall -Werror flags, though - they'll enable all warnings and treat all warnings as errors; they'll force you to deal with warnings.
If you compile a program then the main function should be there. If you compile a program without main, then you can only generate object files. In your case, it looks like main.c contains main() and sub.c contains some function definitions. Other important thing is when you define a header file, ensure you have preprocessor directive to prevent including the header file multiple times.
An example is here:
http://www.tutorialspoint.com/cprogramming/c_header_files.htm

How to create makefile for program using curses.h

I am struggling with making a makefile for the sample code below using curses.h.
#include <stdio.h>
#include <stdlib.h>
#include<curses.h>
int main(){
WINDOW *initscr(void);
initscr();
int endwin(void);
return 0;
}
I included library and header in Netbeans, but when I try to build with makefile:
CC=C:\TDM-GCC-64\bin\gcc
CFLAGS=-std=gnu99 -Werror -Wall -lm -lncurses
DEPS=curses.h
OUTPUT=main
all:
echo "Building all"
$(CC) $(CFLAGS) render.c -o $(OUTPUT)
it gives me :
echo "Building all"
Building all
C:\TDM-GCC-64\bin\gcc -std=gnu99 -Werror -Wall -lm -lncurses render.c -o main
render.c:3:19: fatal error: curses.h: No such file or directory
#include<curses.h>
^
compilation terminated.
make.exe": *** [all] Error 1
BUILD FAILED (exit value 2, total time: 150ms)
Just add -I. -L. to your CFLAGS macro, this adds the project library to the search paths of both the preprocessor and linket. This should work provided you have curses header and library files in your project folder. If the header or library files are in different folders just modify -I or -L flags accordingly.
Your last comment suggested that the preprocessing and compilation went fine but the linker could not locate the library file.
As a general note, it would be a good idea to put compiler flags to CFLAGS and linker flags to a different macro, say LDFLAGS.
Macro DEPS should also be used to enable incremental compilation. It is usually used as a dependency to the compilation rule but since you don't have it separately you could put it besides all such as this:
all : $(DEPS)
Here is what I did, it works, but it still returns 8 errors.
Solution to fix 1 of the 8 errors is listed further down.
I cd to the location of thadgavin.c
( for me it is "pset1/source")
For ubuntu (I used 16.04)
$ cc thadgavin.c -lm -lncurses
$ ./a.out
You can rename a.out to thadgavin (same as "make" would have done if it would have worked).
$ mv a.out thadgavin
There you go, hope this helps resolve the last of the errors.
Note:
There is an easy error fix in main(), you need to specify it as an int first. I believe it is on line 61?
Eg;
"int main()" shows only as "main()" due to "int" being up at the top with the abstracted layout syntax I do not believe it knows it has been called as an int. I may be wrong, hopefully someone else can shed light to this problem.
https://youtu.be/oOUgU0z4qeY
If you solve any of the rest of the errors, please post to my video or email Python253#gmail.com for others to benefit from your solution.
Thank you,
My name is Daniel Paul Evans
.... And this is CS50!

What is wrong with my header files?

I've just completed a school assignment and I'm having a problem testing my code because I keep getting the following output after running make packetize (it's a makefile the professor gave us)
cc packetize.c -o packetize
/tmp/ccJJyqF6.o: In function `block_to_packet':
packetize.c:(.text+0xb1): undefined reference to `crc_message'
collect2: ld returned 1 exit status
make: *** [packetize] Error 1
block_to_packet is defined in a file called packetize.c, crc_message is defined in crc16.c (both of which contain an #include "data.h" line). data.h also has the function heading for crc_message in it All of these files are in the same directory. I've been trying to compile them for the past hour and a half and have searched Google endlessly with no avail. It has something to do with linking I've read, my instructor has not taught this and so I don't know how to compile these files to test their outputs. Can anyone let me know what's wrong?
Your header files are absolutely OK. What you have there is a linker error: The compilation of packetize.c ran without problems, but then you're trying to link an executable file packetize (since you did not give the -c option which states "compile to object file"). And the executable would need the compiled code from crc16.c as well.
Either you have to give all sources on the compiler line:
cc packetize.c crc16.c -o myApp
Or you have to compile into individual object files, eventually linked together:
cc -c packetize.c -o packetize.o
cc -c crc16.c -o crc16.o
cc packetize.o crc16.o -o myApp
The former is what you'd do in a one-shot command line, the latter is what a Makefile usually does. (Because you do not need to recompile crc16.c if all you did was modify packetize.c. In large projects, recompiles can take significant amounts of time.)
Edit:
Tutorial time. Take note of the existence / absence of -c options in the command lines given.
Consider:
// foo.c
int foo()
{
return 42;
}
A source file defining the function foo().
// foo.h
int foo();
A header file declaring the function foo().
// main.c
#include "foo.h"
int main()
{
return foo();
}
A source file referencing foo().
In the file main.c, the include makes the compiler aware that, eventually, somewhere, there will be a definition of the function foo() declared in foo.h. All the compiler needs to know at this point is that the function will exist, that it takes no arguments, and that it returns int. That is enough to compile the source to object code:
cc -c main.c -o main.o
However, it is not enough to actually compile an executable:
cc main.c -o testproc # fail of compile-source-to-exe
ld main.o -o testproc # fail of link-object-to-exe
The compiler was promised (by the declaration) that a definition of foo() will exist, and that was enough for the compiler.
The linker however (implicitly run by cc in the first example) needs that definition. The executable needs to execute the function foo(), but it is nowhere to be found in main.c. The reference to foo() cannot be resolved. "Unresolved reference error".
You need to either compile both source files in one go...
cc foo.c main.c -o testproc # compile-source-to-exe
...or compile foo.c as well and provide the linker with both object files so it can resolve all references:
cc -c foo.c -o foo.o
ld foo.o main.o -o testproc # link-objects-to-exe
Post Scriptum: Calling ld directly as pictured above most likely will not work just like that. Linking needs a couple of additional parameters, which cc adds implicitly -- the C runtime support, the standard C library, stuff like that. I did not give those parameters in the examples above as they would confuse the matter and are beyond the scope of the question.
You have to compile crc16.c as well and link these two object files to build the binary. Otherwise packetize.c, from where crc_message() is being called, has no knowledge of it.
Try using
cc packetize.c crc16.c -o packetize
Your call crc_message() from packetize.c would just be fine.
As Totland writes crc_message is defined in crc16.c; which means that packetize.c can't see the definition, no matter how many shared headers they have. You do not have a compile error but an error from the linker.
If you compile your c files first to object files and then link everything to an executable it will work.

How can I know in which step (Pre-Processor,Compiling, Linking) my program failed to compile?

How can I know in which step (Pre-Processor,Compiling, Linking) my program got compilation failure?
For example, I wrote a program of 3 source files: a.c ,b.c, c.c and all three of them included the header file, h.h, which contains all the prototypes of all the source files, but I also implemented one function, in the header file. I know it's wrong to do, but I wonder on what stage did the program crash, Is it the linking or the compiling, I got an error message, Is this say that the problem is at the linking stage? (otherwise I'll just get a red underline on the mistake from the compiler?)
Where can I read about linking and what I shouldn't do regarding headers and source files and linking errors?
(I work in Linux, with Eclipse)
You find the location of the error by separating compiling and linking. An error due to the precompiler is unusual and also found during compiling. This is how compiling works on the command line:
Compile step:
gcc -c -o a.o -pedantic -Wall a.c
gcc -c -o b.o -pedantic -Wall b.c
gcc -c -o c.o -pedantic -Wall c.c
link step:
gcc a.o b.o c.o -o prog
Of course you need to specify whatever other flags that are necessary (e.g. -l for linking to a library etc.)
Then read the errors and warnings (!) carefully and you shall find the problem.
Your program crashes only once you have pre-procesed, compiled and linked your program to generate an executable that you can run. A crash is a run-time error.
Re preprocessor/compilation/linking:
You didn't specify what platform/environment you are working in, but in a Linux/Unix environment it is easy to determine if you are getting problems with the linker as you usually get a message with ld.
Compilation errors usually syntax related and easy to identify that way (e.g., mismatched parens, missing semi-colons, etc) (Aside, as a general rule, I would recommend you always compile with the highest warning level, and then consciously determine which warning messages to ignore.)
I am not at a system were I can try it out, so I'm not sure of the pre-processor throws out specific easily identifiable error/warning messages, or if they just get passed on to the compiler and get spit out at that stage.
None of these steps crash your program, that only happens (if it does) after all these steps have been completed successfully.

Resources