Why are there multiple copies of header files in /usr/include?
Clash Royale CLAN TAG#URR8PPP
up vote
4
down vote
favorite
I've been browsing my /usr/include folder trying to get acquainted with the layout and I've noticed that there are multiple copies of header files (at least by name, I didn't actually diff them to see if they were exact copies) found in several sub directories of /usr/include. This is especially the case for standard C and C++ header files as well as POSIX/LSB standard header files.
Some examples include (note ./ refers to /usr/include):
./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h
./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h
./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath
./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h
./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h
Why is this? And why do some C standard headers show up in C++ locations?
I only have one compiler installed (GCC 7).
c c++ linux-headers
add a comment |
up vote
4
down vote
favorite
I've been browsing my /usr/include folder trying to get acquainted with the layout and I've noticed that there are multiple copies of header files (at least by name, I didn't actually diff them to see if they were exact copies) found in several sub directories of /usr/include. This is especially the case for standard C and C++ header files as well as POSIX/LSB standard header files.
Some examples include (note ./ refers to /usr/include):
./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h
./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h
./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath
./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h
./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h
Why is this? And why do some C standard headers show up in C++ locations?
I only have one compiler installed (GCC 7).
c c++ linux-headers
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I've been browsing my /usr/include folder trying to get acquainted with the layout and I've noticed that there are multiple copies of header files (at least by name, I didn't actually diff them to see if they were exact copies) found in several sub directories of /usr/include. This is especially the case for standard C and C++ header files as well as POSIX/LSB standard header files.
Some examples include (note ./ refers to /usr/include):
./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h
./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h
./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath
./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h
./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h
Why is this? And why do some C standard headers show up in C++ locations?
I only have one compiler installed (GCC 7).
c c++ linux-headers
I've been browsing my /usr/include folder trying to get acquainted with the layout and I've noticed that there are multiple copies of header files (at least by name, I didn't actually diff them to see if they were exact copies) found in several sub directories of /usr/include. This is especially the case for standard C and C++ header files as well as POSIX/LSB standard header files.
Some examples include (note ./ refers to /usr/include):
./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h
./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h
./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath
./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h
./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h
Why is this? And why do some C standard headers show up in C++ locations?
I only have one compiler installed (GCC 7).
c c++ linux-headers
c c++ linux-headers
asked Nov 19 at 5:26
Adam Sperry
254
254
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
No, they aren't exact copies.
If you care to investigate, you'll find that the files at the top level /usr/include
will normally have a lot of #ifdef
s or other conditionals, and they'll only define the architecture-independent parts and will #include
other stuff from architecture-specific directories deeper within the hierarchy. As some architecture-specific parts may in turn depend on some architecture-independent parts, there may be multiple layers of inclusion on top of each other.
Likewise, the files under /usr/include/c++
will have the additional declarations that will only make sense for C++, and #include
s for the corresponding C include files where appropriate.
The name of the game is deduplication for maintainability: the aim is that when a glibc developer needs to add something new that only affects the ABI between the application and glibc and has no architecture-specific parts, the addition ideally needs to happen at just one location in the tree of include files, and it will take effect for all hardware architectures that use glibc. Or, say, when a new system call is added to the Linux kernel, there will be a place to add it without interfering with *BSD or GNU Hurd system call definitions, for example. Or if you're porting glibc to yet another hardware/kernel architecture, you'll find places you can plug in the necessary kernel ABI definitions without disturbing architecture-independent stuff any more than absolutely necessary.
Yes, it's pretty complicated.
I don't have any easy references for you, since the entire /usr/include
layout is a sum of ISO C and POSIX standards requirements and the choices made by both the GCC and glibc projects.
I'd suggest you make a note of your architecture triplet (x86_64-linux-gnu
in your case; obtainable with gcc -dumpmachine
on any architecture supported by GCC) and then study the compiler's default #include <...>
file search paths.
You can see the search paths with:
cpp -v /dev/null -o /dev/null
for plain Ccpp -x c++ -v /dev/null -o /dev/null
for C++
I don't have a system with GCC 7 at hand here, but for GCC 6, the list of include paths looks like this for C:
...
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
... and like this for C++:
...
#include <...> search starts here:
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
If the /usr/local/include/<architecture triplet>
directory existed, it would get added in the lists, just before /usr/local/include
.
So, it would seem that for your own projects, if you need to have architecture-specific versions of an include file, you could put them under /usr/[local/]include/<architecture triplet>/
, and the regular architecture-agnostic include files to /usr/[local/]include/
. I wouldn't touch any include directories whose path name includes the major version number of the compiler without a very good reason.
If you plan to modify glibc
, and you cannot find what you need in the glibc
developer documentation, you'd better ask for advice on the glibc
development mailing list; glibc
is extra complicated because it is usable also on architectures that use a compiler other than GCC, and so might not have the architecture triplet convention as standard.
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
No, they aren't exact copies.
If you care to investigate, you'll find that the files at the top level /usr/include
will normally have a lot of #ifdef
s or other conditionals, and they'll only define the architecture-independent parts and will #include
other stuff from architecture-specific directories deeper within the hierarchy. As some architecture-specific parts may in turn depend on some architecture-independent parts, there may be multiple layers of inclusion on top of each other.
Likewise, the files under /usr/include/c++
will have the additional declarations that will only make sense for C++, and #include
s for the corresponding C include files where appropriate.
The name of the game is deduplication for maintainability: the aim is that when a glibc developer needs to add something new that only affects the ABI between the application and glibc and has no architecture-specific parts, the addition ideally needs to happen at just one location in the tree of include files, and it will take effect for all hardware architectures that use glibc. Or, say, when a new system call is added to the Linux kernel, there will be a place to add it without interfering with *BSD or GNU Hurd system call definitions, for example. Or if you're porting glibc to yet another hardware/kernel architecture, you'll find places you can plug in the necessary kernel ABI definitions without disturbing architecture-independent stuff any more than absolutely necessary.
Yes, it's pretty complicated.
I don't have any easy references for you, since the entire /usr/include
layout is a sum of ISO C and POSIX standards requirements and the choices made by both the GCC and glibc projects.
I'd suggest you make a note of your architecture triplet (x86_64-linux-gnu
in your case; obtainable with gcc -dumpmachine
on any architecture supported by GCC) and then study the compiler's default #include <...>
file search paths.
You can see the search paths with:
cpp -v /dev/null -o /dev/null
for plain Ccpp -x c++ -v /dev/null -o /dev/null
for C++
I don't have a system with GCC 7 at hand here, but for GCC 6, the list of include paths looks like this for C:
...
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
... and like this for C++:
...
#include <...> search starts here:
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
If the /usr/local/include/<architecture triplet>
directory existed, it would get added in the lists, just before /usr/local/include
.
So, it would seem that for your own projects, if you need to have architecture-specific versions of an include file, you could put them under /usr/[local/]include/<architecture triplet>/
, and the regular architecture-agnostic include files to /usr/[local/]include/
. I wouldn't touch any include directories whose path name includes the major version number of the compiler without a very good reason.
If you plan to modify glibc
, and you cannot find what you need in the glibc
developer documentation, you'd better ask for advice on the glibc
development mailing list; glibc
is extra complicated because it is usable also on architectures that use a compiler other than GCC, and so might not have the architecture triplet convention as standard.
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
add a comment |
up vote
3
down vote
accepted
No, they aren't exact copies.
If you care to investigate, you'll find that the files at the top level /usr/include
will normally have a lot of #ifdef
s or other conditionals, and they'll only define the architecture-independent parts and will #include
other stuff from architecture-specific directories deeper within the hierarchy. As some architecture-specific parts may in turn depend on some architecture-independent parts, there may be multiple layers of inclusion on top of each other.
Likewise, the files under /usr/include/c++
will have the additional declarations that will only make sense for C++, and #include
s for the corresponding C include files where appropriate.
The name of the game is deduplication for maintainability: the aim is that when a glibc developer needs to add something new that only affects the ABI between the application and glibc and has no architecture-specific parts, the addition ideally needs to happen at just one location in the tree of include files, and it will take effect for all hardware architectures that use glibc. Or, say, when a new system call is added to the Linux kernel, there will be a place to add it without interfering with *BSD or GNU Hurd system call definitions, for example. Or if you're porting glibc to yet another hardware/kernel architecture, you'll find places you can plug in the necessary kernel ABI definitions without disturbing architecture-independent stuff any more than absolutely necessary.
Yes, it's pretty complicated.
I don't have any easy references for you, since the entire /usr/include
layout is a sum of ISO C and POSIX standards requirements and the choices made by both the GCC and glibc projects.
I'd suggest you make a note of your architecture triplet (x86_64-linux-gnu
in your case; obtainable with gcc -dumpmachine
on any architecture supported by GCC) and then study the compiler's default #include <...>
file search paths.
You can see the search paths with:
cpp -v /dev/null -o /dev/null
for plain Ccpp -x c++ -v /dev/null -o /dev/null
for C++
I don't have a system with GCC 7 at hand here, but for GCC 6, the list of include paths looks like this for C:
...
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
... and like this for C++:
...
#include <...> search starts here:
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
If the /usr/local/include/<architecture triplet>
directory existed, it would get added in the lists, just before /usr/local/include
.
So, it would seem that for your own projects, if you need to have architecture-specific versions of an include file, you could put them under /usr/[local/]include/<architecture triplet>/
, and the regular architecture-agnostic include files to /usr/[local/]include/
. I wouldn't touch any include directories whose path name includes the major version number of the compiler without a very good reason.
If you plan to modify glibc
, and you cannot find what you need in the glibc
developer documentation, you'd better ask for advice on the glibc
development mailing list; glibc
is extra complicated because it is usable also on architectures that use a compiler other than GCC, and so might not have the architecture triplet convention as standard.
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
No, they aren't exact copies.
If you care to investigate, you'll find that the files at the top level /usr/include
will normally have a lot of #ifdef
s or other conditionals, and they'll only define the architecture-independent parts and will #include
other stuff from architecture-specific directories deeper within the hierarchy. As some architecture-specific parts may in turn depend on some architecture-independent parts, there may be multiple layers of inclusion on top of each other.
Likewise, the files under /usr/include/c++
will have the additional declarations that will only make sense for C++, and #include
s for the corresponding C include files where appropriate.
The name of the game is deduplication for maintainability: the aim is that when a glibc developer needs to add something new that only affects the ABI between the application and glibc and has no architecture-specific parts, the addition ideally needs to happen at just one location in the tree of include files, and it will take effect for all hardware architectures that use glibc. Or, say, when a new system call is added to the Linux kernel, there will be a place to add it without interfering with *BSD or GNU Hurd system call definitions, for example. Or if you're porting glibc to yet another hardware/kernel architecture, you'll find places you can plug in the necessary kernel ABI definitions without disturbing architecture-independent stuff any more than absolutely necessary.
Yes, it's pretty complicated.
I don't have any easy references for you, since the entire /usr/include
layout is a sum of ISO C and POSIX standards requirements and the choices made by both the GCC and glibc projects.
I'd suggest you make a note of your architecture triplet (x86_64-linux-gnu
in your case; obtainable with gcc -dumpmachine
on any architecture supported by GCC) and then study the compiler's default #include <...>
file search paths.
You can see the search paths with:
cpp -v /dev/null -o /dev/null
for plain Ccpp -x c++ -v /dev/null -o /dev/null
for C++
I don't have a system with GCC 7 at hand here, but for GCC 6, the list of include paths looks like this for C:
...
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
... and like this for C++:
...
#include <...> search starts here:
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
If the /usr/local/include/<architecture triplet>
directory existed, it would get added in the lists, just before /usr/local/include
.
So, it would seem that for your own projects, if you need to have architecture-specific versions of an include file, you could put them under /usr/[local/]include/<architecture triplet>/
, and the regular architecture-agnostic include files to /usr/[local/]include/
. I wouldn't touch any include directories whose path name includes the major version number of the compiler without a very good reason.
If you plan to modify glibc
, and you cannot find what you need in the glibc
developer documentation, you'd better ask for advice on the glibc
development mailing list; glibc
is extra complicated because it is usable also on architectures that use a compiler other than GCC, and so might not have the architecture triplet convention as standard.
No, they aren't exact copies.
If you care to investigate, you'll find that the files at the top level /usr/include
will normally have a lot of #ifdef
s or other conditionals, and they'll only define the architecture-independent parts and will #include
other stuff from architecture-specific directories deeper within the hierarchy. As some architecture-specific parts may in turn depend on some architecture-independent parts, there may be multiple layers of inclusion on top of each other.
Likewise, the files under /usr/include/c++
will have the additional declarations that will only make sense for C++, and #include
s for the corresponding C include files where appropriate.
The name of the game is deduplication for maintainability: the aim is that when a glibc developer needs to add something new that only affects the ABI between the application and glibc and has no architecture-specific parts, the addition ideally needs to happen at just one location in the tree of include files, and it will take effect for all hardware architectures that use glibc. Or, say, when a new system call is added to the Linux kernel, there will be a place to add it without interfering with *BSD or GNU Hurd system call definitions, for example. Or if you're porting glibc to yet another hardware/kernel architecture, you'll find places you can plug in the necessary kernel ABI definitions without disturbing architecture-independent stuff any more than absolutely necessary.
Yes, it's pretty complicated.
I don't have any easy references for you, since the entire /usr/include
layout is a sum of ISO C and POSIX standards requirements and the choices made by both the GCC and glibc projects.
I'd suggest you make a note of your architecture triplet (x86_64-linux-gnu
in your case; obtainable with gcc -dumpmachine
on any architecture supported by GCC) and then study the compiler's default #include <...>
file search paths.
You can see the search paths with:
cpp -v /dev/null -o /dev/null
for plain Ccpp -x c++ -v /dev/null -o /dev/null
for C++
I don't have a system with GCC 7 at hand here, but for GCC 6, the list of include paths looks like this for C:
...
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
... and like this for C++:
...
#include <...> search starts here:
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
...
If the /usr/local/include/<architecture triplet>
directory existed, it would get added in the lists, just before /usr/local/include
.
So, it would seem that for your own projects, if you need to have architecture-specific versions of an include file, you could put them under /usr/[local/]include/<architecture triplet>/
, and the regular architecture-agnostic include files to /usr/[local/]include/
. I wouldn't touch any include directories whose path name includes the major version number of the compiler without a very good reason.
If you plan to modify glibc
, and you cannot find what you need in the glibc
developer documentation, you'd better ask for advice on the glibc
development mailing list; glibc
is extra complicated because it is usable also on architectures that use a compiler other than GCC, and so might not have the architecture triplet convention as standard.
edited Nov 19 at 21:23
answered Nov 19 at 8:21
telcoM
14.3k11842
14.3k11842
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
add a comment |
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
Thank you! This was very informative. I would like to investigate further. Do you have any references I can look to for further information about the way /use/include is organized in order to achieve the goals you’ve described? I would like to know which regions of this tree are designated for the specific purposes you’ve mentioned.
– Adam Sperry
Nov 19 at 14:10
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482669%2fwhy-are-there-multiple-copies-of-header-files-in-usr-include%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown