Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Trying gcc5 rather then 4.9
  • Loading branch information
mithro committed Sep 9, 2015
1 parent 7cca06d commit 219f00d
Show file tree
Hide file tree
Showing 7 changed files with 369 additions and 0 deletions.
47 changes: 47 additions & 0 deletions conda/gcc5-lm32-linux/build.sh
@@ -0,0 +1,47 @@
#!/bin/bash

rm -rf libstdc++-v3

if [ "$(uname)" == "Darwin" ]; then
export DYLD_LIBRARY_PATH="$PREFIX/lib/"
export LDFLAGS="-Wl,-headerpad_max_install_names"
export BOOT_LDFLAGS="-Wl,-headerpad_max_install_names"

./configure \
--prefix="$PREFIX" \
--libdir="$PREFIX/lib" \
--with-gmp="$PREFIX" \
--with-mpfr="$PREFIX" \
--with-mpc="$PREFIX" \
--with-isl="$PREFIX" \
--with-cloog="$PREFIX" \
--with-boot-ldflags="$LDFLAGS" \
--with-stage1-ldflags="$LDFLAGS" \
--enable-checking=release \
--disable-multilib \
--target=lm32-elf \
--enable-languages="c,c++" \
--disable-libgcc \
--disable-libssp
else
# For reference during post-link.sh, record some
# details about the OS this binary was produced with.
mkdir -p "${PREFIX}/share"
cat /etc/*-release > "${PREFIX}/share/conda-gcc-build-machine-os-details"
./configure \
--prefix="$PREFIX" \
--libdir="$PREFIX/lib" \
--with-gmp="$PREFIX" \
--with-mpfr="$PREFIX" \
--with-mpc="$PREFIX" \
--with-isl="$PREFIX" \
--with-cloog="$PREFIX" \
--enable-checking=release \
--disable-multilib \
--target=lm32-elf \
--enable-languages="c,c++" \
--disable-libgcc \
--disable-libssp
fi
make -j"$CPU_COUNT"
make install-strip
37 changes: 37 additions & 0 deletions conda/gcc5-lm32-linux/meta.yaml
@@ -0,0 +1,37 @@
package:
name: gcc-5
version: 5.2.0

source:
fn: gcc-5.2.0.tar.bz2
url: http://www.netgull.com/gcc/releases/gcc-5.2.0/gcc-5.2.0.tar.bz2
md5: a51bcfeb3da7dd4c623e27207ed43467

build:
detect_binary_files_with_prefix: true # [not linux32]
number: 0

requirements:
build:
# These are taken from the output of the configure scripts
- gmp >=4.3.2
- mpfr >=2.4.2
- mpc >=0.8.1
- isl
- cloog 0.18.0
# Do not make gcc a build dependency (you will need to add it to the PATH manually)
run:
- gmp >=4.2
- mpfr >=2.4.0
- mpc >=0.8.0
- isl
- cloog 0.18.0

test:
commands:
- gcc --help

about:
home: http://gcc.gnu.org/
summary: The GNU Compiler Collection
license: GPL
20 changes: 20 additions & 0 deletions conda/gcc5-lm32-linux/notes.md
@@ -0,0 +1,20 @@
Tools that are necessary for building GCC:
https://gcc.gnu.org/install/prerequisites.html

This package is known to be able to build on CentOS 5.11 with gcc 4.1.2.
The Docker centos:5.11 image was used and the following packages installed:

* required to unpack GCC sources:
tar bzip2
* required to build GCC:
gcc gcc-c++ make zip

We do not require gcc as a build dependency because we want to make sure that
conda build finds all the files installed for this gcc when creating the
package. So you will need to make sure that the gcc is on the PATH
independently.

On OS X, the dylibs libgcc_ext.10.4.dylib and libgcc_ext.10.5.dylib are Mach-O
stub files, which install_name_tool cannot modify. So we have to use the
binary replacement to change the RPATH in those files, and in a few other
dylibs that pull in the paths from those files.
173 changes: 173 additions & 0 deletions conda/gcc5-lm32-linux/post-link.sh
@@ -0,0 +1,173 @@
#!/bin/bash

if [ "$(uname)" == "Darwin" ]; then
# This post-link script is to fix portability problems
# with our gcc package on Linux. It isn't needed on OSX.
exit 0;
fi

build_os_md5=( $(md5sum "${PREFIX}/share/conda-gcc-build-machine-os-details") )
target_os_md5=( $(cat /etc/*-release | md5sum) )

# No need to make any portability fixes if
# we're deploying to the same OS we built with.
if [[ "${build_os_md5[0]}" == "${target_os_md5[0]}" ]]; then
echo "gcc install OS matches gcc build OS: Skipping post-link portability fixes."
else

# In this script, we attempt to fix 3 Linux distro portability issues:

#
# Linux Portability Issue #1: "fixed includes"
#

# Remove the headers that gcc "fixed" as part of the gcc build process.
# They kill the gcc binary's portability to other systems,
# and shouldn't be necessary on ANSI-compliant systems anyway.
# See this informative writeup of the problem:
# http://ewontfix.com/12/
#
# More discussion can be found here:
# https://groups.google.com/a/continuum.io/d/msg/conda/HwUazgD-hJ0/aofO0vD-MhcJ
while read -r x ; do
grep -q 'It has been auto-edited by fixincludes from' "${x}" \
&& rm -f "${x}"
done < <(find "${PREFIX}"/lib/gcc/*/*/include*/ -name '*.h')

