zaphoyd / websocketpp

C++ websocket client/server library
http://www.zaphoyd.com/websocketpp
Other
7.05k stars 1.98k forks source link

Allow linking examples to shared (rather than static) boost libraries with scons #429

Open unphased opened 9 years ago

unphased commented 9 years ago

I will try to debug the scons run soon, but here is where I'm at so far.

$ BOOST_INCLUDES=/usr/include  BOOST_LIBS=/usr/lib64 scons
scons: Reading SConscript files ...
C++11 build environment partially enabled
scons: done reading SConscript files.
scons: Building targets ...
g++ -o build/release/broadcast_server/broadcast_server.o -c -std=c++0x -O1 -fomit-frame-pointer -Wall -Wcast-align -Wshadow -Wunused-parameter -isystem /usr/include -DNDEBUG -D_WEBSOCKETPP_CPP11_STL_ -I. examples/broadcast_server/broadcast_
server.cpp
scons: *** [build/release/broadcast_server/broadcast_server] Implicit dependency `/usr/lib64/libboost_system.a' not found, needed by target `build/release/broadcast_server/broadcast_server'.
scons: building terminated because of errors.

$ sudo find / -name '*libboost_system*'
/usr/lib64/libboost_system-mt.so.1.53.0
/usr/lib64/libboost_system.so.1.53.0
/usr/lib64/libboost_system-mt.so
/usr/lib64/libboost_system.so

Environment is a Centos 7 with boost 1.53 (ugh, so old) and scons from packages.

I have zero experience with Scons. More than I have cmake. But since I hate cmake so much, it would be neat if we could get the scons build working.

zaphoyd commented 9 years ago

Specifically.. The scons build doesn't work when only shared (i.e. no static) boost libraries are present? A quick poke through the scons documentation indicates that it should work with shared libraries. Strange.

unphased commented 9 years ago

No idea. The thing I'm scratching my head about the most now is actually that if you open the massive manpage for scons, and search for the string "verbose", it is not found.

Anyway... seems like scons has its own ideas about fetching libraries (which I really question because isn't the gcc driver usually what we delegate that job to?)

$ BOOST_INCLUDES=/usr/include  BOOST_LIBS=/usr/lib64 scons --debug=findlibs                                                                                                                    
scons: Reading SConscript files ...
C++11 build environment partially enabled
scons: done reading SConscript files.
scons: Building targets ...
  findlibs: looking for 'libpthread.a' in '/usr/lib' ...
  findlibs: looking for 'libpthread.a' in '/usr/local/lib' ...
  findlibs: looking for 'libpthread.a' in '/usr/lib64' ...
  findlibs: looking for 'libpthread.so' in '/usr/lib' ...
  findlibs: looking for 'libpthread.so' in '/usr/local/lib' ...
  findlibs: looking for 'libpthread.so' in '/usr/lib64' ...
  findlibs: ... FOUND 'libpthread.so' in '/usr/lib64'
  findlibs: looking for 'librt.a' in '/usr/lib' ...
  findlibs: looking for 'librt.a' in '/usr/local/lib' ...
  findlibs: looking for 'librt.a' in '/usr/lib64' ...
  findlibs: looking for 'librt.so' in '/usr/lib' ...
  findlibs: looking for 'librt.so' in '/usr/local/lib' ...
  findlibs: looking for 'librt.so' in '/usr/lib64' ...
  findlibs: ... FOUND 'librt.so' in '/usr/lib64'
scons: *** [build/release/broadcast_server/broadcast_server] Implicit dependency `/usr/lib64/libboost_system.a' not found, needed by target `build/release/broadcast_server/broadcast_server'.
scons: building terminated because of errors.
unphased commented 9 years ago

I did an ill-advised sudo ln -s /usr/lib64/libboost_system.so /usr/lib64/libboost_system.a and the scons build is proceeding now.

Maybe the scons config scripts are funky?

zaphoyd commented 9 years ago

Ah. Line 42 of the SConstruct file says

boost_linkshared = False

Which indicates whether or not to link the boost libraries as static or shared. The default appears to be static. Changing this to true in your case should fix.

There should be a better way to specify this via the env rather than editing the SConstruct file though.

unphased commented 9 years ago

Well... I didnt really do anything out of the ordinary in setting up my environment, i strive for pristine VM installs... is boost ordinarily supposed to provide static libraries?

zaphoyd commented 9 years ago

A manual compile and the default package installs for every OS i've worked with includes both static and shared libraries.

unphased commented 9 years ago

Hmm, I see... well. Can we just allow it to use the shared libs? It should work, right?

unphased commented 9 years ago

changing line 42 to set to True results in

scons: *** [build/release/broadcast_server/broadcast_server] Implicit dependency `/usr/lib64/$LIBPREFIXboost_system.so' not found, needed by target `build/release/broadcast_server/broadcast_server'.
scons: building terminated because of errors.
unphased commented 9 years ago

Maybe I will just do a boost install from source and be rid of this headache. Besides, 1.53 is like ancient.

zaphoyd commented 9 years ago

WebSocket++ examples absolutely work fine with the boost libraries linked shared, assuming we can get the build script to name things correctly =)

