So somewhere along the way compiling as a regular user has stopped working on my server. I'm on Debian Stable. Can't think what has changed on my system that would result in this, or how to fix it, but now only root can compile.

user@box:~/code/helloworld$ gcc helloworld.c -o helloworld
In file included from /usr/include/stdio.h:28:0,
                 from helloworld.c:3:
/usr/include/features.h:356:25: fatal error: /usr/local/include/sys/cdefs.h: Permission denied
compilation terminated.

Compiling as root is fine. I presume this is a permissions issue?

As user@server:

ls -la /usr/local/include/sys/cdefs.h
ls: cannot access /usr/local/include/sys/cdefs.h: Permission denied

ls -la /usr/local/include/sys/       
ls: cannot access /usr/local/include/sys/.: Permission denied
ls: cannot access /usr/local/include/sys/..: Permission denied
ls: cannot access /usr/local/include/sys/apparmor.h: Permission denied
ls: cannot access /usr/local/include/sys/cdefs.h: Permission denied
total 0
d????????? ? ? ? ?            ? .
d????????? ? ? ? ?            ? ..
-????????? ? ? ? ?            ? apparmor.h
-????????? ? ? ? ?            ? cdefs.h

The user can read /usr/local/include fine. Root shows the perms on /usr/local/include/sys to be (note user is in staff group):

drwxr-Sr-- 2 root staff 4096 Dec 7 08:20 sys

Location of cdefs.h

locate cdefs.h

I've tried fixing the perms but I can't get it right. Is there a way to ignore the cdefs.h from /usr/local and use the one it /usr/include/?

Any help greatly appreciated!

2 Answers 2


I don't think there is a particularly good way to totally ignore it (it's possible with the gcc nostdinc switch, but then you will need to add -I for all necessary paths).

However, there is an easy way to force the compiler to choose the one you want. According to http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html, the normal order of include paths is:


Presumably this is to allow you to easily override a system include with a local user one. But what trumps all those is -I, so if you compile:

gcc -I/usr/include/sys

Then it will pick cdefs.h from there. It won't eliminate /usr/local/include from the path tho, so if there are other files that fall into this category you may need more -I's. They are not recursive, so eg:

gcc -I/usr/include

Will not prioritize /usr/include/sys, just as the other version will not prioritize /usr/include. So you might need:

gcc -I/usr/include -I/usr/include/sys

Using a makefile makes these kinds of things significantly easier, btw. Eventually you will want to learn how to do that.

There may be some other problems you will run into related to whatever the reason for having this header duplicated is, but you'll have to explain that. Is this your system?


I've tried fixing the perms but I can't get it right. Is there a way to ignore the cdefs.h from /usr/local and use the one it /usr/include/?

Yes, don't install them in /usr/local/. Debian will never install anything in /usr/local, so if there is files here, it's because you, other local administrators or badly packaged software installed these things here. Install them anywhere else. But installing another libc's headers in /usr/local is asking for trouble.

  • There's nothing wrong with putting stuff in /usr/local. The reason Debian (or any other distro) does not install stuff there is because that's not what it is for -- it's for 3rd party software. It is a better practice to use /usr/local for 3rd party stuff than to use /usr to avoid overwriting distro package stuff. Of course, this can lead to duplications, but that is better than having replaced a system file with one from a 3rd party.
    – goldilocks
    Dec 8, 2012 at 14:39
  • @goldilocks: The problem with having different software is /usr and /usr/local is not about duplication, it's about conflicts. Installing a libc in /usr/local IS Wrong. Put that (and everything third party) in /opt.
    – BatchyX
    Dec 8, 2012 at 14:51
  • I'll agree that installing a libc in /usr/local should not be done willy-nilly. Installing a libc in any standard path -- you do realize /usr/local is in that? So what is it for? ;) -- on top of the distro one should not be done willy-nilly. However, to say that "it is wrong to install software in /usr/local" is, well, just wrong.
    – goldilocks
    Dec 8, 2012 at 14:56
  • @goldilocks: By installing software to /usr/local, you must abide to the fact that the software must be compatible with the existing software on your system/distribution, and any later update you may install. If you cannot guarantee that (and most of the time, you don't, or you don't care), then installing in /usr/local is wrong. /usr/local may be standard but so is /opt. Installing any software (including libcs) in /opt can be done willy-nilly and can be managed more easily.
    – BatchyX
    Dec 8, 2012 at 18:21
  • @goldilocks, @BatchyX: well, installing anything you won't guarantee will work with updates anywhere is asking for troubles. The difference between /usr and /usr/local is historic: /usr often used to be a network mounted filesystem (usually read-only), and /usr/local was the place to put system-wide files that were present on local storage. /opt was intended for sw from other vendors. Hence one of the main differences between /usr/local and /opt is, that the first is usually in $PATH and /opt should have per-application subtrees (today e.g. /opt/kde3).
    – peterph
    Dec 8, 2012 at 23:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.