How to compile if a header does not exist? - build

#include "MyHeader.h"
I would like MyHeader.h to be optional, i.e. to build even if it is not available.
Can I do it with the preprocessor, without involving the build system?

No, not really, not with the standard preprocessor anyway. The #include directive is a fairly simple one which just basically drags in the object as if it was part of the translation unit. You could wrap the include in a macro check:
#ifdef USE_MY_HEADER
#include "MyHeader.h"
#endif
but that would still require input from the build system somehow.
There are no facilities in the standard preprocessor to bring in a file only if it exists but there are several avenues you may want to examine, such as:
Just ensure there always is a file, even an empty one. That way, you can include it easily, and the user can modify it to add whatever they need. They just can't delete it.
Have your build system check for the existence of the file before compiling anything that uses it and, if it does not exist, create an empty one.
Think about whether this is needed at compile time. That should only be necessary if it needs to affect the actual compilation itself. If it's simply to affect the way the program behaves at run time, you could just as easily have a configuration file that's read by your program and uses the information to change behaviour. That way, you can detect a non-existent file and just ignore it.

Related

ignore a main in a header file

I'm trying to use (Ligra) in a project. The framework works as long as the chief header "ligra.h" is included. Trouble is, that header has an implementation of parallel_main, which is a macro wrapper around main with OpenMP trickery. So if I wanted to write a simple program:
#include "ligra.h"
#include <iostream>
int main(){
std::cout<<"Hello World";
return 0;
}
It would not compile. Redefinition of symbol main.
Also, I need a parallel_main, with the exact macro trickery done in the "parallel.h" header.
So I think I have two options:
1) modify the file, add a pair of #ifdef LIGRA_MAIN's and not define the macro at compile time. Thus I can have my own main and not have redefinition. Trouble is I need my project to be using the upstream version of ligra, and Julian Shun, the original developer has probably forgottten about his project (and github, since he ignored more than one pull request).
2) Use/Write a #pragma that would strip that function out at the include stage.
I don't know how to do that last part, and would be very much in your debt if someone who did, reached out.
A solution that does not involve modifying library files (but is somewhat brittle) could be to do the following:
#include "ligra/parallel.h" (this does #define parallel_main main).
#undef parallel_main to prevent this rewriting of function names.
#include "ligra/ligra.h" as usual. Since parallel.h has an include guard, its repeated inclusion is prevented and parallel_main will not be redefined.
Proceed as normal.
You might also want to wrap this into a header so you only have to write it once.
Alternatively, you could do what #user463035818 suggests and redefine main only for the inclusion of ligra.h for very similar effect. The difference is in the names that the parallel_main function(s) from ligra will get.
You can simply not include ligra.h. If there is something useful in that file, then create a copy of the file - excluding the main function - and use that copy.
Sure, that means that if the upstream ligra.h is updated, your copy will not have the corresponding changes. However, given the premise "the original developer has probably forgottten about his project", this is probably not a problem. If the premise is wrong, then a better approach would be to create a pull request to make the framework usable as a library.

Protecting certain include locations

I'm building a little language that will compile to C or C++, I haven't decided yet, however I have come across a dilemma concerning the #include keyword.
My language will come with a standard library that will be incorporated into the language, and be accessible much like that of C or C++ with the standard includes such as #include <string>.
My compiler can automatically tell the difference between user includes and standard library includes, but my issue lies in how the GCC compiler uses the -I flag.
Let's take Java as an example. One of the default packages (folder) is called java.util. If I try to make my own folder called java.util inside my project, I get the error:
The package java.util conflicts with a package accessible from another module: java.base
Meaning it is included by default.
I would like this to do the same thing in C++, but am worried that a user could (hypothetically) do a relative path include and cause a conflict.
Take for example, I use the flag like so: -I ../some/folder.
However then the user could simply type #include "../some/folder" to access the same content. Is there any way I can restrict this, and like the title of the question suggests, "protect" the folder from being called like that?
Furthermore, if there is a file inside of that folder called test.h and the user decides to create their own file called test.h locally and include it. How will the conflicts occur? Will it pick the local folder over the included via. flags?
An example of a basic implementation is as follows: (General syntax, no specific language)
boolean userDefine = false;
string defineName = "foo";
// Do something to determine if <> define or "" define.
if (userDefine) {
// Returns #include "foo"
return "#include \"" + defineName + "\"";
} else {
// Returns #include "stdlib/foo"
return "#include \"stdlib/" + defineName + "\"";
}
But then again, the user could include the folder so that it satisfies the first condition and still gain access.
It's pretty much the standard practice to put any #include files at the very beginning of the C++ source file, as the first order of business.
Of course, a #include can appear anywhere in the C++ source file, and there are situations when that happens but, if you were to grab some random C++ source from github, chances are pretty good that all the #include files will be at the beginning of the file.
So, all you have to do, is to make arrangements that your library's #include is always at the beginning, and use the standard #ifndef/#define guards in your header files. Then, manual inclusion of them subsequently will have no effect whatsoever, no matter what path is used.
Of course, this won't stop anyone from manually #undefing your guard, to create some chaos. However, C++ never had a reputation for reliably preventing you from shooting yourself in the foot, and is unlikely to earn that reputation in the foreseeable future; so what? Actually, most compilers implement #pragma once, which might be a slightly better foot self-shooting prevention approach...

