Including header file from static library

后端 未结 1 1456
小鲜肉
小鲜肉 2021-02-04 03:27

I am making a test setup of a C static library and program. The library code, located in a subdirectory \'foo\' of my project, contains the following files:

foo/

相关标签:
1条回答
  • 2021-02-04 04:01

    Headers are not stored in libraries. Headers are stored separately from libraries. Libraries contain object files; headers are not object files. By default, standard headers on a Unix system are stored in /usr/include — you'll normally find /usr/include/stdio.h and /usr/include/string.h and /usr/include/stdlib.h, for example. By default, libraries are stored in /usr/lib (but you may also find some in /lib). Often, compilers are configured to look in some other places too. One common alternative location is under /usr/local, so /usr/local/include for headers and /usr/local/lib for libraries. Note, too, that a single library may have many headers defining the services. The default library is an example. It has the functions corresponding to those found in <stdio.h>, <string.h>, <stdlib.h> and many other headers too.

    Looking at your code:

    1. If your header file is in ./foo/foo.h, then you need to write:

      #include "foo/foo.h"
      

      Or if you continue to use #include "foo.h", you need to specify where to find the header on the compiler command line with the argument:

      gcc -Ifoo -o test test.c -L. -lfoo
      

      I deliberately excluded the -static; it's only necessary when there's a choice between a static and a shared library, but you only have libfoo.a, so the linker will use that anyway.

      Note that the problem is a compilation error, not a linking error. This would be clearer if you split the program building into two steps: (1) create test.o and (2) link program:

      gcc -c -Ifoo test.c
      gcc -o test test.o -L. -lfoo
      
    2. Your header guard is faulty. You originally had (but have updated the question so this typo is no longer present):

      #ifndef foo_h__
      #define foo_h_
      

      You need:

      #ifndef foo_h__
      #define foo_h__
      

      The macro names must be the same in both lines. Note that in this case, the misspelling is mostly harmless — but on Mac OS X, clang (masquerading as gcc) did give a warning about it (though I'd spotted it before I did any compilation). In some other cases, you wouldn't get the protection that the header guards are designed to provide.

      ./foo/foo.h:1:9: warning: 'foo_h__' is used as a header guard here, followed by #define of a
            different macro [-Wheader-guard]
      #ifndef foo_h__
              ^~~~~~~
      ./foo/foo.h:2:9: note: 'foo_h_' is defined here; did you mean 'foo_h__'?
      #define foo_h_
              ^~~~~~
              foo_h__
      1 warning generated.
      

    You might legitimately wonder:

    • If I need -Ifoo when compiling test.c, why wasn't it necessary when compiling foo/foo.c?

    Good question!

    1. It would not have hurt the compilation of foo/foo.c
    2. GCC looks for headers in the directory where the source code of the translation unit is found (so, when compiling foo/foo.c, it looks in foo directory for headers included as #include "foo.h" anyway.
    3. The source file foo/foo.c should have included foo.h too; it is very important that it does as that is how the compiler provides the cross-checking necessary to ensure consistency. If you had written #include "foo.h", the compilation would work as described. If you wrote (in foo/foo.c) #include "foo/foo.h", then the command line for creating foo.o would have needed -I. so the header could be found.
    0 讨论(0)
提交回复
热议问题