質問

It may sound obvious, but I can't get a clear idea of how to manage Makefiles and #include commands.

As I understand, #include is used to - as per its name - include library files by indicating their header (.h) filename. They can be in the program folder or in some standard library directories. The makefile specifies, among other things, what files and packages have to be put together when compiling the executable.

Say I want to add a source file I made (.c and .h) to an already existing program. Do I have to both #include and add them to the makefile?

EDIT - additional question: if I put a source file in the makefile but forget to #include it, will I get an error or will it just not be used?

役に立ちましたか?

解決

Yes, in general.

All #include does is include, i.e. literally paste in, the mentioned file. Since a header (.h) file typically only contains declarations, but not definitions (i.e. the actual function implementations) it's not enough.

That's why you typically must interact with the linker, often from the Makefile, to tell it which additional libraries to link your program with.

Both are needed, since:

  • Trying to link a program that has the #includes but not the correct libraries will fail, with "unresolved symbol"-type errors.
  • Trying to call functions in a library that you are linking with, but without the proper #includes will generate "undeclared symbol" warnings or errors.

他のヒント

Suppose you have an existing program consisting of main.c, foo.c, foo.h and a makefile that builds the program. And suppose you want to add bar.c and bar.h.

Anything that needs bar code must tell the compiler where to find it. Otherwise if the Foo class has a Bar member, and main() calls bar_transform(), the compiler will scream that it doesn't know what you're talking about. So foo.h and main.c must each contain this line:

#include "bar.h"

(The pattern here is a little subtle. Notice that foo.c probably does not need this directive, because it has #include "foo.h", and foo.h has #include "bar.h". Also, there are cases in which it would be better to use forward declaration int foo.h and put the directive in foo.c instead. If you have trouble with this, we can help.)

Now the code is correct. We can compile it and produce main.o, foo.o and bar.o. We just have to link them correctly.

The makefile must contain something that tells Make what files to use when building the executable, perhaps like this:

app: main.o foo.o
    $(CC) $^ -o $@

If you try this after modifying the source files, Make will compile main.o and foo.o correctly, then try to link them, and the linker will scream that the Bar class is incomplete, and it can find no definition of bar_transform().

To incorporate bar in the build, you need only add bar.o to that list of prerequisites:

app: main.o foo.o bar.o
    ...

There are other ways the makefile could specify the list, so if you have trouble, show us your makefile. Also, this doesn't address the problem of dependency handling (e.g. knowing that foo.o must be rebuilt if bar.h has changed); this is probably very easy to fix, but we have to see the makefile.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top