How to throw a compile error if the include paths for a library were set up not as intended

Our C++ library contains a file with a namethat is (considered) equal to one of the standard libraries' headers. In our case this is "String.h", which Windows considers to be the same as "string.h", but for the sake of this question it could be any other ile name used in the standard library.
Normally, this file name ambiguity is not a problem since a user is supposed to set up the include paths to only include the parent of the library folder (therefore requiring to include "LibraryFolder/String.h") and not the folder containing the header.
However, sometimes users get this wrong and directly set the include path to the containing folder. This means that "String.h" will be included in place of "string.h" in both the user code and in the standard library headers, resulting in a lot of compile errors that may not be easy to resolve or understand for beginners.
Is it possible, during compile-time, to detect such wrongly set up include paths in our libraries' header and throw a compile #warning or #error right away via directive, based on some sort of check on how the inclusion path was?
There's no failsafe way. If the compiler finds another file, it won't complain.
However, you could make it so you can detect it. In your own LibraryName/string.h, you could define a unique symbol, like
#define MY_STRING_H412a55af_7643_4bd6_be5c_4315d3a1e6b7
Then later in dependent code you could check
#ifndef MY_STRING_H412a55af_7643_4bd6_be5c_4315d3a1e6b7
#error "Custom standard library path not configured correctly"
#endif
Likewise you could use this to detect when the wrong version of the library was included.
[edit - as per comments]
Header inclusion can be summarized as :
Parse #include line to determine header name to look up
Depending on <Foo.h> or "Foo.h" form, determine set of locations (usually directories) to search
Interpret the header name, in an implementation-dependent way. (usually as a relative path). Note that this is not necessarily as a string, e.g. MSVC doesn't treat \ as a string escape character.
If the header is found (usually, if a file is found), replace the #include line with the content of that file. If not, fail the compilation.
(The parenthesized "usually" apply to MSVC, GCC, clang, etc but theoretically a compiler could compile directly from a git repository instead of disk files)
The problem here is that the test imagined (spelling of header name) must be located in the included header file. This test would necessarily be part of the replaced #include line, which therefore no longer exists and cannot be tested.
C++17 introduces __has_include but this does not affect the analysis: It would still have to occur in the included header file, and would not have the character sequence from the #include "Foo.h" available.
[old]
Probably the easiest way, especially for beginners is to have a LibraryName/LibraryName.h. Hopefully that name is unique.
The benefit is that once that works, users can replace #include "LibraryName.h" with just #include "String.h" as you know the path is right.
That said, "String.h" is asking for problems. Windows isn't case sensitive.
Use namespaces. In your case this would translate into something like this:
MyString/String.h
namespace my_namespace {
class string {
...
}
}
Now to make sure your std::string or any other class named string is not accidentally used instead of my_namespace::string (by any means, including but not limited to setting up your include paths incorrectly) you need to refer to your type using its fully qualified name, namely my_namespace::string. By doing this you avoid any naming clashes and are guaranteed to get a compile error if you don't include the correct header file (unless there's actually exists another class called my_namespace::string that is not yours). There are other ways to avoid these clashes (such as using my_namespace::string) but I'd rather be explicit about the types I'm using. This solution is costly however because it probably needs change all over your code base (changing all strings to my_namespace::string).
A somewhat less cumbersome alternative would be to change the name of the header String.h to something like MyString.h. This would quickly introduce compile errors but requires changing all your includes from #include "String.h" into#include "MyString.h"` (Should be much less effort compared to the first option).
I cannot think of any other way that requires less effort as of now. Since you were looking for a solution that would work in all similar scenarios I'd go with the namespaces if I were you and solve the problem once and for all. This would prevent any other existing/future naming clashes that may be in you code.

