Skip to content

Conversation

@certik
Copy link
Member

@certik certik commented May 14, 2015

See the commit messages for more information.

This is a change in an important package, so let's check that it (at the latest commit 9aed126):

  • compiles with gcc on OS X
  • compiles with the native clang on OS X
  • compiles on linux with gcc

Fixes #746.

This is ready for review.

@certik
Copy link
Member Author

certik commented May 14, 2015

So on my RHEL6 with gcc 4.9.2, this PR fails with:

[cmake] -- Looking for C++ include cxxabi.h - found
[cmake] -- Checking whether cxxabi works with this C++ compiler
[cmake] -- Checking whether cxxabi works with this C++ compiler - yes
[cmake] -- Using system-installed BZIP2
[cmake] -- Using system-installed CURL
[cmake] -- Using system-installed ZLIB
[cmake] -- Found ZLIB: /local/certik/bld/zlib/fz6rgowvxzv7/lib/libz.so (found version "1.2.3") 
[cmake] -- Could NOT find CURL (missing:  CURL_INCLUDE_DIR) 
[cmake] CMake Error at CMakeLists.txt:275 (message):
[cmake]   CMAKE_USE_SYSTEM_CURL is ON but a curl is not found!
[cmake] Call Stack (most recent call first):
[cmake]   CMakeLists.txt:525 (CMAKE_BUILD_UTILITIES)
[cmake] 
[cmake] 
[cmake] -- Configuring incomplete, errors occurred!
[cmake] See also "/local/certik/tmp/cmake-ojmg3evcf4gz/CMakeFiles/CMakeOutput.log".
[cmake] See also "/local/certik/tmp/cmake-ojmg3evcf4gz/CMakeFiles/CMakeError.log".
[cmake] ---------------------------------------------
[cmake] Error when bootstrapping CMake:
[cmake] Problem while running initial CMake
[cmake] ---------------------------------------------

It's weird it cannot find it, as the build script is as follows:

