g++ default header include list - linux

While performing a compilation with cross g++ in a Linux machine ( lubuntu 11.10 ) in verbose mode, I can see the list of the default include header directories:
#include <...> search starts here:
/opt/eldk-4.2/usr/bin/../lib/gcc/powerpc-linux/4.2.2/include
/opt/eldk-4.2/ppc_4xx/usr/include/c++/4.2.2/opt/eldk-4.2/ppc_4xx/usr/include/c++/4.2.2/powerpc-linux
/opt/eldk-4.2/ppc_4xx/usr/include/c++/4.2.2/backward
/opt/eldk-4.2/usr/../ppc_4xx/usr/include
Executing the very same g++ binary in another Linux machine (lubuntu 12.10), I get another different list, with less elements:
#include <...> search starts here:
/opt/eldk-4.2/usr/bin/../lib/gcc/powerpc-linux/4.2.2/include
and in which some of the elments seem bad constructed, like the following:
ignoring nonexistent directory "/opt/ppc_4xx/usr/lib/gcc/powerpc-linux/includ../include/c++/4.2.2"
The result is that some code compiling on the first system is not compiling on the second because some headers are not found.
Why is this happening?. Where does this list come from?. Who is responsible for constructing it?. Is it possible to easily change it?.
Any help is appreciated.

You can add directories to the default search path by setting environment variables:
C_INCLUDE_PATH (for C header files)
CPLUS_INCLUDE_PATH (for C++ header files).
Alternatively, you can create and edit specfile and place it where G++ looks for them. You can check the path with strace gcc.
Additional documentation on specfiles on GCC page.

I have the exact some problem using ELDK 4.2. This is very likely connected to something that changed in ubuntu 12.04 as I have had the compiler run fine on the same computer before the upgrade.
My problem is that is seems to have forgotten /usr
ignoring nonexistent directory "/opt/eldk-4.2/../ppc_82xx/usr/include"
It should be
/opt/eldk-4.2/usr/../ppc_82xx/usr/include
Which works perfectly on ubuntu 11.10.
I have tried both installing ELDK from the ISO and copying the installation from a working version in ubuntu 11.10

Related

How to find out path of Boost library for manual package build and installation?

I am using Windows subsystem for linux for Ubuntu and I am very new to this. I am trying to build the program (AutoDock Vina) from its source code provided on GitHub - GitHub Link.
In its installation procedure - provided here, it's mentioned that - To compile the binary (you might need to customize the Makefile by setting the paths to the Boost library)
Makefile has the following code written in it -
BASE=/usr/local
BOOST_VERSION=
BOOST_INCLUDE = $(BASE)/include
C_PLATFORM=-static -pthread
GPP=/usr/bin/g++
C_OPTIONS= -O3 -DNDEBUG -std=c++11
BOOST_LIB_VERSION=
include ../../makefile_common
I had previously installed Boost and SWIG using apt-get command as mentioned in the manual.
sudo apt-get install libboost-all-dev swig
When I tried to find out location of Boost library, I found that at following two places boost related files are there -
/usr/lib/x86_64-linux-gnu/ and
/lib/x86_64-linux-gnu/ (these two folders have many files having names starting with libboost)
/usr/include/boost/ (this appears to be main folder for boost)
But, I tried many combinations to the BASE value in Makefile, but in all cases, after building the files, I see the executable named Vina (as expected) is built in the folder but when I try to run the same on terminal, I get command not found error.
Please help me with this - how to find out Boost related values for Makefiles?
Edit 1 - After reading the comment from #MadScientist, I have realized it's not a problem of Boost library but the issue I am facing is because of PATH not set. So I will follow his comment and proceed.

How can get g++ to use my own glibc build's headers correctly?

