1

I will try to be very specific and informative. I want to create a Dockerfile with all the packages that are used in geosciences for the good of the geospatial/geoscientific community. The Dockerfile is built on top of the scipy-notebook docker-stack.

The problem:

I am trying to build HPGL (a Python package for Geostatistics).

For the dependencies: I build some packages using apt-get and for those packages that I couldn't install via apt I downloaded the .deb packages. The Dockerfile below shows the steps for building all the HPGL dependencies:

FROM jupyter/scipy-notebook

###
### HPGL - High Performance Geostatistics Library
###

USER root

RUN apt-get update && \
    apt-get install -y \ 
        gcc \
        g++ \
        libboost-all-dev

RUN apt-get update && \
    apt-get install -y \ 
        liblapack-dev \
        libblas-dev \
        liblapacke-dev

RUN apt-get update && \
    apt-get install -y \ 
        scons

RUN wget http://ftp.us.debian.org/debian/pool/main/libf/libf2c2/libf2c2_20090411-2_amd64.deb && \
    dpkg -i libf2c2_20090411-2_amd64.deb

RUN wget http://ftp.us.debian.org/debian/pool/main/libf/libf2c2/libf2c2-dev_20090411-2_amd64.deb && \
    dpkg -i libf2c2-dev_20090411-2_amd64.deb

RUN wget http://mirrors.kernel.org/ubuntu/pool/universe/c/clapack/libcblas3_3.2.1+dfsg-1_amd64.deb  && \
    dpkg -i libcblas3_3.2.1+dfsg-1_amd64.deb

RUN wget http://mirrors.kernel.org/ubuntu/pool/universe/c/clapack/libcblas-dev_3.2.1+dfsg-1_amd64.deb && \
    dpkg -i libcblas-dev_3.2.1+dfsg-1_amd64.deb

RUN wget http://ftp.us.debian.org/debian/pool/main/c/clapack/libclapack3_3.2.1+dfsg-1_amd64.deb  && \
    dpkg -i libclapack3_3.2.1+dfsg-1_amd64.deb

RUN wget http://ftp.us.debian.org/debian/pool/main/c/clapack/libclapack-dev_3.2.1+dfsg-1_amd64.deb && \
    dpkg -i libclapack-dev_3.2.1+dfsg-1_amd64.deb

RUN wget https://mirror.kku.ac.th/ubuntu/ubuntu/pool/main/l/lapack/libtmglib3_3.7.1-1_amd64.deb && \
    dpkg -i libtmglib3_3.7.1-1_amd64.deb

RUN wget http://ftp.us.debian.org/debian/pool/main/l/lapack/libtmglib-dev_3.7.1-1_amd64.deb && \
    dpkg -i libtmglib-dev_3.7.1-1_amd64.deb

RUN git clone https://github.com/hpgl/hpgl.git

RUN cd hpgl/src/ && \
    bash -c "source activate python2 && scons -j 2"

RUN cd hpgl/src/ && \
    bash -c "source activate python2 && python2 setup.py install"

RUN rm -rf hpgl \
    scons-2.5.0* \
    libf2c2_20090411-2_amd64.deb \
    libf2c2-dev_20090411-2_amd64.deb \
    libtmglib3_3.7.1-1_amd64.deb \
    libtmglib-dev_3.7.1-1_amd64.deb \
    libcblas3_3.2.1+dfsg-1_amd64.deb \
    libcblas-dev_3.2.1+dfsg-1_amd64.deb \
    libclapack3_3.2.1+dfsg-1_amd64.deb \
    libclapack-dev_3.2.1+dfsg-1_amd64.deb

USER $NB_USER

This runs smooth and I can run the Docker container and start notebooks, but when I import HPGL in Python I get this error that I have no idea what is happening or how to solve this:

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-1-604a7d0744ab> in <module>()
----> 1 import geo_bsd

/opt/conda/envs/python2/lib/python2.7/site-packages/HPGL_BSD-0.9.9-py2.7.egg/geo_bsd/__init__.py in <module>()
      2 
      3 
----> 4 from geo import *
      5 from sgs import sgs_simulation
      6 from sis import sis_simulation

/opt/conda/envs/python2/lib/python2.7/site-packages/HPGL_BSD-0.9.9-py2.7.egg/geo_bsd/geo.py in <module>()
      3 import ctypes as C
      4 
----> 5 from hpgl_wrap import _HPGL_SHAPE, _HPGL_CONT_MASKED_ARRAY, _HPGL_IND_MASKED_ARRAY, _HPGL_UBYTE_ARRAY, _HPGL_FLOAT_ARRAY, _HPGL_OK_PARAMS, _HPGL_SK_PARAMS, _HPGL_IK_PARAMS, _HPGL_MEDIAN_IK_PARAMS, __hpgl_cov_params_t, __hpgl_cockriging_m1_params_t, __hpgl_cockriging_m2_params_t, _hpgl_so
      6 from hpgl_wrap import hpgl_output_handler, hpgl_progress_handler
      7 

/opt/conda/envs/python2/lib/python2.7/site-packages/HPGL_BSD-0.9.9-py2.7.egg/geo_bsd/hpgl_wrap.py in <module>()
    144         _hpgl_so = NC.load_library('hpgl_d', __file__)
    145 else:
--> 146         _hpgl_so = NC.load_library('hpgl', __file__)
    147 
    148 _hpgl_so.hpgl_set_output_handler.restype = None

