How to detect OS without directive ifdef? - c++

I have to reset system date and time either on Linux, or on Windows.
How do I check OS without using ifdef, or if defined?

With CMake, you can conditionally add files to a target by using generator expressions. With that, you can isolate any platform-specific code in files, and use them in your build specification as follows.
add_executable(reset-time
$<$<PLATFORM_ID:Darwin>:resettime-macos.cpp>
$<$<PLATFORM_ID:Linux>:resettime-linux.cpp>
$<$<PLATFORM_ID:Windows>:resettime-windows.cpp>)
And as #eeroika pointed out in the comments, a good alternative is
add_executable(reset-time
resettime-$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>.cpp)
as it requires not adjustment (of the CMakeLists.txt) when porting your project to a new system and you can catch a missing implementation file earlier, i.e., before linking.

You could set a global macro definition to the compiler based on which operating system you are compiling for. For example -D IS_WINDOWS=1. You could then use #if IS_WINDOWS instead of #ifdef. I don't know why this would be useful but it achieves what you asked.

Related

CMake doesn't link the actual object to the resulting dll [duplicate]

How do I define a preprocessor variable through CMake?
The equivalent code would be #define foo.
For a long time, CMake had the add_definitions command for this purpose. However, recently the command has been superseded by a more fine grained approach (separate commands for compile definitions, include directories, and compiler options).
An example using the new add_compile_definitions:
add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION})
add_compile_definitions(WITH_OPENCV2)
Or:
add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)
The good part about this is that it circumvents the shabby trickery CMake has in place for add_definitions. CMake is such a shabby system, but they are finally finding some sanity.
Find more explanation on which commands to use for compiler flags here: https://cmake.org/cmake/help/latest/command/add_definitions.html
Likewise, you can do this per-target as explained in Jim Hunziker's answer.
To do this for a specific target, you can do the following:
target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)
You should do this if you have more than one target that you're building and you don't want them all to use the same flags. Also see the official documentation on target_compile_definitions.
The other solutions proposed on this page are useful for some versions of Cmake > 3.3.2. Here the solution for the version I am using (i.e., 3.3.2). Check the version of your Cmake by using $ cmake --version and pick the solution that fits your needs. The cmake documentation can be found on the official page.
With CMake version 3.3.2, in order to create
#define foo
I needed to use:
add_definitions(-Dfoo) # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)
and, in order to have a preprocessor macro definition like this other one:
#define foo=5
the line is so modified:
add_definitions(-Dfoo=5) # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)
PLEASE NOTE (as #squareskittles suggests in one of the comment): "if you are using CMake 3.3.2, you have to use add_definitions() or target_compile_definitions(). The more modern command, add_compile_definitions(), was not added until CMake 3.12."
1.) target_compile_definitions
If you are using CMake 3.X your first choice for adding a preprocessor macro should be target_compile_definitions.
The reason you should prefer this approach over any other approach is because it granularity is target based. IE the macro will only be added to your exe/library.
Here is a common example:
if (WIN32)
target_compile_definitions(my_lib PRIVATE
# Prevents Windows.h from adding unnecessary includes
WIN32_LEAN_AND_MEAN
# Prevents Windows.h from defining min/max as macros
NOMINMAX
)
endif()
2.) add_compile_definitions
New in version 3.12.
Find more explanation on which commands to use for compiler flags here: https://cmake.org/cmake/help/latest/command/add_definitions.html
add_compile_definitions applies macros to any targets that are defined after the call.
Here is the same logic as above with add_compile_definitions.
add_compile_definitions(WIN32_LEAN_AND_MEAN NOMINMAX)
add_library(my_lib)
If you use this approach be careful if you are the top level project.
Otherwise if users consume your library using add_subdirectory they may have issues.
3.) The other less recommended ways
These approaches really aren't recommended anymore. Due to not being modular, not scaling well, not supporting generator expressions, etc.
add_definitions
CMAKE_LANG_FLAGS
Why is target_compile_definitions better/preferred?
It's much more clear to readers of your CMake code how it works.
Allows usage of PRIVATE/PUBLIC/INTERFACE if needed. Which can make life easier for consumers of your library.
It's much more modular.
Applying pre-processor flags (Or any compiler flag) globally can create hidden dependencies in your build.
Essentially think of add_compile_definitions as globals in C/C++. Sometimes you need them, but be careful.
i'd like to recommend use target_*** operations instead of add_*** operations when your solution include many projects.
here is an example where you can pass values from CMAKE to C++ code. Say, you want to pass:
flag, here: BOOST ("true" or "false")
software version string (e.g.: "1.0.0")
I recommend to pass them as strings.
So, when you build software with CMAKE, you can pass parameters like for example if it was built using boost library, software version pulled from CMAKE variable (so that you change that number only in one place)
See below.
In CMakeLists.txt:
add_compile_definitions(
BOOST="${BOOST}"
Software_VERSION="${PROJECT_VERSION}"
)
In your .cpp code:
std::cout << "Software version is: " << Software_VERSION << " BOOST: " << BOOST << "\n";
Hope this helps. Regards.

