Preprocessing with g++ and specs-file - c++

The question refers to arm-none-eabi-g++ 6.2 and linking against newlib-nano.
When I preprocess a C-source with -specs=nano.specs, the file newlib.h from the directory newlib-nano is included:
echo '#include <string.h>' |\
/opt/gcc-arm-none-eabi-6_2-2016q4/bin/arm-none-eabi-gcc -specs=nano.specs -x c -E - |\
grep '^# 1 .*newlib\.h'
outputs # 1 "/opt/gcc-arm-none-eabi-6_2-2016q4/arm-none-eabi/include/newlib-nano/newlib.h" 1 3 4 (as expected). This is because the file nano.specs contains (among others) the lines
%rename cpp nano_cpp
 
*cpp:
-isystem =/include/newlib-nano %(nano_cpp)
But if I feed a C++-source through the same compiler
echo '#include <string.h>' |\
/opt/gcc-arm-none-eabi-6_2-2016q4/bin/arm-none-eabi-gcc -specs=nano.specs -x c++ -E - |\
grep '^# 1 .*newlib\.h'
the output reads # 1 "/opt/gcc-arm-none-eabi-6_2-2016q4/arm-none-eabi/include/newlib.h" 1 3.
In other words: The specs-file is ignored.
I am aware that I should include <cstring> instead of <string.h> in C++ sources and that GNU g++ is commonly invoked by …/arm-none-eabi-c++ instead of …/arm-none-eabi-gcc -x c++ but I did that to carve out the small difference. And: this does not change the matter.
Question: What do I have to add to the specs-file to let C++-files include newlib-nano/newlib.h?