#
# Linux Portability Issue #2: linker needs to locate crtXXX.o
#

# Locate the system's C-runtime object files and link them into the gcc
# build so they are automatically on the gcc search path.
# (The location of these files varies from one system to the next.)
C_RUNTIME_OBJ_FILES="crt0.o crt1.o crt2.o crt3.o crti.o crtn.o"

c_runtime_obj_files_found=0

# Try locating crtXXX.o in default library search paths
for library_path in $(ld --verbose | grep SEARCH_DIR | sed -r 's/SEARCH_DIR\("=?([^"]*)"\);/ \1/g'); do
for obj_file in $C_RUNTIME_OBJ_FILES; do
obj_file_full_path="$library_path/$obj_file"
if [[ -e "$obj_file_full_path" ]]; then
ln -s "$obj_file_full_path" "${PREFIX}/lib/gcc/"*/*/
c_runtime_obj_files_found=1
fi
done
if [ $c_runtime_obj_files_found -eq 1 ]; then
break
fi
done

# Fallback to locating crtXXX.o with system gcc we if couldn't find it in usual places
if [ $c_runtime_obj_files_found -ne 1 ]; then
echo "Couldn't locate crtXXX.o in default library search paths. You may not have it " \
"at all. It is usually packaged in libc6-dev/glibc-devel packages. We will try " \
"to locate crtXXX.o with system installed gcc..."

SYSTEM_GCC=/usr/bin/gcc

if [ -e "${SYSTEM_GCC}" ]; then
for obj_file in $C_RUNTIME_OBJ_FILES; do
obj_file_full_path=$($SYSTEM_GCC -print-file-name="$obj_file")
if [[ "$obj_file_full_path" != "$obj_file" ]]; then
ln -s "$obj_file_full_path" "${PREFIX}/lib/gcc/"*/*/
c_runtime_obj_files_found=1
fi
done
else
echo "There is no $SYSTEM_GCC"
fi
fi

if [ $c_runtime_obj_files_found -ne 1 ]; then
>&2 echo "*** Can't install the gcc package unless your system has crtXXX.o. ***"
exit 1
fi

#
# Linux Portability Issue #3: Compiler needs to locate system headers
#

# Some distros use different system include paths than the ones this gcc binary was built for.
# We'll add these to the standard include path by providing a custom "specs file"