Custom compilation flag to enable specific feature

I have a Qt project which requires a library (gphoto2) to enable some features that are not essential. I'd like to add some sort of configuration option to my qmake or make call to enable features using this library, so I can compile without it being installed.
What is the best way to configure something like this?
I guess I need some way to add a define based on a compiler parameter, which I can query in my code using #ifdef ...
I assume you use make (without qmake). It is reasonable and quite easy to use GNU make (alone) on Qt projects. You could use some other build automation tool like ninja.
Then you could decide to enable that Gphoto feature by compiling your code with -DWITH_GPHOTO and using #if WITH_GPHOTO in your C++ code.
You would compile by adding
CXXFLAGS+= -DWITH_GPHOTO
in your Makefile
I won't call that a "custom compiler flag" (e.g. like GCC plugins can provide) but a preprocessor flag. It is pretty standard practice.
Maybe you also want to pass such flags to moc. Then your Makefile is running moc thru some rule and command, which you could tailor too.
BTW, you might consider GNU autoconf or some other Makefile generator like cmake. I don't think you should spend too much time on these...
PS. I don't know how that idea translates into qmake and leave you to find out.
Assuming, you are using qmake, you can add a preprocessor definition depending on the existence of a file or an environment variable.
You could add a qmake project for compiling your external library and place it relative to your own project by default.
LIBGPHOTO2_PATH = $$getenv(LIBGPHOTO2PATH)
isEmpty(LIBGPHOTO2_PATH): LIBGPHOTO2_PATH = ../../libgphoto2
exists($$LIBGPHOTO2_PATH/libgphoto2.pri): include($$LIBGPHOTO2_PATH/libgphoto2.pri)
In libgphoto2.pri you add a preprocessor definition to indicate the presence of libgphoto2, add include and linker paths etc.:
DEFINES += WITH_LIBGPHOTO2
In the code of your dependent project, you check for the presence using #ifdef.
Instead of creating a qmake-project to compile, you could also check for the presence of the compiled library at a given path and set values directly (I don't know how libgphoto compiles, so I assume a default directory structure with include/, lib/ etc):
LIBGPHOTO2_PATH=$$getenv(LIBGPHOTO2PATH)
isEmpty(LIBGPHOTO2_PATH): LIBGPHOTO2_PATH = ../../libgphoto2
exists($$LIBGPHOTO2_PATH/include) {
DEFINES += WITH_LIBGPHOTO2
INCLUDEPATH += $$LIBGPHOTO2_PATH/include
LIBS += -L$$LIBGPHOTO2_PATH/lib -lgphoto2
}
You should however consider to move to something more modern like qbs, which is a lot faster, more flexible and easier to read.

Correct installation of config.h for shared library using autotools

I am converting a C++ program which uses the autotools build system to use a shared library, introducing the use of libtool. Most of the program functionality is being placed in the shared library, which is loaded by the main program, so that the common code can be accessed by other programs in future.
Throughout the program and library sources the autoheader generated config.h is used with the usual macro:
#if HAVE_CONFIG_H
# include <config.h>
#endif
In configure.ac I use the macro to generate it:
AC_CONFIG_HEADERS([config.h])
My question is, do I need to install config.h for others to be able to use my library, and if so, what is the appropriate way to do it, and should it be renamed to avoid conflicts etc?
The most information I have found on this is here:
http://www.openismus.com/documents/linux/building_libraries/building_libraries#installingheaders
But this is hardly an official source.
Never ever install autoheader's config.h.
The last thing the users of your library need is interference from the macros leaking out of your config.h. Your library may have HAVE_FOOBAR, but my software might be compiled in a way that foobar is disabled, so that HAVE_FOOBAR will break my compilation.
The AX_PREFIX_CONFIG macro from the archive is a workaround, where everything gets prefixed.
A better approach is to create a template file (e.g. blargconfig.h.in) with lines like:
typedef #BLARG_TYPE# blarg_int_t;
#BLARG_RANDOM_INCLUDE#
And then AC_SUBST() those variables in configure.ac:
AC_SUBST(BLARG_TYPE, ["unsigned short"])
AC_SUBST(BLARG_RANDOM_INCLUDE, ["#include <somerandomheader.h>"])
Then list it as an output file:
AC_CONFIG_FILES([Makefile
src/Makefile
...
include/blargconfig.h])
The .h file should be listed with nodist_include_HEADERS; the .h.in file will be automatically distributed because it's listed in AC_CONFIG_FILES.
Destination for such files is commonly $libdir/packagename/include. See GLib for example, although they generate glibconfig.h without a template (by writing the whole creation code inline in configure.ac, as the autobook suggests). I find this approach less maintainable than using AC_SUBST, but it's more flexible.
Of course, to help the compiler find the platform-dependent header you'll probably also want to write a pkgconfig script, like GLib does.
You will need to install config.h if it affects the interface. In practical terms, if the #define's are required by the header(s), not just the .cc implementation / compilation units.
If config.h is a problem, you can specify another name in the AC_CONFIG_HEADERS macro. e.g., AC_CONFIG_HEADERS([foo_config.h]).
The easiest way to install the header, assuming automake, is with:
nodist_include_HEADERS = foo_config.h
in the top-level Makefile.am. the nodist prefix tells automake that foo_config.h is generated rather than distributed with the package.
If not using automake, install foo_config.h in $includedir. $exec_prefix/include is arguably a more correct location for a generated header, but in practice the former location is fine.
I avoid using config.h, by passing relevant definitions in CPPFLAGS or foo_CPPFLAGS along with AC_SUBST to Makefile.am for source builds, or AC_SUBST to foo.h.in to generate headers at configure-time. A lot of config.h is test-generated noise. It requires more infrastructure, but it's what I prefer. I wouldn't recommend this approach unless you're comfortable with the autotools.

Include all of a template library in a file

Off late I have had too use some template libraries like Boost and Thrust (for CUDA) in some of my coding work.
For using a certain feature of the Boost library, one has to include the appropriate header.e.g. for boost::lexical_cast I have to use boost/lexical_cast.hpp. It is tiring to keep including the appropriate header for every new feature of Boost / Thrust which I use for my projects.
Is there any "shortcut" to tell the pre-processor to include all the header files stored under the boost library, so that I need not bother about which header file to include?
I am using GCC under Ubuntu.
You don't want that. You want to include as little as possible. Compile times are abysmal in C++ as it is. Start to include everything everywhere and it is going to get worse even.
I have been working in a project where compilation on a decent single core CPU of the time took 50mins, linking 5-10mins. This hurts big time, if you're doing template stuff deep down in the foundations.
Boost comes with a bunch of stuff (like the MPL) that stretches the compiler to its utmost limits. It would be insane to include this stuff everywhere (except for a five-cpp-files kind of project).
You could simply make a mother-of-all header file like so:
for i in $(find /usr/include/boost/); do echo "#include <"${i/"/usr/include/"/}">"; done > master_header.hpp
Now you can add that and use precompiled headers (you may need an overnight compilation to make the PCH). You should also pass -Wl,-as-needed to the linker to avoid including unneeded libraries.
As #sbi says, this isn't advisable in the least, but since you asked... sometimes the best remedy against finding something "tiresome" is to see how much worse it could be!

How should I detect unnecessary #include files in a large C++ project?

I am working on a large C++ project in Visual Studio 2008, and there are a lot of files with unnecessary #include directives. Sometimes the #includes are just artifacts and everything will compile fine with them removed, and in other cases classes could be forward declared and the #include could be moved to the .cpp file. Are there any good tools for detecting both of these cases?
While it won't reveal unneeded include files, Visual studio has a setting /showIncludes (right click on a .cpp file, Properties->C/C++->Advanced) that will output a tree of all included files at compile time. This can help in identifying files that shouldn't need to be included.
You can also take a look at the pimpl idiom to let you get away with fewer header file dependencies to make it easier to see the cruft that you can remove.
PC Lint works quite well for this, and it finds all sorts of other goofy problems for you too. It has command line options that can be used to create External Tools in Visual Studio, but I've found that the Visual Lint addin is easier to work with. Even the free version of Visual Lint helps. But give PC-Lint a shot. Configuring it so it doesn't give you too many warnings takes a bit of time, but you'll be amazed at what it turns up.
There's a new Clang-based tool, include-what-you-use, that aims to do this.
!!DISCLAIMER!! I work on a commercial static analysis tool (not PC Lint). !!DISCLAIMER!!
There are several issues with a simple non parsing approach:
1) Overload Sets:
It's possible that an overloaded function has declarations that come from different files. It might be that removing one header file results in a different overload being chosen rather than a compile error! The result will be a silent change in semantics that may be very difficult to track down afterwards.
2) Template specializations:
Similar to the overload example, if you have partial or explicit specializations for a template you want them all to be visible when the template is used. It might be that specializations for the primary template are in different header files. Removing the header with the specialization will not cause a compile error, but may result in undefined behaviour if that specialization would have been selected. (See: Visibility of template specialization of C++ function)
As pointed out by 'msalters', performing a full analysis of the code also allows for analysis of class usage. By checking how a class is used though a specific path of files, it is possible that the definition of the class (and therefore all of its dependnecies) can be removed completely or at least moved to a level closer to the main source in the include tree.
I don't know of any such tools, and I have thought about writing one in the past, but it turns out that this is a difficult problem to solve.
Say your source file includes a.h and b.h; a.h contains #define USE_FEATURE_X and b.h uses #ifdef USE_FEATURE_X. If #include "a.h" is commented out, your file may still compile, but may not do what you expect. Detecting this programatically is non-trivial.
Whatever tool does this would need to know your build environment as well. If a.h looks like:
#if defined( WINNT )
#define USE_FEATURE_X
#endif
Then USE_FEATURE_X is only defined if WINNT is defined, so the tool would need to know what directives are generated by the compiler itself as well as which ones are specified in the compile command rather than in a header file.
Like Timmermans, I'm not familiar with any tools for this. But I have known programmers who wrote a Perl (or Python) script to try commenting out each include line one at a time and then compile each file.
It appears that now Eric Raymond has a tool for this.
Google's cpplint.py has an "include what you use" rule (among many others), but as far as I can tell, no "include only what you use." Even so, it can be useful.
If you're interested in this topic in general, you might want to check out Lakos' Large Scale C++ Software Design. It's a bit dated, but goes into lots of "physical design" issues like finding the absolute minimum of headers that need to be included. I haven't really seen this sort of thing discussed anywhere else.
Give Include Manager a try. It integrates easily in Visual Studio and visualizes your include paths which helps you to find unnecessary stuff.
Internally it uses Graphviz but there are many more cool features. And although it is a commercial product it has a very low price.
You can build an include graph using C/C++ Include File Dependencies Watcher, and find unneeded includes visually.
If your header files generally start with
#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#endif
(as opposed to using #pragma once) you could change that to:
#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#else
#pragma message("Someheader.h superfluously included")
#endif
And since the compiler outputs the name of the cpp file being compiled, that would let you know at least which cpp file is causing the header to be brought in multiple times.
PC-Lint can indeed do this. One easy way to do this is to configure it to detect just unused include files and ignore all other issues. This is pretty straightforward - to enable just message 766 ("Header file not used in module"), just include the options -w0 +e766 on the command line.
The same approach can also be used with related messages such as 964 ("Header file not directly used in module") and 966 ("Indirectly included header file not used in module").
FWIW I wrote about this in more detail in a blog post last week at http://www.riverblade.co.uk/blog.php?archive=2008_09_01_archive.xml#3575027665614976318.
Adding one or both of the following #defines
will exclude often unnecessary header files and
may substantially improve
compile times especially if the code that is not using Windows API functions.
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
See http://support.microsoft.com/kb/166474
If you are looking to remove unnecessary #include files in order to decrease build times, your time and money might be better spent parallelizing your build process using cl.exe /MP, make -j, Xoreax IncrediBuild, distcc/icecream, etc.
Of course, if you already have a parallel build process and you're still trying to speed it up, then by all means clean up your #include directives and remove those unnecessary dependencies.
Start with each include file, and ensure that each include file only includes what is necessary to compile itself. Any include files that are then missing for the C++ files, can be added to the C++ files themselves.
For each include and source file, comment out each include file one at a time and see if it compiles.
It is also a good idea to sort the include files alphabetically, and where this is not possible, add a comment.
If you aren't already, using a precompiled header to include everything that you're not going to change (platform headers, external SDK headers, or static already completed pieces of your project) will make a huge difference in build times.
http://msdn.microsoft.com/en-us/library/szfdksca(VS.71).aspx
Also, although it may be too late for your project, organizing your project into sections and not lumping all local headers to one big main header is a good practice, although it takes a little extra work.
If you would work with Eclipse CDT you could try out http://includator.com to optimize your include structure. However, Includator might not know enough about VC++'s predefined includes and setting up CDT to use VC++ with correct includes is not built into CDT yet.
The latest Jetbrains IDE, CLion, automatically shows (in gray) the includes that are not used in the current file.
It is also possible to have the list of all the unused includes (and also functions, methods, etc...) from the IDE.
Some of the existing answers state that it's hard. That's indeed true, because you need a full compiler to detect the cases in which a forward declaration would be appropriate. You cant parse C++ without knowing what the symbols mean; the grammar is simply too ambiguous for that. You must know whether a certain name names a class (could be forward-declared) or a variable (can't). Also, you need to be namespace-aware.
Maybe a little late, but I once found a WebKit perl script that did just what you wanted. It'll need some adapting I believe (I'm not well versed in perl), but it should do the trick:
http://trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes
(this is an old branch because trunk doesn't have the file anymore)
If there's a particular header that you think isn't needed anymore (say
string.h), you can comment out that include then put this below all the
includes:
#ifdef _STRING_H_
# error string.h is included indirectly
#endif
Of course your interface headers might use a different #define convention
to record their inclusion in CPP memory. Or no convention, in which case
this approach won't work.
Then rebuild. There are three possibilities:
It builds ok. string.h wasn't compile-critical, and the include for it
can be removed.
The #error trips. string.g was included indirectly somehow
You still don't know if string.h is required. If it is required, you
should directly #include it (see below).
You get some other compilation error. string.h was needed and isn't being
included indirectly, so the include was correct to begin with.
Note that depending on indirect inclusion when your .h or .c directly uses
another .h is almost certainly a bug: you are in effect promising that your
code will only require that header as long as some other header you're using
requires it, which probably isn't what you meant.
The caveats mentioned in other answers about headers that modify behavior
rather that declaring things which cause build failures apply here as well.