Help - clashes between /usr/include and /usr/include/linux

Help - clashes between /usr/include and /usr/include/linux

Post by Liron Lightwoo » Fri, 09 Apr 1999 04:00:00



Here is a solution to the problem I posted in January.  The problem was that
I was getting errors when trying to compile some Mobile IP implementations
under Red Hat Lnux 5.2.  Errors were of the form that certain variables,
macros, etc. were defined twice, once in an include file under the
/usr/include/linux directory and once in an include file uner /usr/include.
An example was:

> file included from /usr/include/linux/if.h:23,
>                 from /usr/include/linux/route.h:23,
>                 from includes_mn.h:23,
>                 from mymnode.c:18:
>/usr/include/linux/socket.h:38: warning: `SCM_RIGHTS' redefined
>/usr/include/socketbits.h:222: warning: this is the location of the
previous
>definition
>/usr/include/linux/socket.h:41: warning: `SOCK_STREAM' redefined
>/usr/include/socketbits.h:40: warning: this is the location of the previous
>definition
>/usr/include/linux/socket.h:42: warning: `SOCK_DGRAM' redefined
>/usr/include/socketbits.h:43: warning: this is the location of the previous
>definition
>/usr/include/linux/socket.h:43: warning: `SOCK_RAW' redefined
>/usr/include/socketbits.h:45: warning: this is the location of the previous
>definition
>/usr/include/linux/socket.h:44: warning: `SOCK_RDM' redefined
>/usr/include/socketbits.h:47: warning: this is the location of the previous
>definition
>/usr/include/linux/socket.h:45: warning: `SOCK_SEQPACKET' redefined
>/usr/include/socketbits.h:50: warning: this is the location of the previous
>definition
>/usr/include/linux/socket.h:46: warning: `SOCK_PACKET' redefined

>Here is the solution:

In one sentence: you have to separate the kernel space files from user space
files, and add some user space #include files that are the equivalent of the
kernel space #include files, plus a few odds and ends.

In more detail:

1) There is a concept in Red Hat Linux 5.1 and above of user space and
kernel space.  I'll explain this concept as best I can later on, but in the
mean time, please realise that this is an important concept.

2) In your makefile, look for programs and object files compiled in user
space.

How do you tell?  Look in the command line.  Executables and object files
which are compiled for Kernel space have the following macro defined:
__KERNEL__.  This either appears in a file, e.g. #define __KERNEL__, or in
the command lines that call the compiler, e.g.. -D__KERNEL__.

Object files and executables compiled for kernel space are also likely to
have the following in their compile command

-I/usr/src/linux/include

The remaining executable and object files are compiled for user space.

Note that it is possible for the same .h file to be compiled in either
kernel space or user space, depending on which .c file #includes it, and
whether the compile command defines __KERNEL__ or not.

3) Start compiling user space source code into object files.

If you get any errors of the form that a particular macro or struct or
typedef etc. is defined twice, you will notice that one definition is in a
file whose name contains linux, e.g. linux/xxx.h, and the other is in a non
linux file, e.g. sys/xxx.h.

To fix the problem, do the following:

4) Open up the .c file and look for #include lines with a linux directory in
the name of the file, e.g.

#include <linux/if_arp.h>

There may be several of these in a block, and there may be more than one
place where they appear.

5) Put the following before each such line or block of such lines.

#ifdef __KERNEL__

and the following lines after each such block of #include lines:

#else
#endif

so that you might have a block that looks somehting like this:

#ifdef __KERNEL__
#include <linux/xxxx.h>
#include <linux/yyyy.h>
#else
#endif

6) Between each of the #else and #endif's that you've just created, add some
#include files that are the user space equivalent of the <linux/xxx.h>
#include lines between the #ifdef __KERNEL__ and #else pairs.

For example, if there is an '#include <linux/if_arp.h>',  add '#include
<net/if_arp.h> between #else and #endif.  If there is an '#include
<linux/if_ether.h>', add '#include <netinet/if_ether.h> etc.

So you might end up with:

#ifdef __KERNEL__
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#else
#include <net/if_arp.h>
#include <netinet/if_ether.h>
#endif

To find the equivalent user space #include file for, say <linux/if_arp.h> do
the following:

a) cd /usr/include

b) ls if_arp.h */if_arp.h

c) Ignore results like linux/if_arp.h, or anything in the asm or scsi
directory.  Everything else is a user space file.

Note: You may not always find a user space #include file that has the same
name as a kernel space #include file.  For example, there is no user space
equivalent to <linux/module.h>.  In this case, don't worry about it for now.
You may get by without one.  If you have problems later see step xxx below.

Note: Sometimes you may find two files, e.g. abc.h and sys/abc.h.  In this
case, try one and see what you get.

7) If you get compiler error messages saying that types such as "__u8",
"__u16" etc. are undefined, then add the following to any such .c file, near
the top of the file.

#ifndef __KERNEL__
#include <asm/types.h>
#endif

8) Repeat step 5 & 6 for .h files that contain lines like '#include
<linux/xxx.h>'.

9) Compile the user space C files into object files and then try and link
them into executables.

10) Eliminate compilation errors:

a) If you get an error that certain macros, types, structs, etc. are
undefined, this is probably because in step 5 and 6, you found some kernel
space #include files that didn't have an equivalent user space #include file
with the same name, and it matters.

In this case, you will have to look for a user space #include file with a
different name, that defines or declares the missing thing.  You'll have to
do a grep of /usr/include and /usr/include/* to find it.  Once again, ignore
results in /usr/include/linux, /usr/include/asm or /usr/include/scsi.

b) If you get messages saying that certain types, such as "__u8", "__u16",
etc. are not defined, follow step 7 above.

c) If you get error messages like:

x.c:123: warning: assignment makes pointer from integer without a cast

or something like it, it means that the compiler has seen a function  such
as malloc(), but does not know it's declaration, so it treats it as an
integer function.

To fix this problem, look for the #ifndef __KERNEL__ #include <asm/types.h>
#endif block as defined in step 7), and add the following line to that
block:

#include <stdlib.h>

d) If you still get error messages saying that macros, types, structs, etc.
are defined twice, look for the first #include file with this problem that's
not part of your source code, and that's not inside an #ifdef __KERNEL__ ...
#else ... #endif block.  You could try putting it between the #else and
#endif in an #ifdef __KERNEL__ ... #else ... #endif block.

11) Repeat step 10 until the file compiles.

12) Move onto the next user space .c file and repeat steps above

13) Try compiling some Kernel space .c files and see how you go.  You should
have no errors here.

A more detailed explanation

In Red Hat Linux 5.1 and 5.2 and other recent versions of Linux (but not
Slackware I believe) they use a new C library called GlibC version 6.0.
This library has the concept of two different spaces, a kernel space and a
user space. The idea of the different spaces is that you can have different
definitions for various constants in each of these spaces.  For example,
there is a type called size_t in UNIX which is used as a variable type in
manny operating system function calls. Under user space, size_t could be one
size (e.g. 4 bytes) whereas under kernel space, size_t could be another
(e.g. 8 bytes).

The idea is that programs written by users for normal usage would use user
space, whereas programs written to be used by the kernel, are written in
Kernel space.  As to programs which use both, I don't know, I'm not a Linux
expert.

The result is that there are differernt definitions for various types,
structs, etc. for user space and for kernel space, and there are two sets of
#include files.  The kernel space set is in /usr/src/linux/include, whereas
the user space files are in
/usr/include.

The following directories are also for kernel space files:

/usr/include/asm - which is a symbolic link to /usr/src/linux/include/asm
/usr/include/scsi - which is a symbolic link to /usr/src/linux/include
/usr/include/linux - which is a symbolic link to
/usr/src/linux/include/linux

When you compile a program in user space that also interacts with the kernel
in some way, and therefore includes <linux/*.h> files, problems resulting
from two different sets of definitions of macros, types, structs, etc.  may
arise.

The above solution has fixed the problem for me when it has cropped up.

Hope this helps.

Liron Lightwood

 
 
 

Help - clashes between /usr/include and /usr/include/linux

Post by TS Stah » Fri, 09 Apr 1999 04:00:00


Well thought out and crafted post which I have printed for future reference.  I
urge to push the 'problem' up the linux chain of command.

Liron Lightwood wrote:
> Here is a solution to the problem I posted in January.  The problem was that
> I was getting errors when trying to compile some Mobile IP implementations
> under Red Hat Lnux 5.2.  Errors were of the form that certain variables,
> macros, etc. were defined twice, once in an include file under the
> /usr/include/linux directory and once in an include file uner /usr/include.
> An example was:

> > file included from /usr/include/linux/if.h:23,
> >                 from /usr/include/linux/route.h:23,
> >                 from includes_mn.h:23,
> >                 from mymnode.c:18:
> >/usr/include/linux/socket.h:38: warning: `SCM_RIGHTS' redefined
> >/usr/include/socketbits.h:222: warning: this is the location of the
> previous
> >definition
> >/usr/include/linux/socket.h:41: warning: `SOCK_STREAM' redefined
> >/usr/include/socketbits.h:40: warning: this is the location of the previous
> >definition
> >/usr/include/linux/socket.h:42: warning: `SOCK_DGRAM' redefined
> >/usr/include/socketbits.h:43: warning: this is the location of the previous
> >definition
> >/usr/include/linux/socket.h:43: warning: `SOCK_RAW' redefined
> >/usr/include/socketbits.h:45: warning: this is the location of the previous
> >definition
> >/usr/include/linux/socket.h:44: warning: `SOCK_RDM' redefined
> >/usr/include/socketbits.h:47: warning: this is the location of the previous
> >definition
> >/usr/include/linux/socket.h:45: warning: `SOCK_SEQPACKET' redefined
> >/usr/include/socketbits.h:50: warning: this is the location of the previous
> >definition
> >/usr/include/linux/socket.h:46: warning: `SOCK_PACKET' redefined

