stdafx.h

stdafx.h

I am writing a portable program for use on Windows and Linux.

I would like to use:

#if defined(__linux)
#include ...
#else
#include "stdafx.h"
#include ...
#endif

However, on Windows, when using pre-compiled headers I receive this warning

\src\foo.cpp(24): warning #2727: could not create precompiled header file: no #include of stdafx.h before non-preprocessor directive

Other than adding a header to the Linux build is their a way around this?

Jim Dempsey

www.quickthreadprogramming.com
10 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

How about using __WIN32 as the qualifying keyword rather than __linux. It should work on both Linux and Windows . For example, something like:

#ifdef _WIN32
#include
#else
#include
#endif // _WIN32

Would the above work for you?

--mark

>>I am writing a portable program for use on Windows and Linux. I would like to use:
>>
>>#if defined(__linux)
>>#include ...
>>#else
>>#include "stdafx.h"
>>#include ...
>>#endif
>>
>>However, on Windows, when using pre-compiled headers I receive this warning
>>
>>\src\foo.cpp(24): warning #2727: could not create precompiled header file: no #include of stdafx.h before non-preprocessor directive
>>
>>Other than adding a header to the Linux build is their a way around this?
.
Hi everybody,
.
I had a similar issue about 2.5 years ago. First of all, I tried Mark's way and it didn't work. By some unexplained reason Microsoft C/C++ compiler doesn't allow to #ifdef-#else-#endif the 'stdafx.h' file. My solution is as follows:
.
- I renamed 'stdafx.h' / 'stdafx.cpp' to 'stdphf.h' / 'stdphf.cpp' where 'stdphf' stands for 'standard project header file'. That was done in order to remove any dependencies on Microsoft related names, definitions, etc.
.
- Updated all VS project files, GCC-like make files, etc.
.
- A content of the 'stdphf.h' looks like:
.
///////////////////////////////////////////////////////////////////////////////
// Stdphf.h
// Platform Headers Support Section
.
#if defined ( _WIN32_MSC )....................// Windows Desktop Platforms
...
#endif
.
#if defined ( _WIN32CE_MSC )..................// Windows CE Platforms
. ...
#endif
.
#if defined ( _WIN32_MGW )....................// Windows Desktop Platforms with MinGW
//...
#endif
.
#if defined ( _WIN32_BCC )....................// Windows Desktop Platforms with Borland C++
//...
#endif
.
#if defined ( _COS16_TCC )....................// Compact 16-bit Platforms with Turbo C++
//...
#endif
.
#if defined ( _WIN32_ICC )....................// Windows Desktop Platforms with Intel C++
//...
#endif
.
///////////////////////////////////////////////////////////////////////////////
.
My solution perfectly works with five C/C++ compilers and more than 4 platforms.
.
Best regards,
Sergey

>>...Other than adding a header to the Linux build is their a way around this?
.
As you can see I decided to keep both files, renamed to stdphf.h and stdphf.cpp, for all cases ( different C/C++ compilers and platforms ) but stdphf.h has a more advanced content.

The problem, ... well I should say annoyance, is the Windows compilation requires stdafx.h (optionally stdafx.cpp) for precompiled headers. I haven't experimented on Windows changing the file name property on/next to Using Pre-Compiled Headers.

The simple solution is to have the Linux build have a different stdafx.h file, this can easily be done by manipulating the INCLUDE path. However, this now means you have multiple files with same names in different places and this makes maintenance problem prone.

For now, I will resort to using a different stdafx.h for the Linux build.

FWIW, I believe a better soulution would have been:

When a xxx.cpp file is configured to use pre-compiled header of the name stdafx.h (or other), then the source file is pre-pended with "#include stdafx.h\n" (or other chosen name). IOW move the required #include from the source file and insert it via a compiler option.

Jim Dempsey

www.quickthreadprogramming.com

>>The simple solution is to have the Linux build have a different stdafx.h file, this can easily be done by manipulating the INCLUDE path.
>>However, this now means you have multiple files with same names in different places and this makes maintenance problem prone.

This is why I decided to use a "universal stdphf.h" approach.

>>For now, I will resort to using a different stdafx.h for the Linux build.

I think in case of just two platforms it looks good.

>>...is the Windows compilation requires stdafx.h (optionally stdafx.cpp) for precompiled headers.

You could disable it in a project settings:

'Project' -> 'Configuration Properties' -> 'C/C++' -> 'Precompiled Headers' -> and change 'Create/Use Precompiled Header' to 'Not Using Precompiled Headers'

For a small project it works well. For a middle size project ( ~70,000 C/C++ code lines ) the compilation time increases from ~45 seconds to 25 minutes when precompiled headers are not used.

This issue could be resolved in a reasonable way by the compiler writers permitting:

0 or 1 #if preprocessor directive prior to #include "stdafx.h" (when stdafx.h used)
no #include prior to #include "stdafx.h" (when stdafx.h used)

This would permit #ifdef _WIN32 to immediately preceed #include "stdafx.h"

Ah, sadly, this would eliminate an opportunity for MS to annoy non-Windows users.

Jim Dempsey

www.quickthreadprogramming.com

In general, it isn't a problem of some pre-compiled header files used in some software development environment. It is more complex and I would say as better as possible software project organization is needed.

If somebody will visit 10 software companies which claim our software is portable that person will say 'I saw 10 different solutions!' and a common problem all these companies solved was the same:

** Software must be designed and implemented for different platforms using different software development tools **

Consider:

- a software should work on platforms:

Windows Desktop
Windows CE
Windows Mobile ( Pocket PC / Smartphone / etc )
Windows Desktop 64-bit
Linux Desktop
Android

- built with:

Intel C++ compiler
Microsoft C++ compiler
MinGW C++ compiler
Borland C++ compiler
Turbo C++ compiler

- using IDEs:

VS 20xx ( 2005, 2008, 2010, etc )
Eclipse ( for C++ and Java )

In that case a significant isolation is needed in order to make the software as portable as possible. This is because "bad-for-portability" external dependencies must not be used directly, or avoided at all, and must be wrapped in a portable way before they used in codes. What are these dependencies?

For example:

OS specific APIs ( Win32 API, Linux system API, DirectX API, etc )
CPU dependent ( Intel, AMD, ARM, SHx, MIPS, SSE, SSE2, etc )
3rd party libraries ( MFC, ATL, IPP, etc )
Version Control Systems ( Microsoft VSS, Subversion, Star Team, Perforce, etc )

Even if Open Standards APIs are used, like OpenGL, OpenMP, etc, they don't provide 100% portability.

>>...sadly, this would eliminate an opportunity for MS to annoy non-Windows users...

As a matter of fact many Windows software developers are on Microsoft's Win32 API and VS "hooks". Microsoft has done that deliberately.

[ADDED] I really miss the 'Preview' button of the ISN!

Kommentar hinterlassen

Bitte anmelden, um einen Kommentar hinzuzufügen. Sie sind noch nicht Mitglied? Jetzt teilnehmen