# First create specs file from existing defaults
SPECS_DIR=$(echo "${PREFIX}"/lib/gcc/*/*)
SPECS_FILE="${SPECS_DIR}/specs"
gcc -dumpspecs > "${SPECS_FILE}"

# Now add extra include paths to the specs file, one at a time.
# (So far we only know of one: from Ubuntu.)
EXTRA_SYSTEM_INCLUDE_DIRS="/usr/include/x86_64-linux-gnu /usr/include/i686-linux-gnu /usr/include/i386-linux-gnu"

for INCDIR in ${EXTRA_SYSTEM_INCLUDE_DIRS}; do
# The following sed command will replace these two lines:
# *cpp:
# ... yada yada ...
#
# With these two lines:
# *cpp:
# ... yada yada ... -I${INCDIR}
sed -i ':a;N;$!ba;s|\(*cpp:\n[^\n]*\)|\1 -I'${INCDIR}'|g' "${SPECS_FILE}"
done
fi

## TEST: Here we verify that gcc can build a simple "Hello world" program for both C and C++.
##
## Note: This tests the gcc package's ability to actually function as a compiler.
## Therefore, packages should never depend on the gcc package as a 'run' dependency,
## i.e. just for its packaged libraries (they should depend on 'libgcc' instead).
## That way, if there are systems which can't use this gcc package for its
## compiler (due to portability issues) can still use packages produced with it.

workdir=$(mktemp -d XXXXXXXXXX) && cd "$workdir"

# Write test programs.
cat > hello.c <<EOF
#include <stdio.h>
int main()
{
printf("Hello, world! I can compile C.\n");
return 0;
}
EOF

cat > hello.cpp <<EOF
#include <iostream>
int main()
{
std::cout << "Hello, world! I can compile C++." << std::endl;
return 0;
}
EOF

set +e

# Compile.
(
set -e
"${PREFIX}/bin/lm32-elf-gcc" -o hello_c.out hello.c
"${PREFIX}/bin/lm32-elf-g++" -o hello_cpp.out hello.cpp
)
SUCCESS=$?
if [ $SUCCESS -ne 0 ]; then
echo "Installation failed: gcc is not able to compile a simple 'Hello, World' program."
cd .. && rm -r "$workdir"
exit 1;
fi

# Execute the compiled output.
(
set -e
file ./hello_c.out
file ./hello_cpp.out
)
SUCCESS=$?
if [ $SUCCESS -ne 0 ]; then
echo "Installation failed: Compiled test program did not execute cleanly."
cd .. && rm -r "$workdir"
exit 1;
fi

cd .. && rm -r "$workdir"
15 changes: 15 additions & 0 deletions conda/gcc5-lm32-linux/pre-unlink.sh
@@ -0,0 +1,15 @@
#!/bin/bash

if [ "$(uname)" == "Darwin" ]; then
# The post-link script only runs on Linux,
# so this pre-unlink script isn't needed on OSX.
exit 0;
fi

# Remove the crt symlinks created in post-link.sh
find "$PREFIX"/lib/gcc/*/* -type l -print0 | xargs -0 rm -f

# Remove the gcc specs file we created in post-link.sh
SPECS_DIR=$(echo "${PREFIX}"/lib/gcc/*/*)
SPECS_FILE="${SPECS_DIR}/specs"
rm -f "${SPECS_FILE}"
22 changes: 22 additions & 0 deletions conda/gcc5-lm32-linux/run_test.py
@@ -0,0 +1,22 @@
import subprocess
import os

def otool(path):
"thin wrapper around otool -L"
lines = subprocess.check_output(['otool', '-L', path]).decode('utf-8').splitlines()
assert lines[0].startswith(path), path
res = []
for line in lines[1:]:
assert line[0] == '\t'
res.append(line.split()[0])
return res

def assert_relative_osx(path):
for name in otool(path):
assert not 'placehold' in name, path

prefix = os.environ['PREFIX']

for f in os.listdir(os.path.join(prefix, 'lib')):
if f.endswith('dylib'):
assert_relative_osx(os.path.join(prefix, 'lib', f))
55 changes: 55 additions & 0 deletions conda/gcc5-lm32-linux/run_test.sh
@@ -0,0 +1,55 @@
#
# TEST: Here we verify that gcc can build a simple "Hello world" program for both C and C++.
#

workdir=$(mktemp -d XXXXXXXXXX) && cd "$workdir"

# Write test programs.
cat > hello.c <<EOF
#include <stdio.h>
int main()
{
printf("Hello, world! I can compile C.\n");
return 0;
}
EOF

cat > hello.cpp <<EOF
#include <iostream>
int main()
{
std::cout << "Hello, world! I can compile C++." << std::endl;
return 0;
}
EOF

set +e

# Compile.
(
set -e
"${PREFIX}/bin/lm32-elf-gcc" -o hello_c.out hello.c
"${PREFIX}/bin/lm32-elf-g++" -o hello_cpp.out hello.cpp
)
SUCCESS=$?
if [ $SUCCESS -ne 0 ]; then
echo "Build failed: gcc is not able to compile a simple 'Hello, World' program."
cd .. && rm -r "$workdir"
exit 1;
fi

# Execute the compiled output.
(
set -e
file ./hello_c.out
file ./hello_cpp.out
)
SUCCESS=$?
if [ $SUCCESS -ne 0 ]; then
echo "Build failed: Compiled test program did not execute cleanly."
cd .. && rm -r "$workdir"
exit 1;
fi

cd .. && rm -r "$workdir"

0 comments on commit 219f00d

Please sign in to comment.