> >Here is the solution:

> In one sentence: you have to separate the kernel space files from user space
> files, and add some user space #include files that are the equivalent of the
> kernel space #include files, plus a few odds and ends.

> In more detail:

> 1) There is a concept in Red Hat Linux 5.1 and above of user space and
> kernel space.  I'll explain this concept as best I can later on, but in the
> mean time, please realise that this is an important concept.

> 2) In your makefile, look for programs and object files compiled in user
> space.

> How do you tell?  Look in the command line.  Executables and object files
> which are compiled for Kernel space have the following macro defined:
> __KERNEL__.  This either appears in a file, e.g. #define __KERNEL__, or in
> the command lines that call the compiler, e.g.. -D__KERNEL__.

> Object files and executables compiled for kernel space are also likely to
> have the following in their compile command

> -I/usr/src/linux/include

> The remaining executable and object files are compiled for user space.

> Note that it is possible for the same .h file to be compiled in either
> kernel space or user space, depending on which .c file #includes it, and
> whether the compile command defines __KERNEL__ or not.

> 3) Start compiling user space source code into object files.

> If you get any errors of the form that a particular macro or struct or
> typedef etc. is defined twice, you will notice that one definition is in a
> file whose name contains linux, e.g. linux/xxx.h, and the other is in a non
> linux file, e.g. sys/xxx.h.