It had been a bug (https://bugs.launchpad.net/gcc-arm-embedded/+bug/1661882). It has been fixed. It will be in the “6-2017-q1-update”.

Related

Use CXX to query preprocessor defines?

I have a GNUmakefile that respects CXX and CXXFLAGS. It also performs some platform and architecture tests. Currently, the makefile assumes the host and target are the same:
IS_X86 = $(shell uname -m | $(EGREP) -c "i.86|x86|i86|amd64")
In an effort to improve robustness, I want to ask the tools what it is compiling for. I've come up with the following, but I'm not sure it is correct.
$ export CXX=clang++
$ export CXXFLAGS="-DNDEBUG -g2 -O3 -m32"
$ $CXX $CXXFLAGS -dM -E - < /dev/null | egrep "(i386|x86_64)"
#define __i386 1
#define __i386__ 1
#define i386 1
$ export CXX=clang++
$ export CXXFLAGS="-DNDEBUG -g2 -O3"
$ $CXX $CXXFLAGS -dM -E - < /dev/null | egrep "(i386|x86_64)"
#define __x86_64 1
#define __x86_64__ 1
My question is, will the above - with CXX and CXXFLAGS - work reliably to detect a target? Or do I need something else?
Here's the two reasons I ask. First, my experience with Autotools indicates something different. When Autotools performs a test like above, they test CPP, and sometimes CPP or CXX needs to include --isysroot (or other hacks) to get things configured properly.
Second, some toolchains, like Clang, integrate other components (like a preprocessor or assembler), so I can't use CPP directly under all circumstances.
In fact, doing something as simple as $CXX -Wa,-v - </dev/null (ask assembler for its version) results in an "unsupported option" error under Clang when using its integrated assembler. (Cf., With integrated assembler enabled, fail to fetch version string of assembler).
And just in case: this is not an Autools or Cmake project. It does not use Boost or any other libraries. Its a stand alone C++03 project.
My question is, will the above - with CXX and CXXFLAGS - work reliably to detect a target?
The answer is Yes, it will. The preprocessor or compielr driver (passing down to preprocessor) will mostly yield expected target defines with all else being equal. Notable exception is GCC and ARMv8/Aarch64, which is missing a slew of expected defines.
The thing to avoid is uname -m (and friends). Uname reports information on the host, and not the target.

Where is the limit.h file that defines the template numeric_limits

So, I am trying to locate the limit.h file that has the numeric_limits defined.
I seem to find all different flavors of the limit.h but not the defined one, as
shown in
http://en.cppreference.com/w/cpp/types/numeric_limits
I am on debian distro.
Here is what I have done so far. I created a main.cpp with only #include <limits>
Did a g++ verbose build to find all the include path:
g++ -v main.cpp -o tryout.
Now I see that /usr/include
and usr/lib has bunch of limits.h files. But none of them seem to have the template definition I am looking for
in /usr/include/
% find -name limits.h returns the following :
./c++/4.4/tr1/limits.h
./limits.h
./linux/limits.h
in /usr/lib
% find -name limits.h returns the following:
./perl5/Tk/pTk/compat/limits.h
./gcc/x86_64-linux-gnu/4.3/include-fixed/limits.h
./gcc/x86_64-linux-gnu/4.4/include-fixed/limits.h
So where is the std::numeric_limits template located. How do I find that file.
As the reference page shows, std::numeric_limits is defined in the header <limits>, not limits.h. You can find where it is by asking the preprocessor, for example:
~$ cat test.cc
#include <limits>
~$ g++ -E test.cc -o - | grep limits | grep gcc | tail -1
# 841 "/opt/swt/install/gcc-4.7.2/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/limits" 3

Extract all included files in cpp

I have .cpp file (text).I want to get the list of all files names which are included (#include) to this file.
What is the best way to do it?(Need to implement it in C++)
gcc -M source.cpp
Replace -M with -MM if you don't care about the system includes.
Assuming you have a "find" or "grep", something along these lines:
g++ -E source.cpp | grep '\# 1 '

ctags ignore lists for libc6, libstdc++ and boost

I use ctags with vim and the OmniCppComplete plugin. Currently when generating my tags I do it individually for each library. For libc6 I use the following list of tokens / macros in a file named libc6-ignore to ignore during processing:
__attribute__
__attribute_deprecated__
__attribute_format_arg__
__attribute_format_strfmon__
__attribute_malloc__
__attribute_noinline__
__attribute_pure__
__attribute_used__
__attribute_warn_unused_result__
__wur
__THROW
__nonnull+
Am I missing any other tokens I should be ignoring and should I be using this same list or a different one when generating tags for libstdc++ and boost?
For anyone who's interested I use the following to generate my tag files:
# First make sure apt-file is install and then do:
$ sudo apt-file update
# set up tags for libc, the standard C library
$ apt-file list libc6-dev | grep -o '/usr/include/.*\.h'> ~/.vim/tags/libc6-filelist
$ ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -I./libc6-ignore -f ~/.vim/tags/libc6 -L ~/.vim/tags/libc6-filelist
# create tags for stdlibc++ and STL
$ apt-file list libstdc++6-4.4-dev | grep -E -o '/usr/include/.*\.(h|hpp)' > ~/.vim/tags/stdlibcpp-filelist
$ ctags --sort=foldcase -R --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/stdlibcpp -L ~/.vim/tags/stdlibcpp-filelist
# For Boost
$ apt-file list boost | grep -E -o '/usr/include/.*\.(h|hpp)' | grep -v '/usr/include/boost/typeof/' > ~/.vim/tags/boost-filelist
$ ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/boost -L ~/.vim/tags/boost-filelist
You can also use the modified libstdc++ library:
http://www.vim.org/scripts/script.php?script_id=2358
This contains a stripped version of the C++ header files which works for ctags.
I made a Python script that extracts all tags beginning with an underscore from a tags file. You can choose with this script which tags to exclude.
Feel free to tailor the script to meet your needs or suggest anything else:
import re
tags=open('tags','r')
output=open('exclude','w')
regex=re.compile('^_[a-zA-Z0-9_]*')
results=set()
for line in tags:
result=regex.match(line)
if(result!=None):
results.add(result.group(0))
tags.close()
for element in sorted(results):
output.write('{0}\n'.format(element))
output.close()
I have followed those instructions and I am able to get all boost boost references working i.e.
#include <iostream>
I can jump directly to iostream
However what I am still missing is to go to for example
#include <stdio.h>
Although in my generate script I have included as you mentioned i.e.
$ apt-file list libc6-dev | grep -o '/usr/include/.*\.h'> ~/.vim/tags/libc6-filelist
$ ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -I./libc6-ignore -f ~/.vim/tags/libc6 -L ~/.vim/tags/libc6-filelist
After i generate the tag "libc6" file whenever I try to go to stdio.h it is saying “E426: tag not found: stdlib”.
Here is what I have included additionally to my .vimrc in order to make all those 3 tag files visible.
set tags+=~/.vim/tags/boost
set tags+=~/.vim/tags/libc6
set tags+=~/.vim/tags/stdlibcpp
I am not an expert however I can say that this worked somehow for boost but not for libc6-dev. Can someone assist me with the solution
here is the same code as above
sudo apt-file update
# set up tags for libc, the standard C library
apt-file list libc6-dev | grep -o '/usr/include/.*\.h'> ~/.vim/tags/libc6-filelist
ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -I./libc6-ignore -f ~/.vim/tags/libc6 -L ~/.vim/tags/libc6-filelist
apt-file list libstdc++6-4.6-dev | grep -E -o '/usr/include/.*\.(h|hpp)' >> ~/.vim/tags/stdlibcpp-filelist
ctags --sort=foldcase -R --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/stdlibcpp -L ~/.vim/tags/stdlibcpp-filelist
# For Boost
apt-file list boost | grep -E -o '/usr/include/.*\.(h|hpp)' | grep -v '/usr/include/boost/typeof/' > ~/.vim/tags/boost-filelist
ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/boost -L ~/.vim/tags/boost-filelist
Sorry--I've never used ctags before--but I'll take a stab at this question.
If I understand correctly, you can use the list of keywords from GCC itself. I found this https://gist.github.com/959484 inside gcc/gcc/c-family/c-common.c. Looks like it includes reserved words for all the C (c/c++/obj-c variants). I guess some are valid for all compilers, these are for gcc of course.
As for figuring out other symbols to ignore, on OS X I'd use nm to dump the symbols of the library in question an add all symbols marked as private ('s' instead of 'S' for example) to my list of symbols to ignore. Linux has a similar library-dumping tool?
Hope that's useful.
I had my own list and never thought about adding what you've already listed!
Here's that updated ignore list for libc6 that I've come up with (Ubuntu 14.04 and GCC 4.8.4) to use as input to the -I option of ctags:
__attribute__
__attribute_deprecated__
__attribute_format_arg__+
__attribute_format_strfmon__+
__attribute_malloc__
__attribute_noinline__
__attribute_pure__
__attribute_used__
__attribute_warn_unused_result__
__attribute_alloc_size__+
__attribute_const__
__attribute_artificial__
__wur
__THROW
__THROWNL
__BEGIN_DECLS
__END_DECLS
__BEGIN_NAMESPACE_STD
__END_NAMESPACE_STD
__USING_NAMESPACE_STD+
__BEGIN_NAMESPACE_C99
__END_NAMESPACE_C99
__USING_NAMESPACE_C99+
__warndecl+
__warnattr+
__errordecl+
__flexarr=[]
__fortify_function
__REDICRECT+
__REDIRECT_NTH+
__REDIRECT_NTHNL+
__ASMNAME+
__ASMNAME2+
__nonnull+
__always_inline
__extern_inline=extern
__extern_always_inline=extern
__extension__
__restrict
__restrict_arr
I also created the following ignore list for generating a tags file for libstdc++ (GCC 4.8.2 on Ubuntu 14.04) (again, this is input to the -I option):
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_ALGO
_GLIBCXX_END_NAMESPACE_ALGO
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_BEGIN_EXTERN_C
_GLIBCXX_END_EXTERN_C
_GLIBCXX_VISIBILITY+
_GLIBCXX_PURE
_GLIBCXX_CONST
_GLIBCXX_NORETURN
_GLIBCXX_CONSTEXPR=constexpr
_GLIBCXX_USE_CONSTEXPR=constexpr
_GLIBCXX_THROW_OR_ABORT+
_GLIBCXX_NOEXCEPT
_GLIBCXX_USE_NOEXCEPT
_GLIBCXX_THROW+
_GLIBCXX_NOTHROW
I changed __attribute__ to be: __attribute__+ to indicate it looks like a function and should be ignored.
Of course, I have created one for Boost as well, but I think I'll refrain from posting it until someone has a need.

What are the GCC default include directories?

When I compile a very simple source file with gcc I don't have to specify the path to standard include files such as stdio or stdlib.
How does GCC know how to find these files?
Does it have the /usr/include path hardwired inside, or it will get the paths from other OS components?
In order to figure out the default paths used by gcc/g++, as well as their priorities, you need to examine the output of the following commands:
For C:
gcc -xc -E -v -
For C++:
gcc -xc++ -E -v -
The credit goes to Qt Creator team.
There is a command with a shorter output, which allows to automatically cut the include pathes from lines, starting with a single space:
$ echo | gcc -Wp,-v -x c++ - -fsyntax-only
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/backward
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include
/usr/local/include
/usr/include
End of search list.
The credit goes to the libc++ front-page.
To summarise the other answers:
For C++:
c++ -xc++ /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p'
For C:
cc -xc /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p'
Though I agree with Ihor Kaharlichenko’s answer for considering C++ and with abyss.7’s answer for the compactness of its output, they are still incomplete for the multi-arch versions of gcc because input processing depends on the command line parameters and macros.
Example:
echo | /opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-g++ -specs=nano.specs -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=soft -x c++ -E -Wp,-v\
- -fsyntax-only yields
⋮
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../arm-none-eabi/include/newlib-nano
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/arm-none-eabi/thumb/v7e-m/nofp
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/backward
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include-fixed
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include
⋮
whereas echo | /opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-g++ -x c++ -E -Wp,-v - -fsyntax-only yields
⋮
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/arm-none-eabi
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include/c++/9.2.1/backward
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/include-fixed
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/include
⋮
The former invocation utilizes newlib (see lines 1 and 3 of the output), the latter goes with the standard includes. The common files at the end of the list are an example for the usage of include_next.
Bottom line: Always consider all macros and compiler options when printing the include directories.
Just run the following to list the default search paths:
$(gcc -print-prog-name=cc1) -v