There's a TL;DR at the end if the context is too much!
Context
I am trying to update the version of glibc a project uses to 2.23 (I know it's old, that's another issue). In order to do this, I need to swap out the libraries and use the associated interpreter.
I encountered some issues when swapping out the interpreter that looked like an ABI change, so I figured it was probably because the header files had changed somehow and started working on getting those included into the project.
At first I tried using -I to include the headers, but got an error (see below). Later I tried setting --sysroot, but this quickly felt like the wrong way of doing things since I was essentially reinventing what g++ already did with system headers. I later found another mechanism that looked more promising (see Problem section).
Could this be an XY issue? Absolutely, but either way, the problem I'm seeing seems odd to me.
Problem
I looked into whether there was a different mechanism to include headers for system libraries, such as glibc, in gcc and g++. I found the flag -isystem:
-isystem dir
Search dir for header files, after all directories specified by -I but before the standard system directories. Mark it as a system directory, so that it gets the same special treatment as is applied to the standard system directories. If dir begins with "=", then the "="
will be replaced by the sysroot prefix; see --sysroot and -isysroot.
I figured that this was probably wanted and set about intergrating this flag into the build system for the project. The resulting g++ command looks like this (simplified and broken onto multiple lines):
> /path/to/gcc-6.3.0/bin/g++
-c
-Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2
-Wl,--rpath=/path/to/glibc-2.23/build/install/lib
-isystem /path/to/glibc-2.23/build/install/include
-I.
-I/project-foo/include
-I/project-bar/include
-o example.o
example.cpp
This leads to the following error, followed by many similar ones:
In file included from /usr/include/math.h:71:0,
from /path/to/gcc-6.3.0/include/c++/6.3.0/cmath:45,
from example.cpp:42:
/path/to/glibc-2.23/build/install/include/bits/mathcalls.h:63:16: error: expected constructor, destructor, or type conversion before '(' token
__MATHCALL_VEC (cos,, (_Mdouble_ __x));
Looking into this, it appears that this particular math.h is incompatible with this version of glibc. The fact it tries to use it surprises me, because the math.h file exists in the glibc directory I specified; why didn't it use that? Here's how I verified that file exists:
> ls /path/to/glibc-2.23/build/install/include/math.h
/path/to/glibc-2.23/build/install/include/math.h
Research
I searched around on the internet for people with a similar issue and came across the following relevant things:
https://github.com/riscv/riscv-gnu-toolchain/issues/105
https://askubuntu.com/questions/806220/building-ucb-logo-6-errors-in-mathcalls-h
-isystem on a system include directory causes errors
The last of these is the most promising; it talks about why -isystem won't work here stating that the special #include_next traverses the include path in a different way. Here, the solution appears to be "don't use -isystem where you can help it", but since I've tried using -I only get get the same problem again, I'm not sure how I'd apply that here.
Original issue
When compiling with the new glibc, I get the following error (our build process ends up running some of the programs it compiles to generate further source to be compiled, hence this runtime error whilst compiling):
Inconsistency detected by ld.so: get-dynamic-info.h: 143: elf_get_dynamic_info: Assertion `info[DT_RPATH] == NULL' failed!
I found a couple of relevant things about this:
https://www.linuxquestions.org/questions/linux-software-2/how-to-get-local-gcc-to-link-with-local-glibc-404087/
https://www.linuxquestions.org/questions/programming-9/inconsistency-detected-by-ld-so-dynamic-link-h-62-elf_get_dynamic_info-assertion-621701/
The only solution I see there is completely recompiling gcc to use the new glibc. I'd like to avoid that if possible, which is what lead me down the include route.
Eliminating the complex build system
To try and eliminate the complex build system on the "real" project, I reproduced the problem using the following test.cpp file:
#include <cmath>
int main() {
}
Compiled using:
> /path/to/gcc-6.3.0/bin/g++ test.cpp -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2 -Wl,--rpath=/path/to/glibc-2.23/build/install/lib
Running yields the same original issue:
> ./a.out
Inconsistency detected by ld.so: get-dynamic-info.h: 143: elf_get_dynamic_info: Assertion `info[DT_RPATH] == NULL' failed!
Trying to use the newer headers yields the same include issue:
> /path/to/gcc-6.3.0/bin/g++ test.cpp -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2 -Wl,--rpath=/path/to/glibc-2.23/build/install/lib -isystem /path/to/glibc-2.23/build/install/include
In file included from /usr/include/math.h:71:0,
from /path/to/gcc-6.3.0/include/c++/6.3.0/cmath:45,
from test.cpp:1:
/path/to/glibc-2.23/build/install/include/bits/mathcalls.h:63:16: error: expected constructor, destructor, or type conversion before '(' token
__MATHCALL_VEC (cos,, (_Mdouble_ __x));
TL;DR
How can I get g++ to include the headers from my glibc build correctly, without it accidentally including incompatible files from /usr/include?
In your GCC version,<cmath> uses #include_next, which means that you need to make sure that the directory which contains the cmath file comes before (on the include search path) the directory with the proper math.h for the version of glibc you are building against.
You can use g++ -v to view the search path. In your case, it probably looks like this:
#include "..." search starts here:
#include <...> search starts here:
.
/project-foo/include
/project-bar/include
/path/to/glibc-2.23/build/install/include
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
If you configure glibc with --prefix=/usr and install it with DESTDIR=/path/to/glibc-2.23/build/install, its header files will be installed into the directory /path/to/glibc-2.23/build/install/usr/include. This means you should be able to use the -isysroot option, which rewrites the default /usr/include directory, resulting in the right ordering of the search path:
#include "..." search starts here:
#include <...> search starts here:
.
/project-foo/include
/project-bar/include
/usr/include/c++/6
/usr/include/x86_64-linux-gnu/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/x86_64-linux-gnu/6/include
/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
/path/to/glibc-2.23/build/install/usr/include