It looks like setting it to true picks up the right extension/suffix, but not the right library prefix. hmm

zaphoyd commented 9 years ago

can you try defining SHLIBPREFIX to lib?

zaphoyd commented 9 years ago

If you are willing to compile your own copy of Boost (not particularly hard) the newer versions have many bug fixes, features, & performance improvements as well.

unphased commented 9 years ago

Hmmm, seems like something happening in the Python is causing this not to work like we want

$ BOOST_INCLUDES=/usr/include BOOST_LIBS=/usr/lib64 SHLIBPREFIX=lib scons                                                                                                                              
scons: Reading SConscript files ...
C++11 build environment partially enabled
scons: done reading SConscript files.
scons: Building targets ...
scons: *** [build/release/broadcast_server/broadcast_server] Implicit dependency `/usr/lib64/$LIBPREFIXboost_system.so' not found, needed by target `build/release/broadcast_server/broadcast_server'.
scons: building terminated because of errors.

$ BOOST_INCLUDES=/usr/include BOOST_LIBS=/usr/lib64 LIBPREFIX=lib scons                                                                                                                                
scons: Reading SConscript files ...
C++11 build environment partially enabled
scons: done reading SConscript files.
scons: Building targets ...
scons: *** [build/release/broadcast_server/broadcast_server] Implicit dependency `/usr/lib64/$LIBPREFIXboost_system.so' not found, needed by target `build/release/broadcast_server/broadcast_server'.
scons: building terminated because of errors.

Also, soon™ we will eliminate boost dependency from websocketpp? Yes? :yum:

And which parts of the library-bits of boost are really necessary anyway?

zaphoyd commented 9 years ago

You can actually use the library core and the iostream transport without Boost now, provided you have a C++11 compiler. If you want to use the asio transport without Boost you will need the latest version of WebSocket++ on the develop branch and a copy of standalone Asio from think-async.com. Standalone Asio is header only. Combined, standalone Asio + WebSocket++ does not require Boost with a C++11 compiler.

unphased commented 9 years ago

Thats great to hear (I saw you made a comment to that effect on the other issue i made about that too), thanks.

But I take it that the tests do require a boost?

I must be going about this the wrong way. Cloning a boost tag and then doing git submodule init in there (otherwise the quick install script fails trivially finding a script) ends up with me downloading upward of 1.2GB of git submodules for boost. What is this madness... I guess I will just go for the 1.58 source tarball...

edit Well, the source tarball extracts to 520MB, so it ain't that much better, presumably if the git submodule clones could be done with --depth 1 as well it wouldnt be 1.2GB... boost is a dog.

zaphoyd commented 9 years ago

