How to build both static and shared libs for libc++?

Since early today, I have been trying to pick up CMake/CPack as far as
I can so that I can build both static and shared libs for the libc++
3.3 from SVN.

The goal is to create a RPM for RHEL 6.4. The CPack part didn't take
me long to finish. But so far (as a CMake newbie), I am stumbled by
the CMakeLists.txt.

    40 option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
    41
    [...]
   232 if (NOT LIBCXX_ENABLE_SHARED)
   233 list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_BUILD_STATIC)
   234 endif()

Looking at the above, I tried two ways:

0. Changing the ON to OFF in line 40. Got static lib built.
1. Keeping line 40 as is, I got shared lib

In line 232, taking out NOT, I still got shared lib. Comment out 232
and 234, I got shared lib again.

Could anyone kindly tell me what I missed?

Regards,

-- Zack

Since early today, I have been trying to pick up CMake/CPack as far as
I can so that I can build both static and shared libs for the libc++
3.3 from SVN.

The goal is to create a RPM for RHEL 6.4. The CPack part didn't take
me long to finish. But so far (as a CMake newbie), I am stumbled by
the CMakeLists.txt.

   40 option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
   41
   [...]
  232 if (NOT LIBCXX_ENABLE_SHARED)
  233 list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_BUILD_STATIC)
  234 endif()

Looking at the above, I tried two ways:

0. Changing the ON to OFF in line 40. Got static lib built.
1. Keeping line 40 as is, I got shared lib

In line 232, taking out NOT, I still got shared lib. Comment out 232
and 234, I got shared lib again.

Could anyone kindly tell me what I missed?

