Autotools naming bug - build

I have following configure.ac:
AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_PROG_CXX
AC_OUTPUT
And it generates configure, that contains following lines:(grep core configure )
1572: rm -f core *.core core.conftest.* &&
2143:rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2210:rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2212:rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2214:rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
Fun begins with the fact, that I have folder, named core. So ./configure yield
checking for g++... g++
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... rm: cannot remove 'core': Is a directory
yes
checking whether g++ accepts -g... rm: cannot remove 'core': Is a directory
yes
configure: creating ./config.status
rm: cannot remove 'core': Is a directory
I found in google, that it is done in case of compiler crash. But is it any nice way to disable this check(I really do not care about compilers that can core dump on autoconf tests).
Renaming folder is not what I want to do.

But is it any nice way to disable this check
No, there isn't.
Renaming folder is not what I want to do.
In that case, I suggest patching 'configure' after somewhere in an autoconf 'bootstrap.sh' script or after whatever runs autoreconf:
#!/bin/sh
autoreconf -fvi # or whatever autoreconf needs
sed -i 's/rm -f core/rm -f/g' configure
Note that sed -i is not a universal solution, as it relies on GNU sed, but it's not too hard to come up with a portable solution.

As show in the question most projects have a configure.ac file with rules for generating the configure script. The last line is almost always AC_OUTPUT (as it is in your case). You can add this after that line (usually as the very end of the file) to manipulate the generated configure file and scrub the offending commands:
m4_esyscmd_s([test -f configure && sed -i -e '/rm -f/s/ core / /' configure])

Related

Cannot compile Makefile using make command on Windows