Code:Blocks cannot detect gfortran although installed

I believe my question is similar to this post: Linux: cannot find lgfortran though gfortran is installed.
However, since the suggested answer does not fix my problem, there seems no other choice other than asking it again, for a desperate Linux new comer like me.
Here is the problem. I installed GNU fortran compiler 4.8.4 and can find it in terminal
$ which gfortran-4.8
/usr/bin/gfortran-4.8
and
$ locate gfortran
/usr/bin/gfortran-4.7
/usr/bin/gfortran-4.8
/usr/bin/x86_64-linux-gnu-gfortran-4.7
/usr/bin/x86_64-linux-gnu-gfortran-4.8
/usr/lib/gcc/x86_64-linux-gnu/4.7/libgfortran.a
/usr/lib/gcc/x86_64-linux-gnu/4.7/libgfortran.so
/usr/lib/gcc/x86_64-linux-gnu/4.7/libgfortran.spec
/usr/lib/gcc/x86_64-linux-gnu/4.7/libgfortranbegin.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.so
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.spec
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortranbegin.a
/usr/lib/x86_64-linux-gnu/libgfortran.so.3
/usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0
/usr/share/doc/gfortran-4.7
/usr/share/doc/gfortran-4.8
/usr/share/doc/libgfortran-4.7-dev
/usr/share/doc/libgfortran-4.8-dev
/usr/share/doc/libgfortran3
/usr/share/man/man1/gfortran-4.7.1.gz
/usr/share/man/man1/gfortran-4.8.1.gz
/usr/share/man/man1/x86_64-linux-gnu-gfortran-4.7.1.gz
/usr/share/man/man1/x86_64-linux-gnu-gfortran-4.8.1.gz
/var/cache/apt/archives/gfortran-4.7_4.7.3-12ubuntu1_amd64.deb
/var/cache/apt/archives/gfortran-4.8_4.8.4-2ubuntu1~14.04_amd64.deb
/var/cache/apt/archives/libgfortran-4.7-dev_4.7.3-12ubuntu1_amd64.deb
/var/cache/apt/archives/libgfortran-4.8-dev_4.8.4-2ubuntu1~14.04_amd64.deb
/var/cache/apt/archives/libgfortran3_4.8.4-2ubuntu1~14.04_amd64.deb
/var/lib/dpkg/info/gfortran-4.7.list
/var/lib/dpkg/info/gfortran-4.7.md5sums
/var/lib/dpkg/info/gfortran-4.8.list
/var/lib/dpkg/info/gfortran-4.8.md5sums
/var/lib/dpkg/info/libgfortran-4.7-dev:amd64.list
/var/lib/dpkg/info/libgfortran-4.7-dev:amd64.md5sums
/var/lib/dpkg/info/libgfortran-4.8-dev:amd64.list
/var/lib/dpkg/info/libgfortran-4.8-dev:amd64.md5sums
/var/lib/dpkg/info/libgfortran3:amd64.list
/var/lib/dpkg/info/libgfortran3:amd64.md5sums
/var/lib/dpkg/info/libgfortran3:amd64.postinst
/var/lib/dpkg/info/libgfortran3:amd64.postrm
/var/lib/dpkg/info/libgfortran3:amd64.shlibs
/var/lib/dpkg/info/libgfortran3:amd64.symbols
So gfortran seems installed, although I don't understand why 4.7 version is still there after my removing it.
In setting Global Compiler Settings of Code:Blocks, when I choose GNU Fortran Compiler, and its Toolchain Executables, I tried the installation directory as
/usr
/usr/bin
and
/usr/lib/gcc/x86_64-linux-gnu/4.8/
as suggested in the previous post, Code:Blocks tell me
could not auto-detect installation path of "GNU Fortran Compiler".....
More details of compiler configuration is here in the image (Thanks to Mike's suggestion).
And here's the full list of compilers on my computer:
List of Compliers
Your posting shows that you have both gfortran-4.7 and gfortran-4.8
installed under /usr/bin.
Having multiple GCC Fortran compilers (or multiple C or C++ compilers) is
perfectly valid and commonplace. Code::Blocks will allow you configure
as many Fortran compilers as you have got, provided you give them different
names. It's also fine if you just want to configure one of them as the
"GNU Fortran Compiler" and ignore the others.
But in any case, Code::Blocks must be able to unambiguously identify the
installed compiler that you are calling "GNU Fortran Compiler". You
have specified the Compiler's installation directory as /usr/bin
and have left the Program files compiler name as gfortran.
There is no such compiler as /usr/bin/gfortran in your system,
and there is no program called gfortran anywhere in your PATH. You
have /usr/bin/gfortran-4.7 and /usr/bin/gfortran-4.8. As you have
installed both of them, Code::Blocks assumes you want both of them. It
can't tell which one of them you want to configure as "GNU Fortran Compiler".
So:-
Set Compiler's installation directory = /usr/bin
In Program files, change all occurrences of gfortran to gfortran-4.8,
if you want "GNU Fortran Compiler" to mean gfortran-4.8.
OK out.
Default compiler name in 20.3 version was mingw32-gfortran. However, the executable name coming with installation is x86_64-w64-mingw32-gfortran. If this is written in compiler settings. It works.enter image description here
The install file codeblocks-20.03mingw-setup installs the file gfortran.exe into the C:\Program Files\CodeBlocks\MinGW\bin directory. However the Settings>Compiler>toolchainexecutables autodetect function looks for mingw32-gfortran.exe.
To fix this, in toolchainexecutables, change the filename mingw32-gfortran.exe to gfortran.exe in 3 places, then autodetect will find it.

Call Matlab from Intel Fortran (Linux)

I am trying to integrate a Matlab program I wrote into some Fortran code. I tried to follow the example Mathworks provides. But I can't get it to compile because I can't find the header files it requests.
Does anyone know of an example of someone getting it to work on Linux using an Intel compiler. I think that might be part of the problem because Matlab only supports GNU Fortran on Linux.
And I realize this is a simple question, I just don't understand how to do anything in compiling more complicated than including multiple files with defined paths.
Disclaimer: I'm currently using OS X so I can only provide output from OS X but everything should transfer easily over to Linux due to the Unix base. I also don't have the Intel Fortran compiler on OS X (only the C/C++ compiler).
Note: You will need to substitute the paths I use for the correct paths on your system depending on your MATLAB installation directory.
This issue isn't specific to the Intel Compiler, I also receive errors with the GCC Fortran compiler.
$ gfortran fengdemo.F
fengdemo.F:1:0:
#include "fintrf.h"
^
Fatal Error: fintrf.h: No such file or directory
compilation terminated.
You can use the Unix locate command to find files.
$ locate fintrf.h
/Applications/Matlab R2014a.app/extern/include/fintrf.h
In the directory where fengdemo.F is we can then pass the correct directory in using the -I option
-I../../include/
However, this produces linking errors as we haven't specified where the libraries for fintrf.h can be found. We can do this with the -L option (you will need to replace maci64 with the correct option for Linux - I can't remember it off the top of my head but you should be able to see it in the bin directory)
-L../../../bin/maci64/
Now we need to tell it what libraries to use with -leng -lmx and so the completed command is
$ ifort fengdemo.F -I../../include/ -L../../../bin/maci64/ -leng -lmx
and it should compile correctly.
We aren't finished yet though as it won't execute. We need to set up our PATH and DYLD_LIBRARY_PATH environment variables correctly. Specifically we need to add the bin and bin/maci64 directories of our MATLAB installation to PATH
$ export PATH=$PATH:/Applications/Matlab\ R2014a.app/bin/maci64:/Applications/Matlab\ R2014a.app/bin
and the bin/maci64/ and sys/os/maci64/ to DYLD_LIBRARY_PATH
$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Applications/Matlab\ R2014a.app/bin/maci64/:/Applications/Matlab\ R2014a.app/sys/os/maci64/
Note: On Linux DYLD_LIBRARY_PATH should be LD_LIBRARY_PATH. Thanks to Vladimir F for correcting me.
Now you can execute the program using
$ ./a.out