I don't think the CMake files in libc++ are set up to build both shared and static at the same time. For now, you'll have to build twice: once shared, and once static. (Someone should really fix that. :slight_smile:

Chip

Hi Charlies,

I didn't wish to be defeated so easily, so this evening, I studied more CMake/CPack online resources, and enhanced the libc++ bundled CMakeLists.txt some more with an add_library, a set_target_properties, and an install commands, I got both static and shared libs built and packaged as a libcxx-3.3.svn-0.el6.x86_64.rpm

$ rpm -qlp libcxx-3.3.svn-0.el6.x86_64.rpm |grep libc++
/usr/lib/libc++.a
/usr/lib/libc++.so
/usr/lib/libc++.so.1
/usr/lib/libc++.so.1.0

Once and for all. Mission accomplished :sunglasses:

Regards,

Zack

[...]
>
>
I don't think the CMake files in libc++ are set up to build
both shared and static at the same time. For now, you'll
have to build twice: once shared, and once static. (Someone
should really fix that. :slight_smile:

Chip

[...]

Hi Zack,

Do you have any patches? I'd be happy to review your changes, test them here (on Ubuntu) and see if we can get them into the source tree.

Michael

Hi Michael,

At this stage, given the fact that I am a CMake newbie, I am sure what I have done is ugly even it works for what we need.

Please give me a couple more weeks. I will be much better with the CMake build system by then. Furthermore, I will update my desktop to Ubunu 13.04 (right now, it's still on 11.04 x86_64). I will give the deb generation a go too.

Will update the list.

Regards,

Zack

Hi Zack,

Do you have any patches? I'd be happy to review your
changes, test them here (on Ubuntu) and see if we can get
them into the source tree.

Michael

[...]

I am trying to build libc++abi (both shared and static) on SL 6.4 (a
RHEL 6.4 clone) so that we can use C++11 in our code on such OSes
without worrying about the oldish libstdc++ (4.4.x) bundled with
RHEL 6.x.

The bare http://libcxxabi.llvm.org/ doesn't tell you how to build it.

But a quick look around the source tree, in the lib subdir there is
buildit shell script. Following the comments in the script, I did:

[zackp@sl1 lib]$ export TRIPLE='x86_64-pc-linux'
[zackp@sl1 lib]$ ./buildit
+ for FILE in '../src/*.cpp'
+ clang++ -c -g -O3 -fPIC -std=c++0x -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 -Wsign-conversion -Wshadow -Wconversion -Wunused-variable -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter -Wnewline-eof -I../include ../src/abort_message.cpp
+ for FILE in '../src/*.cpp'
+ clang++ -c -g -O3 -fPIC -std=c++0x -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 -Wsign-conversion -Wshadow -Wconversion -Wunused-variable -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter -Wnewline-eof -I../include ../src/cxa_aux_runtime.cpp
+ for FILE in '../src/*.cpp'
+ clang++ -c -g -O3 -fPIC -std=c++0x -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 -Wsign-conversion -Wshadow -Wconversion -Wunused-variable -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter -Wnewline-eof -I../include ../src/cxa_default_handlers.cpp
In file included from ../src/cxa_default_handlers.cpp:18:
../src/cxa_exception.hpp:66:9: error: unknown type name '_Unwind_Exception'
        _Unwind_Exception unwindHeader;
        ^
../src/cxa_exception.hpp:100:9: error: unknown type name '_Unwind_Exception'
        _Unwind_Exception unwindHeader;
        ^
../src/cxa_default_handlers.cpp:35:13: error: unknown type name '_Unwind_Exception'
            _Unwind_Exception* unwind_exception =
            ^
../src/cxa_default_handlers.cpp:36:34: error: unknown type name '_Unwind_Exception'
                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
                                 ^
4 errors generated.

Anyone has a hint as to where I should be looking next?

Regards,

Zack

For an "unwind.h" header, other than the one included with Clang. :slight_smile:

There's a patch floating around for Clang--that I wrote ;)--that fleshes Clang's built-in header out, so that it actually includes such important declarations as "struct _Unwind_Exception". I've attached it here for your convenience. (I wanted to commit it, but nobody's given me the go-ahead yet.)

HTH.

Chip

0001-Headers-unwind.h-Flesh-out.patch (8.35 KB)

Hi Chip,

Thanks for sharing your patch. I will work on it more and will keep
the list posted.

[...]

For an "unwind.h" header, other than the one included with
Clang. :slight_smile:

There's a patch floating around for Clang--that I wrote
;)--that fleshes Clang's built-in header out, so that it
actually includes such important declarations as "struct
_Unwind_Exception". I've attached it here for your
convenience. (I wanted to commit it, but nobody's given me
the go-ahead yet.)

It's weird that even with Google's active support of the
LLVM project and it uses numerous servers running
RHEL 6.x based OSes, this aspect is so lacking! x-(

HTH.

Chip

Regards,

Zack

Hi Chip,

I decided to give your patch a quick try before I call it a day.

[zackp@sl1 lib]$ uname -a
Linux sl1 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 20:37:17 CST 2013 x86_64 x86_64 x86_64 GNU/Linux
[zackp@sl1 lib]$ ls
buildit libc++abi.so.1.0
[zackp@sl1 lib]$ date
Sun Apr 7 22:46:01 PDT 2013

Will do more tests in the coming week and keep the list posted.

Thanks! :sunglasses:

Zack

I followed the instructions given in http://libcxx.llvm.org/, section
"Build on Linux using CMake and libc++abi" to attempt to build libc++
with libc++abi, so that the lib is free from anything from libstdc++
(or libsupc++ for that matter). The build host runs Scientific Linux 6.4 x86_64. The llvm/clang is 3.3 from SVN.

With Chip Davis's patch, I was able to generate a libc++abi.so.1.0 and install it as shown below on this build host:

zackp@sl1 cd /usr/lib
zackp@sl1 ls -l libc++abi*
lrwxrwxrwx 1 root root 14 Apr 8 09:31 libc++abi.so -> libc++abi.so.1
lrwxrwxrwx 1 root root 16 Apr 8 09:30 libc++abi.so.1 -> libc++abi.so.1.0
-rwxr-xr-x 1 root root 1056217 Apr 8 09:30 libc++abi.so.1.0

The two associated headers are installed here:

zackp@sl1 cd /usr/include/c++abi/3.3
zackp@sl1 ls -l
total 16
-rw-r--r-- 1 root root 6869 Apr 8 09:48 cxa_demangle.h
-rw-r--r-- 1 root root 6005 Apr 8 09:48 cxxabi.h

ldd shows that the compiled libc++.so.1.0 got all the dependencies it
needs:

zackp@sl1 ldd libc++.so.1.0
  linux-vdso.so.1 => (0x00007fff261ff000)
  libc++abi.so.1 => /usr/lib/libc++abi.so.1 (0x00007f806f7af000)
  libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f806f592000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f806f1fe000)
  libm.so.6 => /lib64/libm.so.6 (0x00007f806ef7a000)
  librt.so.1 => /lib64/librt.so.1 (0x00007f806ed72000)
  libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f806eb5b000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f806fcb8000)

