3

I am pretty new with C++, and I have a file I have to build both in Linux and Windows.

I was wondering if there was a way I could have different list of #include in the same file for windows and linux, but that somehow I tell it to do so without having to modify the file each time.

Like:

if_Windows
    #include <Include1>
if_Linux
    #include <Include2>

Is it possible to do something like this? How do you do it?

Dzyann
  • 5,062
  • 11
  • 63
  • 95
  • Sometimes it can be worth considering testing other macros than the platform. It can lead to less complex code. – user2672165 Jan 07 '14 at 17:57
  • 1
    @closevoters: this question is **NOT** a duplicate of "how to detect system". detecting the system (analogous to browser sniffing in web development) is only one way to solve this problem. and it's imho absolutely not necessarily the best way, even though it's very common practice -- just like browser sniffing was and perhaps still is common practice. – Cheers and hth. - Alf Jan 07 '14 at 18:15

5 Answers5

2

You could define a macro that you set when you are compiling for windows and Linux.

#define MYPROJECT_CONFIG_WINDOWS_PLATFORM

#if defined(MYPROJECT_CONFIG_WINDOWS_PLATFORM)
    #include <include1>
#elif defined(MYPROJECT_CONFIG_LINUX_PLATFORM)
    #include <include2>
#else
    #error link: no suitable library
#endif

All you then have to do is define MYPROJECT_CONFIG_WINDOWS_PLATFORM when compiling for Window and MYPROJECT_CONFIG_LINUX_PLATFORM when compiling for Linux.

Some IDEs also have pre-set macros for the platform they are compiling for (Like WIN32 for Windows) but you will have to check the documentation for them.

Caesar
  • 9,483
  • 8
  • 40
  • 66
  • 2
    Note: Identifiers of the form `\w*__\w*` and `_[A-Z]\w*` are **reserved to the implementation**. Choose other identifiers than `__Window__` or `__Linux__` or you are in for a world of pain. – Matthieu M. Jan 07 '14 at 17:59
  • I prefer not to use macros that depend on the IDE, since I don't know who will be working on my project on the future and I want to make it as litle IDE/tools dependant as possible. – Dzyann Jan 07 '14 at 18:05
  • As I see it this is next to most dirty approach; in any case it's double-dirty. First the conditional text inclusion (dirty). Then defining the relevant symnbols oneself (dirty). :) – Cheers and hth. - Alf Jan 07 '14 at 18:06
  • @Cheersandhth.-Alf: Actually, it depends how you define said components; it's pretty common to have a single "Config.h" header that defines the appropriate preprocessor guards, and then rely on those guards to switch when necessary. – Matthieu M. Jan 07 '14 at 18:42
  • @MohammedMajeed: I am sorry if the comment was unclear, but since you still have two consecutive underscores in the name, the symbol is still reserved. – Matthieu M. Jan 07 '14 at 18:43
  • @MatthieuM. Edited again, let me know if it is still wrong. – Caesar Jan 07 '14 at 18:48
  • @MohammedMajeed: It is, unfortunately, now you are matching the second regular expressions (starting with `_`). I advise you to follow Boost's strategy for naming macros: ALL_CAPS starting by the project name, followed by the sub-project part, followed by the actual identifier. Here it could be `MYPROJECT_CONFIG_WINDOWS_PLATFORM` for example. (Note: names starting `_[a-z]` are also reserved to the implementation in the global namespace, this applies to preprocessor identifiers since they are not namespaced). – Matthieu M. Jan 08 '14 at 07:18
2

You need to use #ifdef in combination with an appropriate macro for you environment. For example

#ifdef WIN32
 // Windows includes
#elseif __unix__
 // Unix included
#endif

You'll need to check your compiler documentation to see what they define for the appropriate platform.

Sean
  • 60,939
  • 11
  • 97
  • 136
2

Use the #if preprocessor directive:

#if defined(WIN32)
#include <foo_w.h>
#else
#include <foo_l.h>
#endif

Which defines to use for which platform is a bit more complicated and usually your compiler has some documentation on it.

pmr
  • 58,701
  • 10
  • 113
  • 156
0

You need to use the pre-processor.

See http://www.cplusplus.com/doc/tutorial/preprocessor/

Variables things are defined and by using #ifdef etc you can just include the right stuff for the particular platform

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
0

My preferred way is to

#include <myheader.h>

and use the compiler's include path to include headers from different folders on different system.


Another approach is to use platform- and possibly compiler-specific preprocessor symbols to conditionally include different headers, e.g.

#ifdef _WIN32
#    include <myheader.windows.h>
#else
#    include <myheader.nix.h>
#endif

where _WIN32 is defined by the compiler in 32-bit and 64-bit Windows platforms (note that this is not an officfial standard, only a de facto standard).


Finally, third, such conditional text inclusion can be used to let the same file provide different source code on different systems.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • With your first method, you assume that the file names will be the same for both platform. A lot of time that is not the case. – Caesar Jan 07 '14 at 18:15
  • @MohammedMajeed: no, there is no *assumption* that the file names are the same. you are in charge of the file name: you choose it. those system specific headers can in turn include whatever you want. it is never the case that you can't do that. – Cheers and hth. - Alf Jan 07 '14 at 18:18
  • So do you suggest to have a "myheader.h" file, where I have the actual files, and I have 2 different files one for Linux and one for Windows? Or you are just saying to have all the dependencies have the same name for both Linux and Windows, but with different implementations and depending on what folder i tell the compiler to search in, it will build accordingly? – Dzyann Jan 07 '14 at 18:27
  • Sure, if you are writing the headers then you can enforce the names to be the same but if the headers are from a 3rd party then you don't get to choose. Sure, you can edit them but I would not recommend that. Also, giving them the same name can cause a lot of confusion over which is which. You will constantly have to keep checking which one in which folder you are modifying. – Caesar Jan 07 '14 at 18:27
  • @MohammedMajeed: sorry, your comment does not make sense, at all. there is no need to include headers from a third party directly, and it's not advisable to do so. there is no need to edit third party headers, and it's not advisable to do so. there is no need to constantly keep checking which header you're modifying, and it's not advisable to put yuourself in a situation where you have to do that. in short, to repeat, your comment makes **no sense**. it sounds like, "your answer has a lot of foul attributes, like its color, smell, etc.", with no relation to the answer at all. – Cheers and hth. - Alf Jan 07 '14 at 19:00
  • @Dzyann: when you say "file, where I have the actual files", i think maybe you mean "directory" or "folder". yes it's a good idea to define a suitable directory hierarchy. the compiler's include path distingushes directories, not files. – Cheers and hth. - Alf Jan 07 '14 at 19:05
  • @Cheersandhth.-Alf I meant something like Visual Studio does. It has its own .h file that includes in every class you create with the wizard, in that .h they have their own includes. – Dzyann Jan 07 '14 at 19:09
  • @Dzyann: oh. you mean like `stdafx.h`. no i'm not suggesting anything like that. i think that would be a nightmare to maintain. – Cheers and hth. - Alf Jan 07 '14 at 19:11