# Errors compiling Module (Possible OS Bugs?)



## Israel (Dec 20, 2009)

Ok, I've done this in Linux many times but I decided to compile my first Unix module with FreeBSD-7.2  I might be wrong but it looks like the compiler is complaining about code in some of the kernel header files than my code?

Error:

```
# make
Warning: Object directory not changed from original /home/C-Dubs
cc -O2 -fno-strict-aliasing -pipe  -D_KERNEL -DKLD_MODULE -std=c99 -nostdinc   -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-
unit-growth=100 --param large-function-growth=1000 -fno-common  -mno-align-long-strings -mpreferred-stack-boundary=2  -mno-mmx -mno-3dnow 
-mno-sse -mno-sse2 -mno-sse3 -ffreestanding -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith 
-Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions -c hello.c
In file included from hello.c:1:
@/sys/module.h:67: error: expected specifier-qualifier-list before 'u_int'
In file included from @/sys/module.h:97,
                 from hello.c:1:
@/sys/linker_set.h:34:2: error: #error this file needs sys/cdefs.h as a prerequisite
@/sys/linker_set.h:52:2: error: #error this file needs to be ported to your compiler
hello.c:27:2: warning: no newline at end of file
*** Error code 1
```

My first clue was when I saw it complain about 'u_int' when my code never used it?

CODE:

```
#include <sys/module.h>
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>

static int 
load(struct module *module, int cmd, void *arg)
{
	int error = 0;

	switch(cmd){
	case MOD_LOAD:
		uprintf("Hello World!\n");
		break;

	case MOD_UNLOAD:
		uprintf("Good Bye Cruel World!\n");
		break;

	default:
		error = EOPNOTSUPP;
		break;

	return(error);
	}
}
```

Here is the makefile I'm using too:

```
KMOD = hello
SRCS = hello.c

.include <bsd.kmod.mk>
```


----------



## SirDice (Dec 20, 2009)

You're missing sys/types.h and sys/errno.h.

http://www.freebsd.org/doc/en_US.ISO8859-1/books/arch-handbook/driverbasics-kld.html


----------



## Israel (Dec 21, 2009)

I just tried that.  Same responce...


```
Warning: Object directory not changed from original /home/C-Dubs
cc -O2 -fno-strict-aliasing -pipe  -D_KERNEL -DKLD_MODULE -std=c99 -nostdinc   -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-
unit-growth=100 --param large-function-growth=1000 -fno-common  -mno-align-long-strings -mpreferred-stack-boundary=2  -mno-mmx -mno-3dnow 
-mno-sse -mno-sse2 -mno-sse3 -ffreestanding -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith 
-Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions -c hello.c
In file included from hello.c:1:
@/sys/module.h:67: error: expected specifier-qualifier-list before 'u_int'
In file included from @/sys/module.h:97,
                 from hello.c:1:
@/sys/linker_set.h:34:2: error: #error this file needs sys/cdefs.h as a prerequisite
@/sys/linker_set.h:52:2: error: #error this file needs to be ported to your compiler
hello.c:28:2: warning: no newline at end of file
*** Error code 1
```

Maybe I'm wrong but look at the output here /sys/linker_set.h:34:2... this file needs sys/cdefs.h.  I tried putting "#include <sys/cdefs.h>" in my code and in /usr/include/sys/linker_set but once again nothing changes.


----------



## Israel (Dec 21, 2009)

Ok, I just ran the skeleton file and saw that it ran fine.  Looking at it I noticed this part at the bottom of the file was different.


```
/* Declare this module to the rest of the kernel */

static moduledata_t skel_mod = {
  "skel",
  skel_loader,
  NULL
};  

DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);
```

I tried to reproduce this my hello.c file but I'm still getting the same error. Here is the new code:

```
// Declare to the rest of the kernel
static moduledata_t hello_mod = {
	"hello",
	hello_loader,
	NULL
	};

DECLARE_MODULE(hello, hello_mod, SI_SUB_KLD, SI_ORDER_ANY);
```

Can't figure out what I'm doing different now...


----------



## Israel (Dec 21, 2009)

Ok. Before anyone else throws this in I realized that in this:

```
// Declare to the rest of the kernel
static moduledata_t hello_mod = {
        "hello",
        hello_loader,
        NULL
        };

DECLARE_MODULE(hello, hello_mod, SI_SUB_KLD, SI_ORDER_ANY);
```

hello_loader should just be load, to match the name of my original function.  I changed it to load, same error...


----------



## PseudoCylon (Dec 21, 2009)

Order of include files matters. You need to include cdefs.h and param.h before module.h

```
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/module.h>
#include <sys/systm.h> 
#include <sys/errno.h>
#include <sys/kernel.h>
```
*Or*, if you include types.h instead of param.h, you don't need cdefs.h See about line 50 of this page (search the page with "cdefs")

```
#include <sys/type.h>
#include <sys/module.h>
#include <sys/systm.h> 
#include <sys/errno.h>
#include <sys/kernel.h>
```


----------



## Israel (Dec 21, 2009)

Wow... It works. I've never seen C care about the order of the includes files, just that they were there.  Is this something specific to FreeBSD or all platforms?


----------



## PseudoCylon (Dec 22, 2009)

You made your very first kld work, eh?

param.h and types.h are sorta special files. They defines bunch of stuff commonly used, like u_int. In C everything needs to be defined before use. So, before module.h uses u_int, it needs to be defined as a data type. types.h defines it, so types.h need to be included before module.h. (types.h is included in param.h)

Basically, putting one of those file at the top of list will make  compiler stop complaining.


----------



## Israel (Dec 22, 2009)

Yeah, I had done some LKM's(Linux) but that was my first KLD.  I knew includes need to be at the top of the file, or before use, like you said.  Just never saw GCC complain about the order of the includes at the top of the file before. 

Thanks for your help!


----------