I typically download the tarball from boost.org, run its built in build system, and then set BOOST_ROOT to that folder. I typically have a dozen different boost installs on my machine for quickly testing with different versions so it makes swapping between them quick.

Yes. The tests (and possibly some examples) may require Boost, as the tests use the boost unit test framework and every test is run both in C++11 and C++03/Boost mode). If you want to just use the library in a program you can fairly easily do this without Boost. If your goal is to run the tests that is not possible without Boost (and probably won't be for some time).

unphased commented 9 years ago

Excellent. Thanks for the clear explanations and being the most responsive open source library maintainer I have ever seen.

zaphoyd commented 9 years ago

Going to re-open this issue, as the scons build system still doesn't behave correctly with shared boost libraries.

unphased commented 9 years ago

Haha works for me!

zaphoyd commented 9 years ago

If anyone ends up at this issue in the meantime.. some workarounds (discussed in more detail above):

unphased commented 9 years ago

Quick question -- For your standalone boost installs does it work something like this?

Extract boost version into its $SOMEPATH/boost_1_xx_x dir cd into it ./bootstrap ./b2

No installing. And afterwards BOOST_ROOT for the purposes of websocketpp can be made to be $SOMEPATH/boost_1_xx_x.

Well now that I did run bootstrap, I think I answered the question myself. The process makes it very clear that this is how it will work. very clean.

zaphoyd commented 9 years ago

That is correct. Sometimes I will add flags to the b2 install command.. Some reasons would be to switch it to using clang/libc++ when building on OS X, and to switch it to using multiple cores to build if I am building all of Boost. For example: -j8 for an 8 core build. It builds in ~1-2 minutes on an 8 core machine vs 20 or so in the default one at a time mode.

I do not install the standalone boosts as I typically switch between multiple copies and always build programs with the libraries statically linked. Not installing keeps everything a lot cleaner.

unphased commented 8 years ago

I'm really wanting to avoid having to check out boost and build boost when I can obtain (an old crufty but surely functional) boost 1.53 from yum.

I don't know why I was so eager to close this issue on May 17 2015 because it's still an issue today on March 31 2016.

Yes I'm still just trying to verify that the example code compiles but I need the Scons to start working properly. It's looking for the boost static libs and not finding them because yum only installs shared libs.

unphased commented 8 years ago

Here's my diff on the repo that makes test build with clean boost-dev package (and specifying BOOST_LIBS and BOOST_INCLUDES)

image

I tried in vain to make setting the shell variable SHLIBPREFIX=lib work properly for Scons to take it.

Now I have an undefined reference to main at the end of the Scons run but I'm further along than before.

$ BOOST_INCLUDES=/usr/include/boost BOOST_LIBS=/usr/lib64 scons  
scons: Reading SConscript files ...                                                                                                                                                                         
C++11 build environment partially enabled                                                                                                                                                                   
scons: done reading SConscript files.                                                                                                                                                                       
scons: Building targets ...                                                                                                                                                                                 
g++ -o build/test/connection/test_connection_boost build/test/connection/connection_boost.o build/test/connection/connection_tu2_boost.o -L/usr/lib -L/usr/local/lib -L/usr/lib64 /usr/lib64/libboost_unit_t
est_framework.so /usr/lib64/libboost_system.so -lpthread -lrt                                                                                                                                               
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o: In function `_start':                                                                                                                      
(.text+0x20): undefined reference to `main'                                                                                                                                                                 
collect2: error: ld returned 1 exit status                                                                                                                                                                  
scons: *** [build/test/connection/test_connection_boost] Error 1                                                                                                                                            
scons: building terminated because of errors.                                                                                                                                                               
roastercode commented 6 years ago

maybe that is more RedHat relative that anything .. I got that trouble with la little C code :-/


#include <string.h>

// String function -strrev
char *strrev(char *str) {
    char *p1, *p2;
    if (! str || ! *str)
        return str;
    for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
        {
            *p1 ^= *p2;
            *p2 ^= *p1;
            *p1 ^= *p2;
        }
    return str;
}