/opt/conda/envs/python2/lib/python2.7/site-packages/numpy/ctypeslib.pyc in load_library(libname, loader_path)
    148             if os.path.exists(libpath):
    149                 try:
--> 150                     return ctypes.cdll[libpath]
    151                 except OSError:
    152                     ## defective lib file

/opt/conda/envs/python2/lib/python2.7/ctypes/__init__.pyc in __getitem__(self, name)
    435 
    436     def __getitem__(self, name):
--> 437         return getattr(self, name)
    438 
    439     def LoadLibrary(self, name):

/opt/conda/envs/python2/lib/python2.7/ctypes/__init__.pyc in __getattr__(self, name)
    430         if name[0] == '_':
    431             raise AttributeError(name)
--> 432         dll = self._dlltype(name)
    433         setattr(self, name, dll)
    434         return dll

/opt/conda/envs/python2/lib/python2.7/ctypes/__init__.pyc in __init__(self, name, mode, handle, use_errno, use_last_error)
    360 
    361         if handle is None:
--> 362             self._handle = _dlopen(self._name, mode)
    363         else:
    364             self._handle = handle

OSError: /usr/lib/libf2c.so.2: undefined symbol: MAIN__

EDIT1:

So apparently there is this very similar problem pointed by @Jean-François Fabre Here!. There, the problem was related to the file libf2c.so and was solved like this:

rm /usr/lib/libf2c.so && ln -s /usr/lib/libf2c.a /usr/lib/libf2c.so

This solution was explained by @p929 in the same thread:

What it does is in fact is to delete the dynamic library and create an alias to the static library.

Now, I understand that I have the same problem, but with a different file (/usr/lib/libf2c.so.2). The solution would be to "delete the dynamic library and create an alias to the static library". I tried that with the same static library /usr/lib/libf2c.a and had no success.

  • Tagged with 4 languages! Maybe focus on Python and one other language at a time. – chux - Reinstate Monica Jul 28 '17 at 21:04
  • 1
    sounds like a duplicate of https://stackoverflow.com/questions/8345725/linker-errors-with-fortran-to-c-library-usr-lib-libf2c-so-undefined-referenc but I'm too tired to check :) – Jean-François Fabre Jul 28 '17 at 21:10
  • Hello @Jean-FrançoisFabre, I looked into that. Their problem was with the _MAIN variable too, but in the file /usr/lib/libf2c.so. My problem is in the file /usr/lib/libf2c.so.2. – Bruno Ruas De Pinho Jul 28 '17 at 21:39
  • I can't link /usr/lib/libf2c.so.2 with /usr/lib/libf2c.a because, instead, I get this error: OSError: /usr/lib/libf2c.so.2: invalid ELF header – Bruno Ruas De Pinho Jul 28 '17 at 21:40
  • @chux I am sorry. However, the problem doesn't look to be in Python. – Bruno Ruas De Pinho Jul 28 '17 at 21:56
  • Any ideas why my thread is being downvoted and there is no willing for help at all? – Bruno Ruas De Pinho Jul 28 '17 at 22:36
  • NMDV, yet some possibilties: Perhaps with the 4 initial language post, the post looked overly board and unclear. "Any help or thoughts is really appreciated." is broad. Focus on a particular issue and ask a clear quesiton. "knows nothing about c, c++ and fortran" does not engender help as says if one came to you and said "I don't understand science - how does photosynthesis work?" This post has 1 DV, not that much of a tread yet. – chux - Reinstate Monica Jul 28 '17 at 22:42
  • 1
    Thanks @chux, I will add a little more background information at the end. – Bruno Ruas De Pinho Jul 28 '17 at 22:44

2 Answers2

0

The solution:

I finally solved the problem by changing the dynamic library to the static library during the installation. HPGL is built using scons. From scons website:

SCons is an Open Source software construction tool (...) Configuration files are Python scripts

So I edited the SConstruct file in hpgl/src before calling scons to build HPGL.

Original SConstruct file from hpgl/src:

env = Environment(
    CPPDEFINES = cl_defines,
    CPPPATH = [ 
#       '/opt/boost_1_38_src/',
        'tnt_126',
        'geo_bsd/hpgl',
        'CLAPACK-3.1.1.1/INCLUDE' ],
    LIBS = ['stdc++', 'libgomp', 'pthread', 'lapack', 'f2c', 'tmglib', 'blas'],
    LIBPATH =  ['CLAPACK-3.1.1.1'], 
    )

I changed the list LIBS to:

LIBS = ['stdc++', 'libgomp', 'pthread', 'lapack', File('/usr/lib/libf2c.a'), 'tmglib', 'blas'],

This solution was proposed by @BenG in this thread.

This way scons pass to the g++ that we want the static library of libf2c. Part of the build:

g++ -o geo_bsd/_cvariogram.so -shared temp/release/geo_bsd/_cvariogram/ellipsoid.os temp/release/geo_bsd/_cvariogram/stack_layers.os temp/release/geo_bsd/_cvariogram/variograms.os -LCLAPACK-3.1.1.1 -lstdc++ -lgomp -lpthread -llapack /usr/lib/libf2c.a -ltmglib -lblas  
0

Did you try just changing the name in LIBS from 'libf2c' to 'f2c' ?

bdbaddog
  • 3,357
  • 2
  • 22
  • 33