> To fix the problem, do the following:

> 4) Open up the .c file and look for #include lines with a linux directory in
> the name of the file, e.g.

> #include <linux/if_arp.h>

> There may be several of these in a block, and there may be more than one
> place where they appear.

> 5) Put the following before each such line or block of such lines.

> #ifdef __KERNEL__

> and the following lines after each such block of #include lines:

> #else
> #endif

> so that you might have a block that looks somehting like this:

> #ifdef __KERNEL__
> #include <linux/xxxx.h>
> #include <linux/yyyy.h>
> #else
> #endif

> 6) Between each of the #else and #endif's that you've just created, add some
> #include files that are the user space equivalent of the <linux/xxx.h>
> #include lines between the #ifdef __KERNEL__ and #else pairs.

> For example, if there is an '#include <linux/if_arp.h>',  add '#include
> <net/if_arp.h> between #else and #endif.  If there is an '#include
> <linux/if_ether.h>', add '#include <netinet/if_ether.h> etc.

> So you might end up with:

> #ifdef __KERNEL__
> #include <linux/if_arp.h>
> #include <linux/if_ether.h>
> #else
> #include <net/if_arp.h>
> #include <netinet/if_ether.h>
> #endif

> To find the equivalent user space #include file for, say <linux/if_arp.h> do
> the following:

> a) cd /usr/include