set -e
export HDIST_IN_BUILD=yes
export PATH="/local/certik/bld/profile/bto56eplrk4v/bin:$PATH"; export CC=gcc CXX=g++ FC=gfortran
(
export CPPFLAGS="-I${BZIP2_DIR}/include -I${CURL_DIR}/include -I${PATCHELF_DIR}/include -I${ZLIB_DIR}/include"
export LDFLAGS="-L${BZIP2_DIR}/lib -Wl,-rpath=${BZIP2_DIR}/lib -L${CURL_DIR}/lib -Wl,-rpath=${CURL_DIR}/lib -L${PATCHELF_DIR}/lib -Wl,-rpath=${PATCHELF_DIR}/lib -L${ZLIB_DIR}/lib -Wl,-rpath=${ZLIB_DIR}/lib"
./configure --prefix="${ARTIFACT}" \
  "--parallel=${HASHDIST_CPU_COUNT}" "--system-bzip2" "--system-curl" "--system-zlib" "--" "-DCMAKE_PREFIX_PATH=${CURL_DIR}/lib;${ZLIB_DIR}/lib;${BZIP2_DIR}/lib"
)
make -j ${HASHDIST_CPU_COUNT}
make install
rm -f ${ARTIFACT}/lib/*.la

I fixed that by:

diff --git a/pkgs/cmake.yaml b/pkgs/cmake.yaml
index 135252f..b3f32c1 100644
--- a/pkgs/cmake.yaml
+++ b/pkgs/cmake.yaml
@@ -26,6 +26,7 @@ build_stages:
           '--system-zlib',
           '--',
           '-DCMAKE_PREFIX_PATH=${CURL_DIR}/lib;${ZLIB_DIR}/lib;${BZIP2_DIR}/lib',
+          '-DCURL_INCLUDE_DIR=${CURL_DIR}/include',
           ]

 when_build_dependency:

Then it finds curl (but not bzip2):

[cmake] -- Using system-installed BZIP2
[cmake] -- Using system-installed CURL
[cmake] -- Using system-installed ZLIB
[cmake] -- Found ZLIB: /local/certik/bld/zlib/fz6rgowvxzv7/lib/libz.so (found version "1.2.3") 
[cmake] -- Found CURL: /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so (found version "7.37.0") 
[cmake] -- Could NOT find BZip2 (missing:  BZIP2_INCLUDE_DIR) 

But then it fails with:

[cmake] Linking CXX executable ../bin/cmake
[cmake] /usr/bin/ld: warning: libssl.so.1.0.0, needed by /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so, not found (try using -rpath or -rpath-link)
[cmake] /usr/bin/ld: warning: libcrypto.so.1.0.0, needed by /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so, not found (try using -rpath or -rpath-link)
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `ENGINE_set_default'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `UI_get_string_type'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `ERR_error_string_n'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `ASN1_STRING_length'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `SSLeay'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `ENGINE_cleanup'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `ENGINE_free'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `SSL_get_peer_cert_chain'
[cmake] /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `X509_get_issuer_name'
...

But the ssl library seems to have a proper rpath:

certik@redhawk:~$ ldd /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so
    linux-vdso.so.1 =>  (0x00007fffb4de0000)
    libidn.so.11 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../libidn/gbirz5f27ley/lib/libidn.so.11 (0x00007ff55b6b9000)
    libssl.so.1.0.0 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib/libssl.so.1.0.0 (0x00007ff55b44c000)
    libcrypto.so.1.0.0 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib/libcrypto.so.1.0.0 (0x00007ff55b05d000)
    libz.so.1 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../zlib/fz6rgowvxzv7/lib/libz.so.1 (0x00007ff55ae43000)
    librt.so.1 => /lib64/librt.so.1 (0x00007ff55ac1f000)
    libc.so.6 => /lib64/libc.so.6 (0x00007ff55a88b000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007ff55a687000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ff55a469000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff55bb4f000)

So I don't know why the linker can't find it. I wonder if this is related: http://stackoverflow.com/questions/24598047/why-does-ld-need-rpath-link-when-linking-an-executable-against-a-so-that-needs

@certik
Copy link
Member Author

certik commented May 14, 2015

I see what the problem is, here is how to reproduce it. Create a program a.c:

#include <curl/curl.h>

int main(void)
{
    return 0;
}

and compile using (adjust: the paths to your curl):

gcc -I/local/certik/bld/curl/nlll4tgxnhux/include a.c -L/local/certik/bld/curl/nlll4tgxnhux/lib -Wl,-rpath=/local/certik/bld/curl/nlll4tgxnhux/lib -lcurl

it gives:

$ gcc -I/local/certik/bld/curl/nlll4tgxnhux/include a.c -L/local/certik/bld/curl/nlll4tgxnhux/lib -Wl,-rpath=/local/certik/bld/curl/nlll4tgxnhux/lib -lcurl
/usr/bin/ld: warning: libssl.so.1.0.0, needed by /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libcrypto.so.1.0.0, needed by /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so, not found (try using -rpath or -rpath-link)
/local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `SSL_connect'
/local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `X509_check_issued'
/local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so: undefined reference to `SSL_CTX_set_srp_password'
...

Since the curl itself seems to have the rpath set correctly:

$ ldd /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so
    linux-vdso.so.1 =>  (0x00007fff347ff000)
    libidn.so.11 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../libidn/gbirz5f27ley/lib/libidn.so.11 (0x00007f4dbc0d9000)
    libssl.so.1.0.0 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib/libssl.so.1.0.0 (0x00007f4dbbe6c000)
    libcrypto.so.1.0.0 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib/libcrypto.so.1.0.0 (0x00007f4dbba7d000)
    libz.so.1 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../zlib/fz6rgowvxzv7/lib/libz.so.1 (0x00007f4dbb863000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f4dbb63f000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f4dbb2ab000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f4dbb0a7000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4dbae89000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f4dbc56f000)
$ patchelf --print-rpath /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so
${ORIGIN}/../../../libidn/gbirz5f27ley/lib:${ORIGIN}/../../../openssl/x52ytirwj5lx/lib:${ORIGIN}/../../../zlib/fz6rgowvxzv7/lib

The linker is then not following the rpath from libcurl.so to find the dependent libraries --- or it is confused by the ${ORIGIN}. Let's test it --- change ${ORIGIN} to the full paths:

$ chmod +w -R /local/certik/bld/curl/nlll4tgxnhux/
$ patchelf --set-rpath /local/certik/bld/curl/nlll4tgxnhux/lib/../../../zlib/fz6rgowvxzv7/lib:/local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib:/local/certik/bld/curl/nlll4tgxnhux/lib/../../../libidn/gbirz5f27ley/lib /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so
$ patchelf --print-rpath /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so
/local/certik/bld/curl/nlll4tgxnhux/lib/../../../zlib/fz6rgowvxzv7/lib:/local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib:/local/certik/bld/curl/nlll4tgxnhux/lib/../../../libidn/gbirz5f27ley/lib

and recompile:

$ gcc -I/local/certik/bld/curl/nlll4tgxnhux/include a.c -L/local/certik/bld/curl/nlll4tgxnhux/lib -Wl,-rpath=/local/certik/bld/curl/nlll4tgxnhux/lib -lcurl
$ ldd ./a.out 
    linux-vdso.so.1 =>  (0x00007fff6efff000)
    libcurl.so.4 => /local/certik/bld/curl/nlll4tgxnhux/lib/libcurl.so.4 (0x00007f71414bb000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f714110b000)
    libidn.so.11 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../libidn/gbirz5f27ley/lib/libidn.so.11 (0x00007f7140ed8000)
    libssl.so.1.0.0 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib/libssl.so.1.0.0 (0x00007f7140c6b000)
    libcrypto.so.1.0.0 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../openssl/x52ytirwj5lx/lib/libcrypto.so.1.0.0 (0x00007f714087c000)
    libz.so.1 => /local/certik/bld/curl/nlll4tgxnhux/lib/../../../zlib/fz6rgowvxzv7/lib/libz.so.1 (0x00007f7140662000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f7140459000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f714171e000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f7140255000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7140038000)
$ patchelf --print-rpath a.out 
/local/certik/bld/gcc/vfnflgljyg4l/lib:/local/certik/bld/curl/nlll4tgxnhux/lib

It works! The rpaths are followed and it can find all the libraries, but it doesn't work with ${ORIGIN} in the shared library. This has been reported here as well: http://stackoverflow.com/questions/6323603/ld-using-rpath-origin-inside-a-shared-library-recursive

The solution seems to be to either remove $ORIGIN from curl, or specify the full recursive dependencies to cmake and anything else that uses curl. The patch to cmake that fixes this problem is:

--- a/pkgs/cmake.yaml
+++ b/pkgs/cmake.yaml
@@ -1,7 +1,7 @@
 extends: [autotools_package]

 dependencies:
-  build: [zlib, bzip2, curl]
+  build: [zlib, bzip2, curl, openssl, libidn]

 sources:
 - key: tar.gz:vxuu43rwaodxivs7flwyqzsbkrbuit5x

@dagss, @ahmadia, @cekees this is a problem for our plan to use ${ORIGIN}.

certik added 4 commits May 14, 2015 17:09
This way CMake does not build its own versions, but rather uses Hashstack
versions. We also made sure the proper RPATH will be used in the `cmake`
executable via the CMAKE_PREFIX_PATH option.

Only three other libraries are still build as part of CMake: expat, jsoncpp,
libarchive, so we commented out options that disable them for now.

As a bonus, this patch also fixes a problem on OSX 10.10 where the curl
component of CMake fails to build with gcc (we now use Hashstack's version that
builds).
On OSX 10.10, one gets errors of the type:

[cmake] CMake Error at Modules/Platform/Darwin.cmake:76 (message):
[cmake]   CMAKE_OSX_DEPLOYMENT_TARGET is '10.10' but CMAKE_OSX_SYSROOT:
[cmake]
[cmake]    ""
[cmake]
[cmake]   is not set to a MacOSX SDK with a recognized version.  Either set
[cmake]   CMAKE_OSX_SYSROOT to a valid SDK or set CMAKE_OSX_DEPLOYMENT_TARGET to
[cmake]   empty.
[cmake] Call Stack (most recent call first):
[cmake]   Modules/CMakeSystemSpecificInformation.cmake:36 (include)
[cmake]   CMakeLists.txt:16 (project)

Unless the CMAKE_OSX_DEPLOYMENT_TARGET is set to empty. We set it to empty by
unsetting the MACOSX_DEPLOYMENT_TARGET environment variable.

Similar problem happens when cmake is used to build other packages. There the
fix is to unset the CMAKE_OSX_DEPLOYMENT_TARGET variable on the command line.
ld does not seem to follow the $ORIGIN in recursive dependencies properly. The
workaround is to specify the recursive dependencies (in this case openssl,
libidn) explicitly, then the rpath is properly constructed and things work at
link time.

Also add full include paths to the dependencies.
@certik
Copy link
Member Author

certik commented May 14, 2015

As of 9aed126, this is ready for review.

@cekees
Copy link
Contributor

cekees commented May 15, 2015

Thanks for pointing out the $ORIGIN issue.

@cekees
Copy link
Contributor

cekees commented May 15, 2015

I don't have a mac, but I confirmed that your cmake package works with my stack on ubuntu as a replacement for host-cmake. +1 to merge.

@certik
Copy link
Member Author

certik commented May 15, 2015

Thanks. Since it wasn't working on a Mac before, and now it is for me, I think it's good to merge. We can improve upon it later if needed.

certik added a commit that referenced this pull request May 15, 2015
@certik certik merged commit 6a0c174 into master May 15, 2015
@certik certik deleted the cmake_osx branch May 15, 2015 18:55
@certik certik mentioned this pull request May 15, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cmake fails on OS X

3 participants