You are not logged in.
I seem to have lost this knowlage (or maybe never had it)..
..But, before you hit me up with the "let me google that for you" link..
files structure:
./src/global.h --some global define etc
./src/main_proj.h --not actually used yet
./src/main_proj.c --the main() call that ties in all other utility functions
./src/lib/a.h --defs and struct typdefs
./src/lib/a.c --various utility functions
plus about 5 more .c&.h pairs in ./lib
main_proj.c
/*
* .include
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// ( ... )
#include <math.h>
#include "global.h"
#include "lib/a.h"
#include "lib/b.h"
//( ... )
/*
* .text
*/
int main( int argc, char *argv[] )
{
// ( .... )
the files in ./src/lib/ do not have any include statements. Previously though they did, such as:
./src/lib/a.c
#include "a.h"
// ( ... )
void some_code( void ){}
in either case I can compile the code just fine, /but/ when i try to build ( -o ) I get complaints from ld about undefined references to the function names (that exist in the various lib/*.c files, and are prototyped in their relative .h files.
---
Is my question clear, if so, what am I doing wrong?
compile with:
src$ gcc -Wall -c main_proj.c
build with:
src$ gcc lib/*.c main_proj.c -o main_proj
system complains a lot about things like uint32_t being unknown (ive included stdint.h in main_proj.c), #defines from global.h nor being seen in the later lib/*.c files..
Offline
What's in the header files a.h and b.h? Also, it would help your debugging if you reduced it to the bare minimum example, make that work, and then start bringing in other stuff. Eg, why do you have "#include <math.h>"? None of your example code requires it.
Offline
Try instead of #include "lib/a.h" to give the path with a leading ./, like #include "./lib/a.h". Do that for all the header files of yours you included. Did that work?
asus ux303la, core i5@1.6ghz, 8 gb ram, 500gb hdd, hd4400 gpu, crux x64 with openbox
Offline
Most likely, you need to build with the math lib.
$ gcc -Wall lib/*.c main_proj.c -lm -o main_proj
also, you don't need to do this
$ gcc -c main_proj.c
if you do the above.
Offline
Got it working by having each header refer to any other header that it needs data from.. but this seems very very unclean and I would have though that anything linked in at the top of my code would be visible to functions linked in afterwards.
global.h
#ifndef __GLOBAL_
#define __GLOBAL_
#define GLOBAL_DEF 8
#endif
main_proj.c
#include <stdio.h>
#include <stdint.h>
#include "global.h"
#include "lib/a.h"
int main( void )
{
int i = 6;
a_struct my_a_struct;
a_func( &my_a_struct, i );
printf( "struct: %d, i said: %d\n", my_a_struct.some_data, ( uint16_t )i );
printf( "struct global: %d\n", my_a_struct.global_data );
aa_func( &my_a_struct );
printf( "\nnew data: %d\n", my_a_struct.some_data );
return 0;
}
lib/a.h
#ifndef __A_HEADER_
#define __A_HEADER_
#include <stdint.h> //want to get rid of these two here
#include "../global.h" //and have them only in main_proj.c
typedef struct
{
uint16_t some_data;
int global_data;
}a_struct;
int a_func( a_struct *the_struct, uint16_t data );
void aa_func( a_struct *the_struct );
#endif
lib/a.c
#include "a.h" //i can accept this one being here, but again, its included in main_proj.c
int a_func( a_struct *the_struct, uint16_t data )
{
the_struct->some_data = data;
the_struct->global_data = GLOBAL_DEF;
return 0;
}
void aa_func( a_struct *the_struct )
{
the_struct->some_data++;
}
what am I missing in my understanding of the c linker/preprocessor et al
Last edited by GalacticArachnid (2011-12-08 13:14:15)
Offline
I compiled your code after making a few small changes. The problems are unrelated to having multiple source files.
One thing that may help you to understand what is happening is to keep in mind that, in C, the compiler just starts at the top of the file and reads down, line by line. So, with that in mind...
It tries to compile "a.c". The first thing "a.c" does is include "a.h". When it gets to "uint16_t" it gets confused because it's never seen it before, so you need to "#include <stdint.h>" near the top of "a.h".
Your use of pointers in "a_func()" is a little off. The "->" is used when you are using a pointer. Since "the_struct" is already a pointer, you don't need to use the "*" at the beginning of the line, so it'll look like this instead:
the_struct->some_data = ( uint16_t )data;
the_struct->global_data = GLOBAL_DEF;
Continuing down the file, "a.c" doesn't know what "GLOBAL_DEF" is, because it doesn't know about the "global.h" file. (it was never included in "a.h") You COULD include "../global.h", but it makes more sense (in a real library) to just move the declaration of "GLOBAL_DEF" into "a.h".
Lastly, you had some confusion in your use of structures (which you recently edited out). Which is understandable, because I think the way C defines structures is more confusing than pointers. Your edit works fine (obviously), but you also could have removed the "typedef" keyword to get rid of the warning when you were doing it the first way.
struct a_struct
{
uint16_t some_data;
int global_data;
};
You could also combine them and do it both ways:
typedef struct a_struct
{
uint16_t some_data;
int global_data;
} a_struct;
Offline
thank you for the reply drcouzelis, ive reached most of these conclusions myself just now (and the browser showed no replies so i edited again, to reduce spam posts/log entries)
yes, the main issue it seems is that i expected any files at the end to be able to see what the preprocessor/linker as already added at the start, instead of having a spider web of includes. Basically something like..
a.c needs to include b.h to use b_func
b.c needs to include a.h to use a_func
as an arbitrary example ofc
So, is there a clean workflow to use with multiple header files in projects? Especially if i need to use the same system libraries in a whole bunch of them :s
Offline
Just create a 3rd include file that has the stuff the other 2 need, and include that at the top of a & b.
Offline
So, is there a clean workflow to use with multiple header files in projects? Especially if i need to use the same system libraries in a whole bunch of them :s
The guidelines I follow are:
Put "#define" wrappers around header files. (like you did)
A header file only "#include"s things that are needed in itself, the header file.
A source file only "#include"s things that are needed in itself, the source file.
If there are recursive dependencies between two header files, then only redefine what's needed from the other file instead of using "#include". (this should be rare)
Other than that, it's pretty much just picking a nice directory structure for your files. I usually put the source code for my C programs all in one directory. If you are trying to split up your project into "libraries" while you are working on it, my advice is to NOT do that. Just make an application, and when you finish, if you want to, separate out the code that could become its own library.
Lastly, I recently decided that my separation of data structures was rather arbitrary and that it's better for me to write my C programs in one big file. As I get closer to completing the project, I slowly separate functions and their data structures into their own files. I understand that other programmers might think this is a bad idea, but it seems to work well for me.
Offline