33

How can one achieve what the following code is trying to do?

#include "dir/*"
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Karl Glaser
  • 829
  • 2
  • 10
  • 17
  • 9
    why would you want to do that? – jalf Jun 17 '10 at 12:40
  • 10
    This is bad. If you can't tell which files from your own project you need to include, you must have some hell of a design. – ereOn Jun 17 '10 at 12:46
  • 6
    I have a folder which contains all the concrete classes of drawable entities in a game. In the main logic file I need to include all of these classes. Currently every time I create a new concrete class (atm each one has it's own .h and .cpp file) I have to add the #include for the logic file, and I was just trying to skip having to do that one line every time. Perhaps I should put all the concrete classes in one file, or use a namespace (but I don't think so), can you suggest any way to improve my design? – Karl Glaser Jun 17 '10 at 13:45
  • If you're editing a file in `dir/` and your text editor saves a temporary/backup file named `dir/somefile.h~`, `dir/#somefile.h#`, or `dir/somefile.h.tmp`, do you want to include that too? – bk1e Jun 17 '10 at 16:00
  • Note that the interpretation of an `#include ""` is really up to the compiler. It may be helpful and interpret `\ ` in paths for you, or even `*` as a wildcard. You just can't rely on that. In practice, MSVC is helpful and translates `/` to the native `\ `; but AFAIK no compiler expands `*`. – MSalters Feb 26 '21 at 12:22

4 Answers4

25

In Bash:

HEADER=all_headers.h
echo "#ifndef __ALL_HEADERS__" > $HEADER
echo "#define __ALL_HEADERS__" >> $HEADER
for file in dir/*.h
do
    echo "#include <$file>" >> $HEADER
done
echo "#endif" >> $HEADER
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    Would you please explain what to do on a Windows machine? – Arman Bimatov Aug 17 '13 at 21:52
  • 2
    @ArmanBimatov Sorry to necro, but the Batch equivalent is basically identical, and the Powershell uses the same idea. Just Google "iterate over all files in directory cmd" (or Powershell at the end instead, if you want that) and replace the `for` loop with that. – Nic Oct 31 '17 at 15:15
  • Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of [C11 §7.1.3 Reserved identifiers](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) says: — _All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use._ — _All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces._ See also [What does double underscore (`__const`) mean in C?](https://stackoverflow.com/a/1449301) – Jonathan Leffler Jun 19 '19 at 23:28
  • 1
    Also, you could use `{ echo "#ifndef ALL_HEADERS_INCLUDED"; echo "…"; for … done; echo "#endif"; } > $HEADER` to do a single output redirection. You can use newlines inside the braces; there must be a semicolon or newline before the closing brace. (See: [How do I redirect the output of an entire shell script within the script itself?](https://stackoverflow.com/questions/314675)) – Jonathan Leffler Jun 19 '19 at 23:32
14

You can't, without running a script beforehand that generates all #include statements.

The preprocessor can only handle one file per #include statement, so it requires an actual #include for every single file you wish to be included in preprocessing.

Jordan Lewis
  • 16,900
  • 4
  • 29
  • 46
13

One way to achieve that is to write a convenience header that includes all the headers you want. Keep in mind that including headers you will not use may unnecessarily increase compilation time.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
12

Look at how Boost does this for, say, utility.hpp.

$ cat /usr/include/boost/utility.hpp
//  Boost utility.hpp header file  -------------------------------------------//
<snip>
#ifndef BOOST_UTILITY_HPP
#define BOOST_UTILITY_HPP

#include <boost/utility/addressof.hpp>
#include <boost/utility/base_from_member.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/checked_delete.hpp>
#include <boost/next_prior.hpp>
#include <boost/noncopyable.hpp>

#endif  // BOOST_UTILITY_HPP

Now you can just use #include <boost/utility.hpp>.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ezpz
  • 11,767
  • 6
  • 38
  • 39
  • Yeah this is the current way I'm doing it. I guess I'll just keep doing it this way because I don't want to get fancy in bash as the other answer suggests. Thanks guys, just seems weird that java can do this with a *. – Karl Glaser Jun 17 '10 at 12:43
  • 3
    @user137790: The fact that Java provides this mechanism is indeed convenient. But `C++` will **never** choose convenience over efficency; and doing this is precisely **not** efficient. It would allow you to save some keystrokes at the cost of having a much longer compilation time. Which one do you think pays more in the long term ? – ereOn Jun 17 '10 at 13:15