But when I tried to install the generated RPM with a few hacks of the
bundled CMakeLists.txt, I got the following:

zackp@sl1 sudo rpm -Uvh libcxx-3-3svn-0.el6.x86_64.rpm
[sudo] password for zackp:
error: Failed dependencies:
  libc++abi.so.1()(64bit) is needed by libcxx-3.3svn.1-0.el6.x86_64

BTW 0: I didn't have any issue when building the libc++ with the libsupc++. The package installed just fine.

BTW 1: I double-checked _CPack_Packages/0.el6.x86_64/RPM/SPECS/libcxx.spec
but couldn't figure out what I missed.

I would appreciate any hints.

Zack

[...]

But when I tried to install the generated RPM with a few
hacks of the
bundled CMakeLists.txt, I got the following:

zackp@sl1 sudo rpm -Uvh libcxx-3-3svn-0.el6.x86_64.rpm
[sudo] password for zackp:
error: Failed dependencies:
libc++abi.so.1()(64bit) is needed by
libcxx-3.3svn.1-0.el6.x86_64

It's bad form to follow-up one's own post. But in this case I feel I
must so as not to waste other's time. I "manually" install libc++abi.
I should generate a RPM for it and install that RPM first!

Time for more coffee :wink:

Zack

I have followed the instructions on http://libcxx.llvm.org/ and built
libc++ in two of the three approaches suggested:

0. Build on Linux using CMake and libsupc++
1. Build on Linux using CMake and libc++abi

The build host runs Scienetific Linux 6.4 (a RHEL 6.4 clone) x86_64.
The latest llvm/clang 3.3 from SVN is used.

As a test of what I built, I downloaded the latest boost_1_53_0 and
tried to build it with clang/libc++ and/or libc++abi. In both case,
the entire boost_1_53_0 got built successfully.

One of my goals is to ensure all the resulting boost libraries are
free from libstdc++. I know what libsupc++ is, so I expected that a
ldd *.so* in BOOST_ROOT/stage/lib would show dependencies of it.

In fact, the following three do:

libboost_graph
libboost_locale
libboost_regex

But once I switched to approach 1, a ldd *.so* in stage/lib still show
the three libs having dependencies on libstdc++ x-(

For example:

ldd libboost_regex.*so*
[...]
libboost_regex.so.1.53.0:
  linux-vdso.so.1 => (0x00007fffe9ae3000)
  libicuuc.so.42 => /usr/lib64/libicuuc.so.42 (0x00007f8fd7be5000)
  libicui18n.so.42 => /usr/lib64/libicui18n.so.42 (0x00007f8fd784f000)
  libicudata.so.42 => /usr/lib64/libicudata.so.42 (0x00007f8fd6709000)
  librt.so.1 => /lib64/librt.so.1 (0x00007f8fd6501000)
  libc++abi.so.1 => /usr/lib/libc++abi.so.1 (0x00007f8fd62b5000)
  libc++.so.1 => /usr/lib/libc++.so.1 (0x00007f8fd6000000)
  libm.so.6 => /lib64/libm.so.6 (0x00007f8fd5d7c000)
  libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f8fd5b66000)
  libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8fd5948000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f8fd55b5000)
  libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f8fd52af000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f8fd8247000)

This is what I used to build the full boost_1_53_0:

./b2 toolset=clang cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++ -lc++abi" -j4

How did the libstdc++.so.6 sneaked in? ./b2 --help didn't provide me
a clue ;-(

I would appreciate a hint!

Zack

I found the reason why. The solution? RTFM http://libcxx.llvm.org/
really carefully!

Zack

It might be useful to call out which part of the manual you didn't
read carefully enough previously. Perhaps we can improve the
documentation so that's harder to miss (Or at least anyone else who
has this problem & stumbles across this thread will find the answer)