conditional compliation based on variable into makefile - include

Inside my C/C++ code I would like to include or not a file depending on different compilation.
For the moment I use this:
#ifndef __x86_64__
#include <myLib.h>
#endif
this gives me the possibility of doing whether the platform is 32/64 bit but does not give me enough freedom.
I would like to pass a variable to my makefile like
make includeMyLib=1
and depending on this having something like:
#ifndef includeMyLib
#include <myLib.h>
#endif
Do you know if anything like this is possible?

If you use GNU make, you could have something like this in the Makefile:
ifdef includeMyLib
CFLAGS += -DincludeMyLib
endif
This will change the flags used by the compiler to add the #define includeMyLib.

Related

How to implement CMake configure_file command in Makefile?

I think everybody knows this excellent CMake command:
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/version.h
)
But I have to implement that in Makefile. Could you please help me? How to do it?
Configuration file (version.h) is very simple:
#ifndef _VERSION_H_
#define _VERSION_H_
#define VERSION_MAJOR #VERSION_MAJOR#
#define VERSION_MINOR #VERSION_MINOR#
#define VERSION_BUILD #VERSION_BUILD#
#define VERSION_REVISION #VERSION_REVISION#
#endif // _VERSION_H_
This won't work. Well it might be, but it will be a hassle. These config.h files are made to communicate the result from a configure tool (configure from Autotools, CMake etc.) to the compiler.
When you use Makefiles, you can simply attach necessary flags or variables to the C(++) compiler call (with -D). There is no need to add the complexity of a config.h.

Using __NR_in userspace code

I have a code which checks the presence of certain system calls via something like
#if defined(__NR_process_vm_readv)
blah blah
#else
blah2 blah2
#endif
After running the source file through the pre-processor I see that the code in #else is being compiled. The reason is that the the unistd.h which is included resides under /usr/include whereas the unistd.h file which has those particular defines is under /usr/include/asm-generic/unistd.h. So how am I supposed to include it? The code I'm working has been written by a 3rd party so I don't know if the strategy that they opted to follow is even correct (relying on those defines).
The right way to do this on linux is shown in the syscall(2) manual page (see for example http://man7.org/linux/man-pages/man2/syscall.2.html):
#include <unistd.h>
#include <sys/syscall.h>
possibly with a preceding "#define _GNU_SOURCE" or other system specifier, though that doesn't seem to be necessary on my system. The <sys/syscall.h> file actually includes <asm/unistd.h>. This provides the SYS_syscall definition as well as __NR_syscall

Detect whether clang is compiling using c++11 or legacy libstdc++ standard library

I've got an Xcode project that I'm migrating to use with clang's option -stdlib libc++, to enable C++11 support. Some of my source files need to know which library is being used, for instance so that I do things like this:
#ifdef HAVE_CPP11_LIB_SUPPORT
#include <memory>
#else
#include <tr1/memory>
#endif
#ifdef HAVE_CPP11_LIB_SUPPORT
vector.emplace_back(newValue);
#else
vector.push_back(newValue);
#endif
I'm having trouble though finding the preprocessor macros (if indeed there are any) that are set for this option. I've tried dumping the outputs of clang with:
clang -x c++ -std=c++11 -stdlib=libc++ -dM -E - < /dev/null
to compare with:
clang -x c++ -std=c++11 -stdlib=libstdc++ -dM -E - < /dev/null
but this gives the same results. Note that I don't want to switch on whether we're using the c++11 language setting, but whether we're using the c++11 library. Is there any reliable way of detecting this in the code?
I don't know of any sure way that is guaranteed to be portable, but this is what I use for now:
// libc++ detected: _LIBCPP_VERSION
// libstdc++ detected: __GLIBCXX__
#if defined(__clang__)
# if __has_include(<__config>) // defines _LIBCPP_VERSION
# include <__config>
# elif __has_include(<bits/c++config.h>) // defines __GLIBCXX__
# include <bits/c++config.h>
# else
# include <ios>
# endif
#elif defined(__GNUC__) // gcc does not have __has_include
# include <ios> // ios should include the c++config.h which defines __GLIBCXX__
#endif
It's not great, but works for me for now.
libc++ defines _LIBCPP_VERSION and stdc++ defines __GLIBCXX__ which is nice, but unfortunately these macros are not defined by the compiler. Instead, they're defined in a non-standard header file, and you cannot test their definition unless that header has been included.
Note: Apparently stdc++ defined __GLIBCPP__ in older versions instead. Since you require c++11, this isn't going to be a problem.
Clang (Edit: Standard since C++17) has a nice feature __has_include which can be used to test for these but if neither header is found, the macro falls back to just including a standard header which hopefully uses the internal header under the hood. I have <ios> here, but the choice of standard header to include is up to you. You can look for headers that include the internal header with something like (this is for gcc on linux):
grep -Rl '#include <bits/c++config.h>' /usr/include/c++
Pick any header that you're likely to use in the project anyway.
Since this isn't guaranteed to work for any given past or future compiler/standard library version, I wouldn't rely on these defines for anything but optional features like:
#ifdef __GLIBCXX__
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
#endif
#ifdef __has_include
# if __has_include(<ciso646>)
# include <ciso646>
# if defined(_LIBCPP_VERSION)
# define USING_LIBCPP 1
# endif
# endif
#endif
#if !USING_LIBCPP
# define USING_LIBSTDCXX 1
#endif
If you're writing these kinds of checks I suggest you choose a compiler/library version and require that or newer. It makes no sense to half-use C++11 library features. On Mac OS X, just require compilation with clang++ -stdlib=libc++.
I use next code:
#include <cstddef> // for __GLIBCXX__
#ifdef __GLIBCXX__
# include <tr1/memory>
#else
# include <memory>
#endif
source

cpp: delay #include's until second pass

I'm running my source file through the C preprocessor twice before compiling it, and I want to delay The #include directives until the second pass.
Intuitively, I tried this, but it doesn't work:
##include <zlib.h>
I just need a construct, that when preprocessed, will give #include mylib.
You could define a macro, like
#define INCLUDE #include
and then when you include stuff, use the macro instead.
INCLUDE <zlib.h>
In GCC's preprocessor, at least, that gives me #include <zlib.h>.

How to undefine a define at commandline using gcc

How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.

Resources