To know precompiled header is used - visual-c++

I have a.cpp that is used in several projects. Some of them are using precompiled headers, others - not. Depending on this I must add or remove line :
#include <stdafx.h>
Is it possible somehow play with #define to make this in automatic way?
UPD.
I can't use empty stdafx.h file in case when precompiled headers are not used because I got strange behaviour in my situation when a.cpp is placed in project sub directory libA. In this case projects that use precompiled header must have line:
#include <stdafx.h>
and projects that are not using PCH must have line:
#include "..\stdafx.h"
Wice versa is not working. Actually I still can't understand this behavior. I would like to have a.cpp file identical for all projects.

You can include a preprocessor define in the project settings for those projects which use precompiled headers, and then base the inclusion of stdafx.h based on its existence. Using your example, libA's C++ settings should include /D USE_PCH, and then in a.cpp:
#ifdef USE_PCH
#include <stdafx.h>
#else
#include "../stdafx.h"
#endif
To ensure that the define and precompiled header settings remain in sync, you could create a property sheet with both settings, and link it to your project. However, if it were me, I would just disable precompiled headers for the files which are shared between libraries. Unless the PCH is very large, and the number of shared sources also very large, the compilation time savings likely won't outweigh the maintenance of this approach.

Related

AC_CHECK_HEADERS: define a macro before testing for header presence