Codesourcery toolchain under Win7/cygwin can't find some files

I have searched this but the questions I found are about getting the toolchain to work, my problem is that it works on all but a few directories. Also I am not building Linux.
I am trying to move a project from a Linux machine to Windows to make people happy. The same project builds fine under Linux (Ubuntu 12.04) using the Linux Binary for the same toolchain (I recently reloaded both toolchains from the same directory at Mentor to be sure, see details below).
I installed Cygwin, got the packages, set up paths, etc. In general the build works for 90% of the project BUT as make traverses the directory, it finds everything except two files (to clarify, these two are the first files in their respective directories, so I assume the problem will apply to the whole directory). The log below shows the first fail:
if I take lwip out of the build then it blows up on the next one
if I take the next one out of the build then everything else (quite a bit) compiles; then the linker fails on the two missing items as expected.
More precisely, e.g.
it finds /home/Nadi/project/version-2.9/external/freertos/Source/portable/GCC/ARM_CM3_MPU/port.c
but not /home/Nadi/project/version-2.9/external/lwip/src/api/api_lib.c
from the directory that I am running make, "ls" finds the file that the compiler cannot.
log:
$ make
external/freertos
external/lwip
[cc] Debug/api_lib.o
arm-none-eabi-gcc.exe: error: /home/Nadi/project/version-2.9/external/lwip/src/api/api_lib.c: No such file or directory
arm-none-eabi-gcc.exe: fatal error: no input files compilation terminated.
Makefile:189: recipe for target `Debug/api_lib.o' failed
make[2]: *** [Debug/api_lib.o] Error 1
Makefile:37: recipe for target `lwip_world' failed
make[1]: *** [lwip_world] Error 2
Makefile:160: recipe for target `extern' failed
make: *** [extern] Error 2
Details:
GCC Chain : arm-none-eabi-gcc ; gcc version 4.7.2 (Sourcery CodeBench Lite 2012.09-63)
Cygwin : CYGWIN_NT-6.1-WOW64
Although it might not help in this particular case, I faced similar problem with CodeSourcery's gcc not recognising Cygwin's paths like /cygdrive/d/foo.c at all - installation of cygpath package and setting environment variable export CYGPATH=c:/cygwin32/bin/cygpath (or set CYGPATH=c:/cygwin32/bin/cygpath in windows console) solved all the issues.
Be sure to define path to cygpath executable in exactly same way as above, regardless of Cygwin or Windows console used.
The details of my previous comment is that you're in for a lot of trouble using the windows/cygwin combo with Sourcery based cross-compilers. You can read more about this at SamyGo. Some of the issues using Windows, presented in all gory detail there, are:
Uses ACL to set file permissions and ownership (Not Linux compatible.)
Has it's own way of creating symbolic links (Not Linux compatible.)
Uses a non case-sensitive default for its fixed NTFS drives.
(Often and silently break archives originally compressed under Linux.)
Uses the Win32 (non POSIX) standard for file paths (Not Linux compatible.)
Uses the 2 characters Carriage-Return and New-Line ("\r" & "\n") for
End-of-Line (EOL) representation, contrary to POSIX, which uses only NL.
So in order not to waste time doing 3rd party debugging, you'd be much better off building your own cross-compiler from scratch, as shown in the XDA links in that other post. Since the advent of Android's, this is no longer difficult.

Resources