Is there any compiler flag (or other method) that disallow include like following
#include "../lib.h"
but still allows you to include libs in current context and its childs
#include "lib.h"
#include "directory/lib.h"
There is no such flag that one can pass to perform this.
I suspect that one could craft some calls to other programs in the compiler call, but that is starting to become a maintenance nightmare.
Rather, one should look into the features offered by the build system used for the project and see if it offers any forms of checks that can be run before compilation.
Related
I am giving Gwan a whirl.
Having made it through example code, I started a small project with more than one source file. I now have two problems:
I got a linking error at server startup:
Linking main.cpp: undefined symbol: _ZN7GwanUrl9concatAllEv
(the main file #includes the two other files; all the files are in the csp directory)
As an alternative to having all the files in the /csp directory, I would like to make a library outside of the /csp directory while still using some of the gwan functions. sadly, a tonne of errors follow -- WHEN I GCC from commandline not via G-WAN Startup.
In file included from /home/ec2-user/gwan/include/gwan.h:22,
from Xbufstream.h:10,
from Xbufstream.cpp:10:
/usr/include/time.h:199: error: ‘size_t’ does not name a type
.....
Anyone knows what the gwan g++ argument string looks like?
(odd the 1. and 1. its 1. and 2. in the editor)
First, this is not a linker issue: you have "undefined symbol" rather than "unresolved symbol" as an error.
This is simply an #include issue.
define the main() function in your script.cpp file.
there's a G-WAN folder dedicated to user-defined include files called /gwan/include but you can as well use /csp/my_include.hpp... if you are using the right syntax:
For example, having #include "toto.hpp" in /csp/hello.cpp lets me reach C++ functions defined and implemented in the gwan/include/toto.hpp file (or defined in toto.hpp and implemented in a pre-compiled library linked to your script with #pragma link).
If you rather use #include <toto.hpp> then the SYSTEM INCLUDE PATH will be searched instead (and this will work providing that your library was correctly installed).
If you want to use #include "toto.hpp" for a custom folder that was not setup in the system, you can use G-WAN's #pragma include "../my_folder" directive to specify its PATH or you can explicitely specify it in each include: #include "../my_folder/toto.hpp".
Nothing fancy there, only C/C++ dependancy rules apply (and G-WAN really helps by providing alternate ways that do not involve system settings).
For libraries (see the G-WAN examples for SQLite, Cairo, mySQL, cURL, etc.) you can either use pre-installed libraries that exported their location in SYSTEM variables... or put your library in the /gwan/libraries folder and their include file in the /gwan/include folder.
When writing your own libraries, remember that they need to be pre-compiled. This means that you obviously cannot use G-WAN symbols since your compiler may #include "gwan.h" (to have the definitions) but your linker will not know from where G-WAN symbols can be found. The way around is to always use the G-WAN API from the G-WAN scripts. Your custom libraries must either be general-purpose or buffer any payload intended to be used by G-WAN. No-double copy is needed since G-WAN provides the set_reply() call to let G-WAN use persistent replies built without the reply xbuffer provided by G-WAN servlets.
Now, a last word about linking (which was not the cause of your trouble but could participate to the confusion). If you mix C and C++, use extern C {} to wrap your C++ prototypes called from C (otherwise you will really have "unresolved symbols").
With all this information, you should be ready to face every possible situation.
the issue of referencing gwan.h symbols inside #include files can also be solved by moving all code into the header file, whether its .h or .hpp
its ungraceful but a fix nevertheless. and good enough for the simple extension i wanted.
looking into the /libraries/sqlite3/sqlite.h helped.
#gil, thanks for your time.
I recently spent a fairly substantial amount of time tracking down a problem that turned out to be caused by compiling a library with -D_GLIBCXX_DEBUG (which tells libstdc++ to use a debug version of the standard library with extra checks) but compiling the client program without. This caused an ABI compatibility problem.
Is there some way I can automatically detect problems like this with GCC? Visual Studio provides the detect_mismatch pragma which I think would have served this purpose, but I'm unaware of any GCC equivalent. GCC does something with embedding a symbol name (e.g. GLIBCXX_3.4.9), and I can imagine schemes that would cause a linking error because of an undefined symbol if a corresponding symbol (e.g. mylib_debug_stl) were not present, but the only ways I can think of to get a use of that symbol are really hacky.
Alternatively, how do other people avoid this issue? Build the checked version of the library to a different name or something like that?
Is there some way I can automatically detect problems like this with GCC?
Only the linker can detect if you link incompatible code, not the compiler.
The alternative linker, gold, can detect some problems with the --detect-odr-violations option.
Alternatively, how do other people avoid this issue? Build the checked version of the library to a different name or something like that?
I just ensure I rebuild everything when I want to use the Debug Mode, I don't think I've ever wanted to keep a library around that was built with Debug Mode. It's meant for debugging, not for normal use.
I rarely use -D_GLIBCXX_DEBUG anyway, I more often do something like:
#if 0
# include <debug/vector>
namespace my_class_stl = __gnu_debug;
#else
#include <vector>
namespace my_class_stl = std;
#endif
struct my_class
{
typedef my_class_stl::vector<int> container;
typedef container::iterator iterator;
// ...
};
Then I change the preprocessor condition when I want to use a Debug Mode vector for that specific class, without affecting every container in the program. Because the change involves writing to the file (and so updating its timestamp) anything that depends on that header will get rebuilt by make, and there are two distinct types, std::vector<int> and __gnu_debug::vector<int>, which have different symbols and can't be confused by the linker.
Just defining _GLIBCXX_DEBUG doesn't cause all dependencies to be rebuilt, and silently alters the definition of std::vector globally, rather than changing specific containers to a different type with a different name, __gnu_debug::vector
turned out to be caused by compiling a library with -D_GLIBCXX_DEBUG (which tells libstdc++ to use a debug version of the standard library with extra checks) but compiling the client program without.
It is an explicit libsdc++ debugging mode design goal to support such configuration, and I somewhat doubt that that was the actual cause of your problem.
The problem may have disappeared after you rebuilt the library without -D_GLIBCXX_DEBUG, but that doesn't prove that the ABI incompatibility was the root cause.
I am writing a user-space Win32 application. However, as part of this application I need to make some DeviceIo calls to the Windows 1394 stack. The header file which contains the prototypes for these DeviceIo calls is included as part of the Windows DDK at:
C:\WinDDK\7600.16385.1\inc\api\ntdd1394.h
(Although the header claims to be "Kernel mode only" the prototypes are for user-space IOCTLs.) I am wondering what the best way to include this file in my application is.
It would be poor practice to #include it directly (the path depends, among other things, on the DDK version) and in addition there is no real need for the DDK to be installed --- the only dependency my application has on it is for this very header file.
Hence I am wondering what the best course of action is? I was considering including a stripped-down version of it directly in my applications source but really am not sure.
I'd say include either a stripped down version, or if what your using is really small, import copy it directly into the main header for your project.
regardless which path you take, I'd say wrap both in #define guards, incase someone else who tinkers with this inports the correct header and causes trouble. Even better would be something to allow the user to either define the path to the DDK or use your stripped down version:
#define EXP(x) #x
#define STR(x) EXP(x)
#if defined(__WIN32_DDK_PATH)
#include STR(__WIN32_DDK_PATH)
#else
//Stripped DDK stuff...
#endif
tested the above using gcc 3.4.5(old I know, but dev-cpp is all I have where I am), works fine
How are you linking against the actual implementations of these functions? The documentation for the library you are linking against should tell you what to #include.
Also, do you need other people to be able to build this application or is it a one-man job? You could always set up a virtual build machine which has the DDK installed and #include the file that way.
Otherwise, yes, including the function prototypes in your own stripped down header file (with a comment to say why you are doing this!) is probably the way to go.
This works for me (taken from one of the samples in DDK):
#define _WIN1394_C
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ntdd1394.h>
#undef _WIN1394_C
I've run into trouble in the past when I've tried porting some C++ code written on Mac OS X to a Linux system, or trying to compile code written against an older version of gcc/g++ with a newer one:
It seems that some (older?) versions of gcc/g++ would automatically include some header files for you.
For example, code that uses printf should require #include <stdio.h>. And code that uses memcpy should require #include <string.h>. But depending on the version of gcc I'm using, it will occasionally include these for me.
It wreaks havoc when I forget to include something and then never get errors until I go to compile the code on another system. At that point it's a game of running all over the project and fixing the includes.
Has anyone else run into this? Is there a way to force gcc to autoinclude or to not autoinclude? Or, is there a way to know what it's autoincluding?
-include file
Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched for file is the preprocessor's working directory instead of the directory containing the main source file. If not found there, it is searched for in the remainder of the #include "..." search chain as normal.
If multiple -include options are given, the files are included in the order they appear on the command line.
http://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html
Are you sure it's not other headers pulling those one's in, and on the other platforms not doing so?
When compiling on different systems, you might meet different problems and not only includes.
I would suggest investing in a continuous build system that will compile on all OS you need after each update of the code, so you are rapidly aware of any portability issue.
You can also put all common system header files inside a specific header file you will write and systematically include it in all your files.
Why does C++ Builder 6 always compile all files?
I make some changes on one file but BCB 6 compiles all files when I start the app. Any idea? I use Windows XP SP2.
try this plugin for BCB compiler:
Bcc32Pch IDE Plugin
Are you source files and binary objects located on the same machine? If not sounds like you have a network time sync issue.
If they are its most likely a header file issue, either the compiler include files have a modified date some time in the future or your application is dependent on some header file that changes during compilation say from a COM import.
EDIT: Check the setting VS has a flag to always re-compile, this might be true for BCB too, if set then unset it. Another possibility is that pre-compiled headers are miss-configured to generate on every source file.
I am not familiar with BCB 6 to give a more precise answer.
Have you made all or many of your files dependent on a particular module?
Any files that are dependent on a particular module will be rebuilt any time the module class structure (contained in the .h file) is modified. If, for example, you have a data module that is accessed by many other modules you will see a rebuild of all dependent modules each time the data module's class structure is modified.
There are an pragma in Borland, wich controls how many lines of code is recompiled.
In the past years i have managed (in some project), that only changes of my source are compiled. I don't know, if this will be worked in newer versions of borland
Borland 6 has an pragma "hdrstop".
this is only active, if the project option "Pre-Compile headers" is NOT "none"
years ago I have an very slow computer an i accelerate the compilition time from hours to minutes with following trick
all cpps have become this first line
#include "all.h"
#pragma hdrstop
default was an include of "vcl.h"
"all.h" will includes all header, wich are needed in all! units. every unit will skip all sources, wich depend on header before pragma hdrstop.
Example:
Unit1.h
#include <string>
Unit1.cpp
#include "all.h"
#pragma hdrstop
#include "Unit1.h"
Unit2.h
#include <vcl>
Unit2.cpp
#include "all.h"
#pragma hdrstop
#include "Unit2.h"
all.h
#include <string>
#include <vcl>
Importing
dont use all.h in headerfiles
you can add all includes, wich are used in the project header, like ,
All sources wich depend on the "pre compiled headers" will not be compiled again!
generation of precompiled headers will be slow! So only add headers in all.h, which will not be changed often. Like system headers or your headers wich are already finished.
compilation can be failed. sometimes the order of the includes produce an "deadlock" for the comilation. if its happen, deactivate "pre-compiled headers". Most problems will be solved, if you write your c++ like in java: every class will become his own files(cpp and h).
Filename in the project option "Pre-Compiled headers" shows the basename of the real precompiled files. an unit can share an precompiled file with another unit, if it have (exact) the same inludes before "pragma hdrstop". Best performance is reached, if you have only one file with an numeric postfix. Example for more than one precompiled header:
Unit1.h
#include <string>
Unit1.cpp
#include "all.h"
#pragma hdrstop
#include "Unit1.h"
Unit2.h
#include <vcl>
Unit2.cpp
#include <vcl> //!!!!!!!!!!!!!!!!!!! produce a second version of an precompiled file
#pragma hdrstop
#include "Unit2.h"
all.h
#include <string>
#include <vcl>
Make sure you are using the "make" command and not the "build" command, unless it is required.
Making a project with the Borland tools has always seemed to have that issue -- that it doesn't necessarily notice which ones have changed and starts to compile everything.
Look at the Pre-Compiled Headers options, which may help speed things up.
When Borland/CodeGear, starting in C++Builder 2007, switched to the MSBuild system, the compilations have gone much faster and are more efficient.