How and where to define pre-processor directives such that they are accessible wherever we want in the project?

The intention here is that when the program starts, a particular function will read a configuration file and set some #defines. In other parts of this project, these preprocessor directives will decide what code to execute and what not.
Example:
A file X contains:
#define WHAT 0
A file Y contains:
#if (WHAT)
// Do this
How and where should these types of #defines be organized so that they are accessible where they should be without creating a mess?
Preprocessor directives are resolved when the program is compiled, not when it starts, so what you're asking for can't be done.
You'll need a runtime mechanism to make this work, but that doesn't guarantee code exclusion from the compiled binary.
The intention here is that when the program starts, a particular
function will read a configuration file and set some #defines. In
other parts of this project, these preprocessor directives will decide
what code to execute and what not.
As the other answer has said, this is not possible as the preprocessor directives like #define are consumed by the compilers pre-processors. What your executable binaries actually see is the compiled modified source which remains the same irrespective of every time you run with a different file that you open. Moreover, there is no concept like loading a configuration file and changing the run time as, C++ is a compiled language and not an interpreted.
What actually is possible is to
load the configuration file (preferable in a stand format)
Parse it with publicly available libraries for standard format or write your own parser.
Use STL objects like map to create a mapping between the configuration key and value
Place the STL in some namespace so as not to pollute the global namespace and make it extern. Ensure that an extern declaration is present in a header file and the variable is defined in a .cpp file so that the variable can be accesses from a translation unit different from where it was defined.
Consume the mapped configuration anywhere within your program.

What MSVC++ 2008 Express Editon compiler does and doesn't

I've been wondering if the msvc++ 2008 compiler takes care of multiple header includes of the same file, considering this example:
main.cpp
#include "header.h"
#include "header.h"
Will the compiler include this file multiple times or just one? (I'm aware I can use the #ifndef "trick" to prevent this from happening)
Also, if I include "header.h" which contains 10 functions, but I only call or use 2, will it still include all 10 or just the 2 I need and all of their needs?
#include is basically a synonym for "copy-and-paste". If you do identical #includes, the contents of that header file will be copy-and-pasted twice, sequentially.
As to your second question, it doesn't really make sense. #includes are executed by the preprocessor, which runs before the compiler and the linker. The preprocessor doesn't know or care what the content of the header file is, it simply copy-and-pastes it in. The linker may be able to eliminate unnecessary functions, but that's completely independent of the preprocessor.
No, the compiler (or, more accurately, the pre-processor) doesn't take care of this "automatically". Not in Visual C++ 2008, or in any other version. And you really wouldn't want it to.
There are two standard ways of going about this. You should choose one of them.
The first is known as include guards. That's the "#ifndef trick" you mentioned in your question. But it's certainly not a "trick". It's the standard idiom for handling this situation when writing C++ code, and any other programmer who looks at your source file will almost certainly expect to see include guards in there somewhere.
The other takes advantage of a VC++ feature (one that's also found its way into several other C++ toolkits) to do essentially the same thing in a way that's somewhat easier to type. By including the line #pragma once at the top of your header file, you instruct the pre-processor to only include the header file once per translation unit. This has some other advantages over include guards, but they're not particularly relevant here.
As for your second question, the linker will take care of "optimizing" out functions that you never call in your code. But this is the last phase of compilation, and has nothing to do with #include, which is handled by the pre-processor, as I mentioned above.
The MSVC 20xx preprocessor (not the compiler -- the compiler never sees preprocessor directives) does not in any sense "take care of" multiple #includes of the same file. If a file is #included twice, the preprocessor obeys the #includes and includes the file two times. (Just imagine the chaos if the preprocessor even thought about trying to correct your source file's "bad" #include behavior.)
Because the preprocessor is so meticulous and careful about following your instructions, each #included file must protect itself from being #included twice. That protection is what we see when we find lines like these at the top of a header file:
#ifndef I_WAS_ALREADY_INCLUDED // if not defined, continue with include
#define I_WAS_ALREADY_INCLUDED // but make sure I'm not included again
[ header-file real contents ]
#endif // I_WAS_ALREADY_INCLUDED
When you write a header file, you must always be sure to protect it in this way.
Why do you care? It doesn't add really much burden on the compiler because the compiler conditionally (with #ifdefs, for example) excludes code it doesn't need to compile.
Preprocessor will include 2 times these headers. Thats why guards in header files are required.
As far as I know the linker is most cases will remove code (functions) that are newer used to reduce executable file size.