anaconda / docker-images

Repository of Docker images created by Anaconda
https://hub.docker.com/u/continuumio/
833 stars 282 forks source link

Unable to build a simple program with gcc provided in docker image #48

Closed 183amir closed 7 years ago

183amir commented 7 years ago

I am using the continuumio/conda_builder_linux:latest image and start the image with the build64/start_cpp98.sh script that is provided but I fail to compile a simple program with boost and conda-build.

The test cpp code is this:

#include <boost/filesystem.hpp>

int main() {
  boost::filesystem::path("a.out").extension().c_str();
}

The recipe to build it with conda-build is this:

package:
  name: test
  version: 0.0.1

source:
  path: test.cpp

build:
  script:
    - g++ test.cpp -I ${CONDA_DEFAULT_ENV}/include/ -L ${CONDA_DEFAULT_ENV}/lib -lboost_filesystem -lboost_system
    - cp a.out ${PREFIX}/bin/

requirements:
  build:
    - python 2.7*
    - boost 1.61.0
  run:
    - python 2.7*
    - boost 1.61.0

test:
  commands:
    - a.out

And these are the commands that I run:

$ ./start_cpp98.sh --rm=true -v ~/recipes/:/recipes

Welcome to the conda-builder image, brought to you by Continuum Analytics.

Binaries produced with this image should be compatible with any Linux OS
that is at least CentOS 5 or newer (Glibc lower bound), and anything 
that uses G++ 5.2 or older (libstdc++ upper bound)

    GCC is: gcc (GCC) 5.2.0
    Default C++ ABI: 4 (C++98)
    GLIBC is: glibc 2.5
    ld/binutils is: GNU ld (GNU Binutils) 2.26.20160125

    Native arch is x86_64.  To build 32-bit code, set the ARCH environment
        variable to 32. (-e "ARCH=32" docker argument)

    The dev user (currently signed in) has passwordless sudo access.
    miniconda (2.7) is installed at /opt/miniconda.
    git is also available.
    Your .gitconfig has been imported.

Helpful aliases:
    clone_recipes: clones the conda/conda-recipes repo from Github
    clone_anaconda: clones the continuumIO/anaconda (private) repo from Github
    anaconda_setup: clones anaconda repo and sets up continuum internal build system.

[dev@63520f40e292 ~]$ conda build /recipes/test
BUILD START: test-0.0.1-0
updating index in: /opt/miniconda/conda-bld/linux-64
updating index in: /opt/miniconda/conda-bld/noarch

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    icu-54.1                   |                0        11.3 MB
    xz-5.2.2                   |                1         669 KB
    python-3.5.2               |                0        17.2 MB
    boost-1.61.0               |           py35_0        16.3 MB
    setuptools-27.2.0          |           py35_0         526 KB
    wheel-0.29.0               |           py35_0          82 KB
    pip-9.0.1                  |           py35_1         1.7 MB
    ------------------------------------------------------------
                                           Total:        47.7 MB

The following NEW packages will be INSTALLED:

    boost:      1.61.0-py35_0
    icu:        54.1-0       
    openssl:    1.0.2j-0     
    pip:        9.0.1-py35_1 
    python:     3.5.2-0      
    readline:   6.2-2        
    setuptools: 27.2.0-py35_0
    sqlite:     3.13.0-0     
    tk:         8.5.18-0     
    wheel:      0.29.0-py35_0
    xz:         5.2.2-1      
    zlib:       1.2.8-3      

WARNING: conda-build appears to be out of date. You have version 2.0.11 but the
latest version is 2.1.0. Run

conda update -n root conda-build

to get the latest version.

Copying /recipes/test/test.cpp to /opt/miniconda/conda-bld/test_1483546947159/work
Package: test-0.0.1-0
source tree in: /opt/miniconda/conda-bld/test_1483546947159/work
+ source /opt/miniconda/bin/activate /opt/miniconda/conda-bld/test_1483546947159/_b_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac
+ g++ test.cpp -I /opt/miniconda/conda-bld/test_1483546947159/_b_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac/include/ -L /opt/miniconda/conda-bld/test_1483546947159/_b_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac/lib -lboost_filesystem -lboost_system
+ cp a.out /opt/miniconda/conda-bld/test_1483546947159/_b_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac/bin/
number of files: 1
Fixing permissions
patchelf: file: /opt/miniconda/conda-bld/test_1483546947159/_b_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac/bin/a.out
    setting rpath to: $ORIGIN/../lib