> b) ls if_arp.h */if_arp.h

> c) Ignore results like linux/if_arp.h, or anything in the asm or scsi
> directory.  Everything else is a user space file.

> Note: You may not always find a user space #include file that has the same
> name as a kernel space #include file.  For example, there is no user space
> equivalent to <linux/module.h>.  In this case, don't worry about it for now.
> You may get by without one.  If you have problems later see step xxx below.

> Note: Sometimes you may find two files, e.g. abc.h and sys/abc.h.  In this
> case, try one and see what you get.

> 7) If you get compiler error messages saying that types such as "__u8",
> "__u16" etc. are undefined, then add the following to any such .c file, near
> the top of the file.

> #ifndef __KERNEL__
> #include <asm/types.h>
> #endif

> 8) Repeat step 5 & 6 for .h files that contain lines like '#include
> <linux/xxx.h>'.

> 9) Compile the user space C files into object files and then try and link
> them into executables.

> 10) Eliminate compilation errors:

> a) If you get an error that certain macros, types, structs, etc. are
> undefined, this is probably because in step 5 and 6, you found some kernel
> space #include files that didn't have an equivalent user space #include file
> with the same name, and it matters.

> In this case, you will have to look for a user space #include file with a
> different name, that defines or declares the missing thing.  You'll have to
> do a grep of /usr/include and /usr/include/* to find it.  Once again, ignore
> results in /usr/include/linux, /usr/include/asm or /usr/include/scsi.

> b) If you get messages saying that certain types, such as "__u8", "__u16",
> etc. are not defined, follow step 7 above.

> c) If you get error messages like:

> x.c:123: warning: assignment makes pointer from integer without a cast

> or something like it, it means that the compiler has seen a function  such
> as malloc(), but does not know it's declaration, so it treats it as an
> integer function.

> To fix this problem, look for the #ifndef __KERNEL__ #include <asm/types.h>
> #endif block as defined in step 7), and add the following line to that
> block:

> #include <stdlib.h>

> d) If you still get error messages saying that macros, types, structs, etc.
> are defined twice, look for the first #include file with this problem that's
> not part of your source code, and that's not inside an #ifdef __KERNEL__ ...
> #else ... #endif block.  You could try putting it between the #else and
> #endif in an #ifdef __KERNEL__ ... #else ... #endif block.

> 11) Repeat step 10 until the file compiles.

> 12) Move onto the next user space .c file and repeat steps above

> 13) Try compiling some Kernel space .c files and see how you go.  You should
> have no errors here.

> A more detailed explanation

> In Red Hat Linux 5.1 and 5.2 and other recent versions of Linux (but not
> Slackware I believe) they use a new C library called GlibC version 6.0.
> This library has the concept of two different spaces, a kernel space and a
> user space. The idea of the different spaces is that you can have different
> definitions for various constants in each of these spaces.  For example,
> there is a type called size_t in UNIX which is used as a variable type in
> manny operating system function calls. Under user space, size_t could be one
> size (e.g. 4 bytes) whereas under kernel space, size_t could be another
> (e.g. 8 bytes).

> The idea is that programs written by users for normal usage would use user
> space, whereas programs written to be used by the kernel, are written in
> Kernel space.  As to programs which use both, I don't know, I'm not a Linux
> expert.

> The result is that there are differernt definitions for various types,
> structs, etc. for user space and for kernel space, and there are two sets of
> #include files.  The kernel space set is in /usr/src/linux/include, whereas
> the user space files are in
> /usr/include.

> The following directories are also for kernel space files:

> /usr/include/asm - which is a symbolic link to /usr/src/linux/include/asm
> /usr/include/scsi - which is a symbolic link to /usr/src/linux/include
> /usr/include/linux - which is a symbolic link to
> /usr/src/linux/include/linux

> When you compile a program in user space that also interacts with the kernel
> in some way, and therefore includes <linux/*.h> files, problems resulting
> from two different sets of definitions of macros, types, structs, etc.  may
> arise.

> The above solution has fixed the problem for me when it has cropped up.

> Hope this helps.

> Liron Lightwood

--
Scott Stahl
MIS Asst.
Illinois Housing Development Authority
401 N. Michigan Ave. Ste. 900
Chicago, IL 60611