A particular C++ logging library called spdlog that I use in my project has a broken package on CentOS (the platform I'm trying to compile on) where the header file will only compile if SPDLOG_FMT_EXTERNAL is defined before any of its files are included. [And this will not be fixed.]
I am trying to find a way to use autoconf directives to test for the presence of this header file - previously I used a homegrown macro that compiles a program which uses that, but its speed latency is unacceptably slow so I am trying to replace it.
Here is the relevant snippet of my configure.ac:
dnl check for libfmt is done earlier...
AC_CHECK_HEADERS([spdlog/spdlog.h], [have_spdlog="yes"], [have_spdlog="no"])
if test x$have_spdlog = xyes; then
LDFLAGS="$LDFLAGS -lspdlog -lfmt";
else
AC_MSG_ERROR([spdlog is required for logging support but is missing.])
fi
The header file spdlog/spdlog.h exists, but Autoconf deems it as not usable because it won't compile by itself.
AC_CHECK_HEADERS has a parameter I can specify include files required to include that particular header file. I can use that to specify the #define macro before the file is included.
Is there an easier way to just directly specify a macro without creating a new header file?
After some experimenting, I learned that the fourth parameter to AC_CHECK_HEADERS accepts macros as well - anything that can be used in a C/C++ preprocessor works as well, such as #ifdef, #endif and so on. It is not restricted to only #include directives.
AC_CHECK_HEADERS([spdlog/spdlog.h], [have_spdlog="yes"], [have_spdlog="no"], [
#define SPDLOG_FMT_EXTERNAL
])

What is the purpose of features.h header?

What is the purpose of the features.h header? Why and when can it be used in my code?
Does it define source features supported by the system?
Or does it define some additional things which must be defined depending on other defines?
The features.h header file provides various macro definitions that indicate standard conformance to other header files, i.e. which features (hence the name) should be turned on or off depending on which standard the user wishes to use.
Most C/C++ compilers have command line options to handle standards conformance. Let's take GCC as an example: when you pass the -std=gnu9x option, you ask for the GNU dialect of the C99 standard. The features.h header makes sure that all other headers that include it will turn exactly those features on or off that are needed to support this particular dialect. This is achieved by #define -ing or #undef - ing some "intermediate" macros.
As a bonus, features.h also provides the glibc version information macros as well, and various other bits & bobs.
I have grepped POSIX 7 as explained at: https://unix.stackexchange.com/questions/340285/install-the-latest-posix-man-pages/483198#483198 and there are no hits for features.h, so it must be a glibc extension only.
In glibc 2.28, it is present at include/features.h.
One of the interesting things that it defines are version macros:
#include <stdio.h>
#include <features.h>
int main(void) {
printf("__GLIBC__ %u\n", __GLIBC__);
printf("__GLIBC_MINOR__ %u\n", __GLIBC_MINOR__);
return 0;
}
Ubuntu 16.04, which has glibc 2.23, this outputs:
__GLIBC__ 2
__GLIBC_MINOR__ 23
See also: Check glibc version for a particular gcc compiler
Also, this header seems to get included in most / all glibc headers, which might allow you to check if glibc is being used: How to tell if glibc is used but TODO I couldn't find a documentation for that.
From features.h File Reference
Defines on whether to include algorithm variants.
Less variants reduce executable size and compile time. This file is a GNU parallel extension to the Standard C++ Library.
So this file will include some algorithm listed in the reference page.
In general if you need to use any of the variables or functions defined in a header file, you need to include it in your program. This rule is valid for features.h also. You can see a URL for features.h for your reference below:
http://repo-genesis3.cbi.utsa.edu/crossref/heccer/usr/include/features.h.html

ensure config.h is included once

I have a library project that I'm working on porting to using the autotools suite in Linux. I'm quite new to autotools (this week). I've learned the basics of its operation. I have a question about how to keep the contents of config.h from being redefined.
I'm surprised to find that the generated config.h file doesn't either, 1) wrap each macro in a #ifndef or, 2) that the entire file isn't wrapped in the standard #ifndef CONFIG_H.
As I've alluded, this code is built on Windows and Linux. Thus there are several uses of a macro, _linux (I'm not saying that's the best name, but it's in use everywhere) to bring in elements to classes which exist in Linux only. Thus, this will happen
header.h
#ifndef HEADER1_H
#define HEADER1_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
source.cxx
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "header.h" // oops, preprocessor gets excited because of redefs
One simple solution is I do that standard unique wrap in config.h.in after the file is generated. However, I was wondering, is there a better way of handling this? I can't be the first to encounter this and there might even be a means of handling it in configure.ac but being a complete neophyte in this, I don't know what to even search for.
The way I do this is indeed creating a wrapper file (which I usually call global.h) that reads like this.
#ifndef MY_PROJECT_GLOBAL_H
#define MY_PROJECT_GLOBAL_H
#include <config.h>
/* Maybe other global definitions… */
#endif
Note that the recommended way to #include the config.h file is via <config.h> not "config.h" so it works better with VPATH builds.
Then, all the source files in my project #include this global.h header as their very first #include and don't care about config.h. A header file should never #include config.h since this would lead to bad name conflicts. Actually, if you stick to this guideline, your code should also work without #include guards in the configuration header.
Update regarding OP's comment
Or: How to use configuration results in headers?
If your headers need to declare different things depending on the results of the configure script, you have a number of options, none of which is perfect.
For internal headers, there is no problem. They simply rely on the macros being #defined without #includeing anything. This works if – as is recommended – all source files #include (maybe indirectly as shown above) config.h before any other header.
If the headers are to be installed publicly, this is not such a great solution. For those of your users that use Autoconf, it wouldn't be that bad, although even those would have to remember what checks to place in their configure.ac files. For users who don't use Autoconf, it will be pretty bad. If you only have a few switches (such as Glibc's fature test macros), it is okay to ask your users to #define them before #includeing your headers but if you need many, this is not a real option. Not to mention that you'll expose a lot of implementation details to your users that way.
If all you need to do is branch depending on the platform you are building for, you could probe some of the pre-defined macros like __linux or _WIN32. There is the Boost.Predef library that aims to make these check a little more convenient by providing a higher-level abstraction. The library works with C and C++ alike but, of course, it adds an additional dependency to your project.
Finally, you could make a version of your config.h that uses a macro prefix specific to your project. There is a contribution in the Autoconf macro archive that does exactly that for you. A minimal example could look like this.
AC_PREREQ([2.69])
AC_INIT([example-project], [1.0], [bugs#example.org])
AC_CONFIG_SRCDIR([example.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AX_PREFIX_CONFIG_H([public_config.h], [EXAMPLE_PROJECT], [config.h])
AC_PROG_CC
AC_OUTPUT
Save this as configure.ac, download ax_prefix_config_h.m4 from the Autoconf macro archive and place it in the sub-directory m4 and then run autoreconf && ./configure. It will create the normal config.h and in addition public_config.h where in the latter file, all macros are prefixed with EXAMPLE_PROJECT_. The file public_config.h (which also has #include guards by the way) can be installed and #included in your project's public header files if need be.
With autoheader, you can add header and trailer boiler plate code to config.h
https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/Autoheader-Macros.html
For example, add the following to your configure.ac
#
# Add include guards to config.h
#
AH_TOP([
#ifndef __CONFIG_H_INCLUDE_GUARD
#define __CONFIG_H_INCLUDE_GUARD
])
AH_BOTTOM([
#endif
])

Is there a way to tell whether code is now being compiled as part of a PCH?

I need to branch a certain statement in a precompiled-header .h file, based on whether the .h is now being used to create the PCH (i.e., included in a cpp compiled with /Yc), or now included just to use the PCH (i.e., included in a cpp compiled with /Yu).
In other words, I'm looking for something like -
#ifdef NOW_CREATING_THE_PCH
#import yadayada_with_option_a
#else
#import yadayada_with_option_b
#endif
...and can't find anything.
Any ideas would be appreciated!
Thanks,
-Ofek
[Edit:] The reason I need this is that I use Incredibuild, and have started getting this warning. Per the FAQ suggestion, I wish to #import with no_implementation during PCH creation, and with implementation_only during PCH usage.
You can specifically change the configuration (in Visual Studio) of stdafx.cpp (or whatever source file you have that gets compiled with /Yc) to define the symbol NOW_CREATING_THE_PCH, leaving the symbol undefined for the rest of the source files (which get compiled with /Yu).
That's not something you get out-of-the-box, but if you need to do it just for one project (or a few), it's not a problem.
While this is not a direct answer to your question, the simplest way of solving this problem is to use the #import statement with no_implementation in the header file which is used to generate the precompiled header (usually StdAfx.h) and re-#import the header file into the source file that is used to trigger the generation of the pch with the parameter implementation_only. That way the implementation of the wrapper functions are being defined, but only in one place.

Avoid adding "include paths" for headers that are not directly #included

Suppose I have two vc++ project, proj_a and proj_b
proj_a contains a header file a.h
proj_b has dependency on proj_a. It contains file b.h that does #include <a.h>. I add a.h's directory in the "additional include directories" in its project settings to build it.
Now say, I have 100 more projects, whose files #include <b.h>. Only adding b.h's directory in the "additional" column does not work. I have to include the path of a.h too.. How to avoid this?
Simply put, how to keep the number of include paths for any vc++ project equal to the number of direct dependencies?
I don't have the option to set vc++ environment settings to globally include a.h's path since everybody else in my team will have to import my settings and things will turn messier..
I don't have enough idea but is there a way to achieve this through precompiled headers? I think they are project-specific and should not be shared across projects?
Dependencies are transitive. That is, since b.h includes a.h, anything that includes b.h will need to be able to find a.h. The only thing you can do about it is to somehow remove the dependency of b.h on a.h, perhaps by using a forward declaration for the types in a.h instead of relying on the full definition of the types from the header file.
If that's not an option, at least you can ease the pain of include paths that are duplicated across projects by using Visual C++'s "property sheet" feature. These let you define shared build settings in a single file which can be inherited by an arbitrary number of projects. This will also solve the problem of sharing these settings with your collaborators.
Thanks for the answer Nick. I could have used relative path to a.h inside b.h and save having additional-include-directories inside proj_b and rest of 100 projects.
Actually, in my case there are multiple flavors of proj_a: 'proj_a1, proj_a2, etc. each having a separate a.h. The other 100 projects decide on which flavor to include by having appropriate additional-include-directory in their settings. This was an issue, whenever we need to upgrade proj_a flavors, all include-dirs will need to be changed.
I got across this problem by removing all include-dirs and instead defining PROJ_A1, PROJ_A2, etc. in the rest of projects. b.h does not #include a.h anymore, it include a a_redirector.h header file instead (with relative path). Inside a_redirector.h, we have all #ifdef PROJ_A1, #ifdef PROJ_A2, etc. that looks at the include a particular a.h file (relative paths here too) depending on what has been defined.
Now, whenever we need to upgrade proj_a flavors, I need only to modify a_redirector.h only to point to all new a.h thereby having a single point of control as compared to the earlier architecture.

Resources