Problem summary
I am trying to install an open-source parallel finite-element code called TACS and available at this github repository. To comply with the indicated prerequisites, I followed the instructions at this github repository, which allowed me to install SuiteSparse and METIS on Windows with precompiled BLAS/LAPACK DLLs. For the MPI, I installed both the Intel MPI Library and Open MPI through Cygwin. The final step should be to compile running make, however this command is not directly available in Windows 10. As a consequence, I explored the options suggested in this question, unfortunately without success. I feel at a dead end, any help will be appreciated.
What I've tried
Please have a look below at my attempts. I am mainly a Windows user and I don't know much of compiling programs using Makefile. My current understanding is that the Makefile that I am trying to compile is written for Linux and whatever GNU compiler for Windows I use will not work because of the different syntax needed. Please correct me if I am wrong. What I can't understand is why I get errors also when I try to compile with Ubuntu Bash for Windows 10 (last attempt of the list below).
Visual Studio nmake
Running the Developer Command Prompt for VS 2019 as administrator, I typed nmake -f Makefile in TACS base directory and I got Makefile.in(28) : fatal error U1001: syntax error : illegal character '{' in macro Stop.
Chocolatey make
Running Windows Command Prompt as administrator with C:\ProgramData\chocolatey\bin at the top of PATH environment variable, I typed make in TACS base directory and I got
"" was unexpected at this time.
make: *** [Makefile:23: default] Error 255
Cygwin make
Running Windows Command Prompt as administrator with C:\cygwin64\bin at the top of PATH environment variables, I typed make in TACS base directory and I got three types of error:
error: expected ',' or '...' before numeric constant
error: cannot convert 'int*' to 'idx_t*' {aka 'long int*'}
error: no matching function for call to 'TACSSchurMat::getBCSRMat(BCSRMat**, NULL, NULL, NULL)'
I tried to change some variable names in the affected scripts (like N_ in place of _N) and I got rid of the first and the third type of error, but not of the second one.
GnuWin make
Running Windows Command Prompt as administrator with C:\Program Files (x86)\GnuWin32\bin at the top of PATH environment variables, I typed make in TACS base directory and I got
"" was unexpected at this time.
make: *** [Makefile:23: default] Error 255
MinGW mingw32-make
Running Windows Command Prompt as administrator with C:\MinGW\bin at the top of PATH environment variables, I typed mingw32-make in TACS base directory and I got
"" was unexpected at this time.
Makefile:23: recipe for target 'default' failed
mingw32-make: *** [default] Error 255
MSYS MinGW 64-bit make
Running Windows Command Prompt as administrator with C:\msys64\usr\bin at the top of PATH environment variables, I typed make in TACS base directory and I got
make[1]: mpicxx: No such file or directory
make[1]: *** [../TACS_Common.mk:28: C:/Users/qa21944/git/tacs/src/TACSAssembler.o] Error 127
make[1]: *** Waiting for unfinished jobs....
make[1]: mpicxx: No such file or directory
make[1]: *** [../TACS_Common.mk:28: C:/Users/qa21944/git/tacs/src/TACSCreator.o] Error 127
make[1]: Leaving directory '/c/Users/qa21944/git/tacs/src'
make: *** [Makefile:23: default] Error 1
This is quite difficult for me to understand, as the mpicxx file is C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin, which in turn is in the PATH environment variable. When I tried to add C:\cygwin64\bin to PATH (below C:\msys64\usr\bin) and to rerun make, I got
0 [main] opal_wrapper (14432) C:\cygwin64\bin\opal_wrapper.exe: *** fatal error - cygheap base mismatch detected - 0x180352408/0x180357408.
This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version. The most recent version *should*
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution. Rebooting is also suggested if you
are unable to find another cygwin DLL.
I tried to follow these instructions and then rebooted my computer, but nothing changed.
Ubuntu Bash for Windows 10 make
This attempt was inspired by this answer. I downloaded Ubuntu from Microsoft Store and installed make. From the Ubuntu Bash I typed make in TACS base directory and I got
make[1]: Entering directory '/mnt/c/Users/qa21944/git/tacs/src'
Makefile:26: *** target pattern contains no '%'. Stop.
make[1]: Leaving directory '/mnt/c/Users/qa21944/git/tacs/src'
make: *** [Makefile:23: default] Error 1
I do not understand why I should get this error. I also made sure that all lines started with a tab rather than white spaces, but nothing changed.
Codes
Below you can find the Makefile.in and Makefile that I am using.
Makefile.in
# Do not modify this file. Copy this file to Makefile.in and then modify it.
# In order to get TACS to compile, you'll need to fill in the
# following path information. Some of the items below are required
# only if you're going to use the python interface.
# the full path to the root TACS directory
TACS_DIR = C:/Users/qa21944/git/tacs
CXX = mpicxx
RM = rm -f
PYTHON = python
PYTHON_CONFIG = python-config
# Set up for parallel make
MAKE = make -j 8
# Set the ar flags
AR_FLAGS = rcs
# Flags for debugging and regular compilation versions
EXTRA_DEBUG_CC_FLAGS = -fPIC -g
EXTRA_CC_FLAGS = -fPIC -O3
# Use this if you have problems with mpich
# TACS_DEF = -DMPICH_IGNORE_CXX_SEEK
# Defines whether to use static or dynamic linking
# TACS_LD_CMD=${TACS_DIR}/lib/libtacs.a
TACS_LD_CMD=-L${TACS_DIR}/lib/ -Wl,-rpath,${TACS_DIR}/lib -ltacs
# For linux systems, use the following settings:
SO_EXT=so
SO_LINK_FLAGS=-fPIC -shared
# For MAC OS X, use the following settings:
# SO_EXT=so
# SO_LINK_FLAGS=-fPIC -dynamiclib
# This uses the default installation of LAPACK.
# Use an optimized version of LAPACK if available.
# You may also have to include -lblas as well.
LAPACK_LIBS = -LC:/SP_ROOT/lapack_windows/x64 -llapack -lpthread -lblas
# For MAC OSX use the accelerate framework
# LAPACK_LIBS=-framework accelerate
# METIS is handy for partitioning graphs, but can be problematic for
# compilation. If you compile METIS using a C++ compiler you must add
# -DTACS_CPLUSPLUS_METIS to the TACS_DEF arguments below. If you
# compile METIS using a C compiler, there should be no issues.
METIS_INCLUDE = -IC:/SP_ROOT/build/install/include
METIS_LIB = -LC:/SP_ROOT/build/install/lib -lmetis
# AMD is a set of routines for ordering matrices. It is not required by default.
AMD_INCLUDE = -IC:/SP_ROOT/build/install/include/suitesparse
AMD_LIBS = -LC:/SP_ROOT/build/install/lib -llibamd
Makefile
# ============================================
#
# Make file for TACS_DIR/
#
# ============================================
include Makefile.in
include TACS_Common.mk
TACS_SUBDIRS = src \
src/bpmat \
src/elements \
src/elements/dynamics \
src/elements/basis \
src/elements/shell \
src/constitutive \
src/functions \
src/io
TACS_OBJS := $(addsuffix /*.o, ${TACS_SUBDIRS})
default:
#if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "Building Complex TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $# in $$subdir"; \
echo; (cd $$subdir && $(MAKE) TACS_DIR=${TACS_DIR} TACS_DEF="${TACS_DEF} -DTACS_USE_COMPLEX") || exit 1; \
done \
else \
echo "Building Real TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $# in $$subdir"; \
echo; (cd $$subdir && $(MAKE) TACS_DIR=${TACS_DIR}) || exit 1; \
done \
fi
${CXX} ${SO_LINK_FLAGS} ${TACS_OBJS} ${TACS_EXTERN_LIBS} -o ${TACS_DIR}/lib/libtacs.${SO_EXT}
#if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "ctypedef complex TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_CDOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = complex" >> tacs/TacsDefs.pxi; \
else \
echo "ctypedef double TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_DOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = np.double" >> tacs/TacsDefs.pxi; \
fi
debug:
#if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "Building Complex TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $# in $$subdir"; \
echo; (cd $$subdir && $(MAKE) debug TACS_DIR=${TACS_DIR} TACS_DEF="${TACS_DEF} -DTACS_USE_COMPLEX") || exit 1; \
done \
else \
echo "Building Real TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $# in $$subdir"; \
echo; (cd $$subdir && $(MAKE) debug TACS_DIR=${TACS_DIR}) || exit 1; \
done \
fi
${CXX} ${SO_LINK_FLAGS} ${TACS_OBJS} ${TACS_EXTERN_LIBS} -o ${TACS_DIR}/lib/libtacs.${SO_EXT}
#if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "ctypedef complex TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_CDOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = complex" >> tacs/TacsDefs.pxi; \
else \
echo "ctypedef double TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_DOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = np.double" >> tacs/TacsDefs.pxi; \
fi
interface:
${PYTHON} setup.py build_ext --inplace
complex_interface:
${PYTHON} setup.py build_ext --inplace --define TACS_USE_COMPLEX
complex: TACS_IS_COMPLEX=true
complex: default
complex_debug: TACS_IS_COMPLEX=true
complex_debug: debug
clean:
${RM} lib/libtacs.a lib/libtacs.so
${RM} tacs/*.so tacs/*.cpp
#for subdir in $(TACS_SUBDIRS) ; do \
echo "making $# in $$subdir"; \
echo; \
(cd $$subdir && $(MAKE) $# TACS_DIR=${TACS_DIR}) || exit 1; \
done
Edit: I am adding a snippet of TACS_Common.mk as requested in the comments.
TACS_Common.mk
TACS_LIB = ${TACS_DIR}/lib/libtacs.a
TACS_INCLUDE = -I${TACS_DIR}/src \
-I${TACS_DIR}/src/bpmat \
-I${TACS_DIR}/src/elements \
-I${TACS_DIR}/src/elements/dynamics \
-I${TACS_DIR}/src/elements/basis \
-I${TACS_DIR}/src/elements/shell \
-I${TACS_DIR}/src/constitutive \
-I${TACS_DIR}/src/functions \
-I${TACS_DIR}/src/io
# Set the command line flags to use for compilation
TACS_OPT_CC_FLAGS = ${TACS_DEF} ${EXTRA_CC_FLAGS} ${METIS_INCLUDE} ${AMD_INCLUDE} ${TACS_INCLUDE}
TACS_DEBUG_CC_FLAGS = ${TACS_DEF} ${EXTRA_DEBUG_CC_FLAGS} ${METIS_INCLUDE} ${AMD_INCLUDE} ${TACS_INCLUDE}
# By default, use the optimized flags
TACS_CC_FLAGS = ${TACS_OPT_CC_FLAGS}
# Set the linking flags to use
TACS_EXTERN_LIBS = ${AMD_LIBS} ${METIS_LIB} ${LAPACK_LIBS}
TACS_LD_FLAGS = ${EXTRA_LD_FLAGS} ${TACS_LD_CMD} ${TACS_EXTERN_LIBS}
# This is the one rule that is used to compile all the
# source code in TACS
%.o: %.cpp
${CXX} ${TACS_CC_FLAGS} -c $< -o $*.o
#echo
#echo " --- Compiled $*.cpp successfully ---"
#echo
I can't answer but maybe I can orient you.
First nmake is not make. It will not work with any makefile not written specifically as an nmake makefile. And it's only available on Windows. So, best to just forget it exists.
Second, it's important to understand how make works: rules in makefiles are a combination of targets/prerequisites, and a recipe. The recipe is not in "makefile" syntax, it's a shell script (batch file). So make works in tandem with the shell, to run commands. Which shell? On POSIX systems like GNU/Linux and MacOS it's very simple: a POSIX shell; by default /bin/sh.
On Windows systems it's much less simple: there are a lot of options. It could be cmd.exe. It could be PowerShell. It could be a POSIX shell, that was installed by the user. Which one is chosen by default, depends on how your version of make was compiled. That's why you see different behaviors for different "ports" of make to Windows.
So, if you look at the makefiles you are trying to use you can see they are unquestionably written specifically for a POSIX system and expect a POSIX shell and a POSIX environment. Any attempt to use a version of make that invokes cmd.exe as its default shell will fail immediately with syntax errors ("" was unexpected at this time.).
OK, so you find a version of make that invokes a POSIX shell, and you don't get that error anymore.
But then you have to contend with another difference: directory separators. In Windows they use backslash. In POSIX systems, they use forward slash and backslash is an escape character (so it's not just passed through the shell untouched). If you are going to use paths in a POSIX shell, you need to make sure your paths use forward slashes else the shell will remove them as escape characters. Luckily, most Windows programs accept forward slashes as well as backslashes as directory separators (but not all: for example cmd.exe built-in tools do not).
Then you have to contend with the Windows abomination known as drive letters. This is highly problematic for make because to make, the : character is special in various places. So when make sees a line like C:/foo:C:/bar its parser will get confused, and you get errors. Some versions of make compiled for Windows enable a heuristic which tries to see if a path looks like a drive letter or not. Some just assume POSIX-style paths. They can also be a problem for the POSIX shell: many POSIX environments on Windows map drive letters to standard POSIX paths, so C:\foo is written as /c/foo or /mnt/c/foo or something else. If you are adding paths to your makefile you need to figure out what the right mapping, if any, is and use that.
That's not even to start discussing the other differences between POSIX and Windows... there are so many.
From what you've shown above, this project was not written with any sort of portability to Windows in mind. Given the complexity of this, that's not surprising: it takes a huge amount of work. So you have these options that I can see:
Port it yourself to be Windows-compatible
Try to get it working inside cygwin (cygwin is intended to be a POSIX-style environment that runs on Windows)
Try to get it working in WSL
Install a virtual machine using VMWare, VirtualBox, etc. running a Linux distribution and build and run it there
Unfortunately I don't know much about the pros and cons of these approaches so I can't advise you as to the best course.
The route I chose, long long ago, was to get rid of Windows entirely and just use GNU/Linux. But of course that won't be possible for everyone :).
You need a real answer: you can't compile using the Windows Command Prompt.
Get yourself MSYS2 -- which will also install MinGW-w64 -- and follow the setup instructions. Then launch the MSYS shell to get a unix-y terminal prompt (zsh, IIRC), and change directory to the head of the project folder.
To access the Windows filesystem the root directory will be either /c or /mnt/c (sorry, on my mobile ATM, I can improve this in a day or two). For example,
C:\Users\qa21944\git\tacs
becomes
/c/Users/qa21944/git/tacs
From there the GNU/Windows make command should work:
mingw32-make
There is also this post to use more modern *nix environments under Windows:
How to install and use "make" in Windows?
Thanks may be overkill for what you need, though.
When I finish traveling and can sit down to look at this properly I can improve this answer's details, but getting a Linux shell terminal is what you need.

Bitbake cannot find the header file of another recipe

I am having a package which is depending on asterisk. As it is depending on asterisk I included DEPENDS = "asterisk" in bitbake file.But my source package cannot locate "asterisk.h" which is available in asterisk package.I tried "bitbake asterisk -c listtasks" in this command [do_populate_sysroot] was available.But from where bitbake is expecting the asterisk.h to reside, so that it can fetch from there.
Following is the log error I am getting while compiling my recipe.
checking for string.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for termios.h... (cached) yes
checking whether asterisk.h in ../include... no
checking whether asterisk.h in /usr/include... no
checking whether asterisk.h in /usr/local/include... no
checking whether asterisk.h in /opt/local/include... no
configure: error: Can't find "asterisk.h"
NOTE: The following config.log files may provide further information.
We can use provider and user to illustrate this case, the package (recipe) provides a header file to be used by another package (recipe) is the provider, the package (recipe) use a header file from another package (recipe) is the user.
First we change the provider's recipe (myprovider.bb) to export the header file -- myapi.h,
...
do_install() {
install -d ${D}/${bindir}
install -m 755 ${B}/hello_provider ${D}/${bindir}
install -d ${D}${libdir}/lib_myprovider/
install -m 0755 ${WORKDIR}/myapi.h ${STAGING_DIR_TARGET}${libdir}/lib_myprovider/
}
...
Secondly we change the user's recipe (myuser.bb) to refer the header file -- myapi.h
...
do_compile () {
${CC} ${WORKDIR}/main.c -o hello_user ${CFLAGS} ${LDFLAGS} -I${STAGING_DIR_TARGET}/${libdir}/lib_myprovider/
}
# file dependency declaration
FILES_${PN} = "${libdir}/lib_myprovider"
# package dependency declaration
DEPENDS += "myprovider"
...
At last, rebuild myprovider.bb and myuser.bb recipes, it should work.

local header files available in the project but make gives No such file or directory error

From entire day I am trying to install OverSim [http://www.oversim.org/wiki/OverSimInstall]
The make file looks like this:
all: checkmakefiles
cd src && $(MAKE)
clean: checkmakefiles
cd src && $(MAKE) clean
cleanall: checkmakefiles
cd src && $(MAKE) MODE=release clean
cd src && $(MAKE) MODE=debug clean
rm -f src/Makefile
makefiles:
cd src && opp_makemake -f --deep --make-so -o inet -O out $$NSC_VERSION_DEF
checkmakefiles:
#if [ ! -f src/Makefile ]; then \
echo; \
echo '======================================================================='; \
echo 'src/Makefile does not exist. Please use "make makefiles" to generate it!'; \
echo '======================================================================='; \
echo; \
exit 1; \
fi
doxy:
doxygen doxy.cfg
tcptut:
cd doc/src/tcp && $(MAKE)
I am using Omnet5.1.1 as omnet4.2.2 is not supported on Ubuntu16.04, my gcc version is 5.4.1.
Every time I try to build this make all, it gives header file not found error where as in actual the header files are present inside the project directory.
In file included from applications/ethernet/EtherAppCli.cc:21:0:
applications/ethernet/EtherAppCli.h:21:22: fatal error: INETDefs.h: No such file or directory
The includes are done like this:
#include "INETDefs.h" //available at src/linklayer/contract/
#include "MACAddress.h" //available at src/base/
project structure:
How could I resolve this build error?
This is a basic difference between newer OMNeT++ versions 5.x and the older OMNeT++ versions 3.x and 4.x.
As far as I remember Oversim, it was released for build with OMNeT 3.x and 4.2 as well as the older INET releases.
These old versions used parameters like --deep to search for include files, that's why the included files are just named and not entered with a complete path.
The newer INET and OMNeT releases use hierarchical path settings for include files. The complete paths have to be given for the compiler to access the included file.
So for INET version 3.x and OMNeT++ version 5.x, an include looks like: #include "inet/common/INETDefs.h"
Oversim does not include the complete paths for included headers, that's why you have errors when using Oversim with newer OMNeT releases.
The first option is to either use an older OMNeT version. Either install an older GCC in parallel on your system or set-up a virtual machine with an older Ubuntu if you like.
The second (and more complex) option is to adopt all include paths or define all necessary paths via the -I option of the compiler/linker.
Frankly, I'd suggest to use the older OMNeT++ 4.2.2 version...
The #include directive searches first of all inside the same directory as the file containing the directive and then in a preconfigured list of standard system directories.
If you don't want to move the header files to the same directory as EtherAppCli.cc, you will have to add the paths to these header files to this preconfigured list, usually with the compiler option
-Ipath/to/dir
I'm not sure if this is what is intended in the app your'e compiling but this is more or less what you can do.
Check to see if you missed anything in the installation guide.
Use OMNet 4.6 instead. Keep using inet-20111118. You should be able to build inet normally. Then build Oversim

GCC & binutils build - C compiler cannot create executables

I'm trying to build gcc-5.3 and binutils-2.26. I've done it like this:
mkdir gcc; cd gcc
wget http://path/to/gcc-5.3.0.tar.bz2
wget http://path/to/binutils-2.26.tar.bz2
tar xf gcc-5.3.0.tar.bz2
tar xf binutils-2.26.tar.bz2
cd gcc-5.3.0
contrib/download_prerequisites
for file in ../binutils-2.26/*; do ln -s "${file}"; done
cd ..
mkdir build
mkdir dist
cd build
../gcc-5.3.0/configure --prefix=/home/teamcity/gcc/dist --disable-multilib --with-system-zlib --enable-languages=c,c++,fortran --program-suffix=-mine
make
This appears to build the first stage executables okay; prev-gas, prev-gcc, prev-ld are all present with plausible-looking executables in them. But the next stage fails:
Configuring stage 2 in ./intl
configure: loading cache ./config.cache
checking whether make sets $(MAKE)... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether NLS is requested... yes
checking for msgfmt... /usr/bin/msgfmt
checking for gmsgfmt... /usr/bin/msgfmt
checking for xgettext... /usr/bin/xgettext
checking for msgmerge... /usr/bin/msgmerge
checking for x86_64-unknown-linux-gnu-gcc... /home/teamcity/gcc/build/./prev-gcc/xgcc -B/home/teamcity/gcc/build/./prev-gcc/ -B/home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/bin/ -B/home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/bin/ -B/home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/lib/ -isystem /home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/include -isystem /home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/sys-include -L/home/teamcity/gcc/build/./ld
checking for C compiler default output file name...
configure: error: in `/home/teamcity/gcc/build/intl':
configure: error: C compiler cannot create executables
See `config.log' for more details.
The relevant bit of config.log appears to be this:
configure:2978: checking for C compiler default output file name
configure:3000: /home/teamcity/gcc/build/./prev-gcc/xgcc -B/home/teamcity/gcc/build/./prev-gcc/ -B/home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/bin/ -B/home/teamcity/gcc/dist/x86_64-unkn
own-linux-gnu/bin/ -B/home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/lib/ -isystem /home/teamcity/gcc/dist/x86_64-unknown-linux-gnu/include -isystem /home/teamcity/gcc/dist/x86_64-unknown-l
inux-gnu/sys-include -L/home/teamcity/gcc/build/./ld -g -O2 -gtoggle -static-libstdc++ -static-libgcc conftest.c >&5
/home/teamcity/gcc/build/./prev-gcc/as: 106: exec: /home/teamcity/gcc/build/./gas/as-new: not found
This looks like prev-gcc's as is expecting to find gas/as-new, when actually it's prev-gas/as-new.
Is there some workaround for this? Is it safe to just ln -s prev-gas gas? I'd sort of expect that to cause problems later on. Is it not possible to build these two versions of gcc and binutils together?
This is my edited answer after trying it on my own on an Ubuntu 14.04 Azure VM.
The following approach worked for me:
Build and install binutils 2.26; for the purposes of this discussion,
let's say it's installed in /opt/gcc-5.3.0.
Configure gcc-5.3.0 in a build directory using /root/objdir/../gcc-5.3.0/configure --prefix=/opt/gcc-5.3.0
--enable-languages=c,c++ --disable-multilib --with-ld=/opt/gcc-5.3.0/bin/ld --with-as=/opt/gcc-5.3.0/bin/as assuming gcc-5.3.0 and the build directory, objdir, are at the same
level.
Do make followed by make install in the objdir build directory.
To verify that the ld used by the newly-built gcc is the one from the new binutils:
/opt/gcc-5.3.0/bin/gcc -print-prog-name=ld
The output should be, in this example:
/opt/gcc-5.3.0/bin/ld
Another test: rename the system ld, in my case /usr/bin/ld; the newly-built gcc should still work.
Of course, this applies to both ld and as.
Setting AS and LD environment variables to point to the newly-built binaries from the binutils package did not work: the -print-prog-name=... still showed default tools, and removing/renaming the default tools caused gcc to fail.
Thus the best way of accomplishing this is to build binutils first and then use the --with-ld and --with-as options to configure. If you also want to ensure that the newly-built binutils are used to build GCC, you may want to put them in the PATH before the system-provided tools, or you can even rename the system-provided tools to keep them out of the picture.
Thank you for checking with another mailing list to verify that building GCC and binutils together doesn't work unless they are pulled from the source control, I guess that option is not applicable when using downloaded tarballs. Overall this was an interesting exercise.

How can I set rpath on gcc binaries during bootstrap?

I am trying to build gcc 4.7.2 using a custom prefix $PREFIX
I have built and installed all the prerequisites into my prefix location, and then successfully configured, built and installed gcc.
The problem that I now have is that $PREFIX is not in the library search path, and therefore the shared libraries cannot be found.
$PREFIX/bin $ ./g++ ~/main.cpp
$PREFIX/libexec/gcc/x86_64-suse-linux/4.7.2/cc1plus: \
error while loading shared libraries: \
libcloog-isl.so.1: \
cannot open shared object file: No such file or directory
What works, but isn't ideal
If I export LD_LIBRARY_PATH=$PREFIX/lib then it works, but I'm looking for something which works without having to set environment variables.
If I use patchelf to set the RPATH on all the gcc binaries then it also works; however this involves searching out all elf binaries and iterating over them calling patchelf, I would rather have something more permanent.
What I think would be ideal for my purposes
So I'm hoping there is a way to have -Wl,-rpath,$PREFIX/lib passed to make during the build process.
Since I know the paths won't need to be changed this seems like the most robust solution, and can be also be used for when we build the next gcc version.
Is configuring the build process to hard code the RPATH possible?
What I have tried, but doesn't work
Setting LDFLAGS_FOR_TARGET prior to calling configure:
All of these fail:
export LDFLAGS_FOR_TARGET="-L$PREFIX/lib -R$PREFIX/lib"
export LDFLAGS_FOR_TARGET="-L$PREFIX/lib"
export LDFLAGS_FOR_TARGET="-L$PREFIX/lib -Wl,-rpath,$PREFIX/lib"
Setting LDFLAGS prior to calling configure:
export LDFLAGS="-L$PREFIX/lib -Wl,-rpath,$PREFIX/lib"
In any event I worry that these will override any of the LDFLAGS gcc would have had, so I'm not sure these are a viable option even if they could be made to work?
My configure line
For completeness here is the line I pass to configure:
./configure \
--prefix=$PREFIX \
--build=x86_64-suse-linux \
--with-pkgversion='SIG build 12/10/2012' \
--disable-multilib \
--enable-cloog-backend=isl \
--with-mpc=$PREFIX \
--with-mpfr=$PREFIX \
--with-gmp=$PREFIX \
--with-cloog=$PREFIX \
--with-ppl=$PREFIX \
--with-gxx-include-dir=$PREFIX/include/c++/4.7.2
I've found that copying the source directories for gmp, mpfr, mpc, isl, cloog, etc. into the top level gcc source directory (or using symbolic links with the same name) works everywhere. This is in fact the preferred way.
You need to copy (or link) to those source directory names without the version numbers for this to work.
The compilers do not need LD_LIBRARY_PATH (although running applications built with the compilers will need an LD_LIBRARY_PATH to the $PREFIX/lib64 or something like that - but that's different)
Start in a source directory where you'll keep all your sources.
In this source directory you have your gcc directory either by unpacking a tarball or svn...
I use subversion.
Also in this top level directory you have, say, the following source tarballs:
gmp-5.1.0.tar.bz2
mpfr-3.1.1.tar.bz2
mpc-1.0.1.tar.gz
isl-0.11.1.tar.bz2
cloog-0.18.0.tar.gz
I just download these and update to the latest tarballs periodically.
In script form:
# Either:
svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc_work
# Or:
bunzip -c gcc-4.8.0.tar.bz2 | tar -xvf -
mv gcc-4.8.0 gcc_work
# Uncompress sources.. (This will produce version numbered directories).
bunzip -c gmp-5.1.0.tar.bz2 | tar -xvf -
bunzip -c mpfr-3.1.1.tar.bz2 | tar -xvf -
gunzip -c mpc-1.0.1.tar.gz | tar -xvf -
bunzip -c isl-0.11.1.tar.bz2 | tar -xvf -
gunzip -c cloog-0.18.0.tar.gz | tar -xvf -
# Link outside source directories into the top level gcc directory.
cd gcc_work
ln -s ../gmp-5.1.0 gmp
ln -s ../mpfr-3.1.1 mpfr
ln -s ../mpc-1.0.1 mpc
ln -s ../isl-0.11.1 isl
ln -s ../cloog-0.18.0 cloog
# Get out of the gcc working directory and create a build directory. I call mine obj_work.
# I configure the gcc binary and other outputs to be bin_work in the top level directory. Your choice. But I have this:
# home/ed/projects
# home/ed/projects/gcc_work
# home/ed/projects/obj_work
# home/ed/projects/bin_work
# home/ed/projects/gmp-5.1.0
# home/ed/projects/mpfr-3.1.1
# home/ed/projects/mpc-1.0.1
# home/ed/projects/isl-0.11.1
# home/ed/projects/cloog-0.18.0
mkdir obj_work
cd obj_work
../gcc_work/configure --prefix=../bin_work <other options>
# Your <other options> shouldn't need to involve anything about gmp, mpfr, mpc, isl, cloog.
# The gcc build system will find the directories you linked,
# then configure and compile the needed libraries with the necessary flags and such.
# Good luck.
I've been using this configure option with gcc-4.8.0, on FreeBSD, after building and installing gmp, isl and cloog:
LD_LIBRARY_PATH=/path/to/isl/lib ./configure (lots of other options) \
--with-stage1-ldflags="-rpath /path/to/isl/lib -rpath /path/to/cloog/lib -rpath /path/to/gmp/lib"
and the resulting gcc binary does not need any LD_LIBRARY_PATH. The LD_LIBRARY_PATH for configure is needed because it compiles a test program to check for the ISL version, which would fail if it didn't find the ISL shared lib.
I tried it on Linux (Ubuntu) where it failed during configuring because the -rpath args were passed to gcc instead of ld. I could fix this by using
--with-stage1-ldflags="-Wl,-rpath,/path/to/isl/lib,-rpath,/path/to/cloog/lib,-rpath,/path/to/gmp/lib"
instead.
Just using configure --with-stage1-ldflags="-Wl,-rpath,/path/to/lib" was not enough for me to build gcc 4.9.2, bootstrap failed in stage 2. What works is to pass he flags directly to make via
make BOOT_LDFLAGS="-Wl,-rpath,/path/to/lib"
I got this from https://gcc.gnu.org/ml/gcc/2008-09/msg00214.html
While it still involves setting environment variables, what I do is that I define LD_RUN_PATH, which sets the rpath. That way the rest of the system can keep using the system provided libraries instead of using the ones that your gcc build generates.
I am going to make a suggestion that I believe solves your problem, although it definitely does not answer your question. Let's see how many downvotes I get.
Writing a generic wrapper script to set LD_LIBRARY_PATH and then to run the executable is easy; see https://stackoverflow.com/a/7101577/768469.
The idea is to pass something like --prefix=$PREFIX/install to configure, building an install tree that looks like this:
$PREFIX/
install/
lib/
libcloogXX.so
libgmpYY.so
...
bin/
gcc
emacs
...
bin/
.wrapper
gcc -> .wrapper
emacs -> .wrapper
.wrapper is a simple shell script:
#!/bin/sh
here="${0%/*}" # or use $(dirname "$0")
base="${0##*/}" # or use $(basename "$0")
libdir="$here"/../install/lib
if [ "$LD_LIBRARY_PATH"x = x ] ; then
LD_LIBRARY_PATH="$libdir"
else
LD_LIBRARY_PATH="$libdir":"$LD_LIBRARY_PATH"
fi
export LD_LIBRARY_PATH
exec "$here"/../install/bin/"$base" "$#"
This will forward all arguments correctly, handle spaces in arguments or directory names, and so forth. For practical purposes, it is indistinguishable from setting the rpath like you want.
Also, you can use this approach not only for gcc, but for your entire my-personal-$PREFIX tree. I do this all the time in environments where I want an up-to-date suite of GNU tools, but I do not have (or want to admit to have) root access.
Try to add your $PREFIX to /etc/ld.so.conf and then run ldconfig:
# echo $PREFIX >> /etc/ld.so.conf
# ldconfig
This will recreate cache that is used by runtime linker and it will pick up your libraries.
WARNING: This operation will cause ALL applications to use your newly compiled libraries in $PREFIX instead of default location