Fixing permissions
updating index in: /opt/miniconda/conda-bld/linux-64
updating: test-0.0.1-0.tar.bz2
TEST START: test-0.0.1-0
updating index in: /opt/miniconda/conda-bld/linux-64
updating index in: /opt/miniconda/conda-bld/noarch

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    test-0.0.1                 |                0           7 KB  local

The following NEW packages will be INSTALLED:

    boost:      1.61.0-py35_0      
    icu:        54.1-0             
    openssl:    1.0.2j-0           
    pip:        9.0.1-py35_1       
    python:     3.5.2-0            
    readline:   6.2-2              
    setuptools: 27.2.0-py35_0      
    sqlite:     3.13.0-0           
    test:       0.0.1-0       local
    tk:         8.5.18-0           
    wheel:      0.29.0-py35_0      
    xz:         5.2.2-1            
    zlib:       1.2.8-3            

WARNING: conda-build appears to be out of date. You have version 2.0.11 but the
latest version is 2.1.0. Run

conda update -n root conda-build

to get the latest version.

+ source /opt/miniconda/bin/activate /opt/miniconda/conda-bld/test_1483546947159/_t_env
+ /bin/bash -x -e /opt/miniconda/conda-bld/test_1483546947159/test_tmp/run_test.sh
+ a.out
/opt/miniconda/conda-bld/test_1483546947159/test_tmp/run_test.sh: line 3:   140 Segmentation fault      (core dumped) a.out
TESTS FAILED: test-0.0.1-0

It segfaults. This is easily reproducible through this test code that I have provided here. It segfaults on ArchLinux's gcc too:

$ g++ --version
g++ (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

but it compiles fine when I use the gcc and libgcc packages from the defaults channel:

package:
  name: test
  version: 0.0.1

source:
  path: test.cpp

build:
  script:
    - g++ test.cpp -I ${CONDA_DEFAULT_ENV}/include/ -L ${CONDA_DEFAULT_ENV}/lib -lboost_filesystem -lboost_system
    - cp a.out ${PREFIX}/bin/

requirements:
  build:
    - python 2.7*
    - boost 1.61.0
    - gcc
  run:
    - python 2.7*
    - boost 1.61.0
    - libgcc

test:
  commands:
    - a.out

Isn't boost in the defaults channel compiled with the same image? Is this a boost bug or a gcc problem?

ping @msarahan @ccordoba12

mingwandroid commented 7 years ago

I compiled boost on defaults. I never use the docker image, I always use 'real' CentOS 5.11.

183amir commented 7 years ago

Are you suggesting that I try this on a real CentOS 5.11? I am following the instructions on https://github.com/ContinuumIO/anaconda-recipes to compile packages that are not available in the defaults channel. Since I want to build packages on the CI, I am stuck with docker images. The main question is why does this segfaults and how can I avoid it?

mingwandroid commented 7 years ago

I am confused as you answered the question already yourself.

You need to use the gcc andlibgcc packages as requirements/build and requirements/run respectively as the boost recipe does rather than linking both your system's (be that the Arch or the docker image one) libstdc++ and the one from libgcc into the same executable.

183amir commented 7 years ago

@mingwandroid if the boost package from defaults is supposed to work only with libgcc from defaults, isn't better to list it as a dependency?

mingwandroid commented 7 years ago

Ah no, you are right, seems I used CentOS 5.11's native GCC. The boost devs do a good job of supporting really old libstdc++ it seems!

You are probably running into a C++ ABI issue then. GCCs > 5.2 are usually built with with the new C++11 ABI (mainly to do with Small String Optimization). You can read more about it here: https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/

Can you try passing -D_GLIBCXX_USE_CXX11_ABI=0 on your g++ command line and see if that works? I'd be interested to know.

There was an attempt at maintaining support for 'dual ABI' support, but from what I've read from Clang developers, it was broken for a long time.

Sticking below GCC 5.2 avoids the C++11 ABI which is probably why using gcc and libgcc works.

183amir commented 7 years ago

Passing -D_GLIBCXX_USE_CXX11_ABI=0 makes it work. Thank you. I was exporting export CXXFLAGS="${CXXFLAGS} -Wabi=2" and export CXXFLAGS="${CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0" but I was not paying attention that this is not inherited in conda build.

mingwandroid commented 7 years ago

Great. FYI, I am working on updating all of our compilers and switching to C++11 ABI. At that point, we will be recommending everyone to use the compilers for all packages (on Linux initially, then macOS later in the year).

Once we adopt the C++11 ABI people will not be able to link to conda libraries when they use older compilers.