← User:Mkretz You do not have permission to edit this page, for the following reason: The action you have requested is limited to users in one of the groups: Users, Administrators, trusted, KDEDevelopers. You can view and copy the source of this page. == getting #includes right == There are two types of #include statements: <tt>#include <foo.h></tt> and <tt>#include "foo.h"</tt>. Say we have the file <tt>xyz.h</tt> in <tt>/usr/include/mylib/</tt> that contains the following: <code cpp n> #include <header1.h> #include "header2.h" </code> The preprocessor will search for the file <tt>header1.h</tt> in all the paths given as <tt>-I</tt> arguments and then replace the line with the contents of that file. For line 2 the preprocessor tries to use the file /usr/include/mylib/header2.h first and if it does not exist search for the file like it did for <tt>header1.h</tt>. The important part to note here is that the preprocessor does not look in the directory of the source file that includes <tt>xyz.h</tt> but in the directory where <tt>xyz.h</tt> resides. Now, which include statement is the one to use? After all you can specify every directory you want using <tt>-I</tt> and thus could use <tt>#include <...></tt> everywhere. === as an application developer === * Include headers from '''external''' libraries using '''angle brackets'''. <code cpp> #include <iostream> #include <QtCore/QDate> #include <zlib.h> </code> * Include headers from your '''own project''' using '''double quotes'''. <code cpp> #include "myclass.h" </code>Using angle brackets works correctly if the first <tt>-I</tt> switch to the compiler is your own source directory (KDE4 cmake projects do that per default). Ideally you would not need to specify <tt>-I./</tt> though, as that might break with library headers that have the same filename as a header of your project (i.e.: If a library has the header file <tt>foo.h</tt> and your project has a different file with the same filename the compiler will always pick the header from your project instead of the one from the library because the source directory of the project is specified first.) === as a library developer === * Include headers from '''external''' libraries using '''angle brackets'''. <code cpp> #include <iostream> #include <QtCore/QDate> #include <zlib.h> </code> * Include headers of your '''own library''' and libraries that belong to it using '''double quotes'''. <code cpp> #include "xyz.h" // same library and same directory </code> If you use subdirectories for the installed header files you need to have the exact same directory structure for the headers in the source directory. Example: <tt>/usr/include/libfoo/</tt> contains the directory <tt>bar</tt>. In <tt>libfoo</tt> resides the header <tt>header1.h</tt>, in <tt>libfoo/bar</tt> the file <tt>header2.h</tt>. The latter depends on the former so it includes it using <code cpp> #include "../header1.h" // BAD IDEA </code> If the source directory structure of the library is not the same (in this case: <tt>header2.h</tt> in a subdirectory of the directory where <tt>header1.h</tt> resides) this obviously will break. It is also possible to use angle brackets in library headers, but that requires the application to supply the exactly correct <tt>-I</tt> paths (e.g. libfoo above can be used either with <tt>-I/usr/include</tt> and <tt>#include <libfoo/header1.h></tt> or <tt>-I/usr/include/libfoo</tt> and <tt>#include <header1.h></tt>, if libfoo were to use angle brackets to include its own headers one of the include switches has to be present for the lib to find its own headers). Also angle brackets require the application to not put any include directory before the <tt>-I</tt> switch for the lib that contains header files of the same filename as for the library. An example how angle brackets can break the build: <tt>/usr/include/libxyz/xyz.h</tt> includes <tt>foo.h</tt> using angle brackets and expects to have it replaced with the contents of the file <tt>/usr/include/libzyx/foo.h</tt>. Assuming there's another library that also ships a <tt>foo.h</tt> file in the directory <tt>/usr/include/anotherlib</tt>. If the application that uses both libraries compiles with <tt>g++ -I/usr/include/libxyz -I/usr/include/anotherlib ...</tt> libxyz will work as expected (but anotherlib might break). If the application compiles with <tt>g++ -I/usr/include/anotherlib -I/usr/include/libxyz ...</tt> the header <tt>xyz.h</tt> will include the file <tt>/usr/include/anotherlib/foo.h</tt> instead of the file that is shipped with libxyz. The same problem can appear if an application has a header file of the same name as a library and specifies <tt>-I./</tt> as the first include directory. ---- I suggest replacing 'application' with 'buildsystem' in various places to avoid confusion. Further what is missing here is a small guideline section. Things that people can read and use without having to grok the whole thing. Thanks! [[User:Zander|Zander]] 19:41, 9 April 2007 (CEST) Return to User:Mkretz. Retrieved from "https://techbase.kde.org/User:Mkretz"