How do you statically link Boost libraries only?
Use the boost archive files (.a files) instead of the shared lib files (.so aka. linking with -l). You are linking those boost libraries dynamically right now. Writing it out might help to ensure what is being linked statically and what dynamically.
This will look something like:
g++ -o"acmserver" ./src/acmserver.o ... ./src/server.o \
/usr/local/lib/libboost_system.a /usr/local/lib/boost_filesystem \
... -lGL ...
Depending on the gcc version or platform type you might also have to add the -static` flag.
Linking Boost static libraries
Does this mean I have to recompile Boost using -fPIC command?
Yes. All code that is linked into a shared library must be Position Independent Code. Object
files within static libraries normally are not, as shared libraries normally
link other shared libraries.
But there is nothing in principle to stop you from building boost static libraries
from -fPIC
-compiled object files.
It would be simpler, of course, to link the shared versions of the boost libraries.
Link the static versions of the Boost libraries using CMake
In your CMakeLists.txt
file:
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED ...)
Where I have ...
, you optionally put the names of the libraries you want to use, and then target_link_libraries(targetname ${Boost_LIBRARIES})
later below. If you have a fairly recent distribution of CMake, it should work exactly as advertised. I do it exactly this way in my own projects.
Trying to statically link Boost
For pthread_mutex_init, you want to compile/link with -pthread option:
g++ -static -pthread -o"MyProgram" ./main.o -lboost_thread
The problem is that functions like pthread_mutex_init are in a separate library. Dynamic libraries can include the metadata for the fact that it needs the separate library (so libboost_thread.so includes the fact that it needs libpthread).
But static libraries don't have that information. So you need to provide the reference to any necessary libraries when you link statically.
As for using -pthread
instead of -lpthread
, it's slightly preferable because it not only links the necessary library, but provides any other options that should be used (such a -D_REENTRANT
to the compiler).
Boost Logger Static Linking: Not Working
By default on modern UNIX-like systems gcc links with shared libraries by default. In order to force static linking you can either add -static
to your linking command line (see the docs) or make sure gcc doesn't find the shared libraries but only finds the static libraries (e.g. move the shared libraries to a separate directory while you're linking your project). Note that -static
will make all libraries linked statically, including libstdc++.
Alternatively, you can specify the static libraries directly, without the -l
switch. You will have to use the full path to the libraries though, so instead of
gcc ... -lboost_log ...
you would write
gcc ... ..../boost_1_61_0_b1/stage/lib/libboost_log.a ...
In any case, you should not define BOOST_ALL_DYN_LINK
because this macro means exactly the opposite - that you intend to link with Boost shared libraries.
Linking statically only boost library G++
Replace -lboost_system
with -Wl,-Bstatic -lboost_system -Wl,-Bdynamic
. The -Wl
option sends the thing after it to the linker, in the order it appears on the command-line.
Static linking with Boost Filesystem not working
You seem to be using the old CMake variables for Boost. As of Boost 1.70, Boost now provides CMake support to make it easier for CMake to find and use Boost for your project (see documentation on this page).
When you build Boost, you will see CMake package configuration files for each Boost library (typically placed along with the built libraries in a cmake
folder). You can use find_package()
in CONFIG
mode to find these package configuration files. These provide imported targets such as Boost::filesystem
that you can link to directly. This way, if the filesystem
library is missing, you don't have to sift through the list of libraries in the BOOST_LIBRARIES
variable when compilation/linking fails. Instead, CMake will tell you the library is missing at the CMake configure-time.
Also, the Boost library dependencies should now be resolved automatically. So, if you're using filesystem
, you should no longer have to explicitly call out the system
library also. Boost should resolve this dependency for you. With these changes, your find_package()
command usage could look like this:
find_package(Boost CONFIG REQUIRED filesystem)
if(Boost_FOUND)
add_executable(${PROJECT_NAME} "execute_code.cpp")
target_link_libraries(executable PRIVATE Boost::filesystem)
endif()
For what it's worth, you can run make VERBOSE=1
to see the verbose output at the link stage to verify that all the correct libraries are being linked. You should be able to see that Boost's filesystem
and system
libraries are linked, and you can verify they are the desired static (.a
) libraries.
Boost static linking
Just add -static
to your build invocation. Here is a quick example session:
$ cat boost_formatted_time.cpp
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
using namespace boost::posix_time;
using namespace std;
int main(int argc, char **argv) {
time_facet *facet = new time_facet("%d-%b-%Y %H:%M:%S");
cout.imbue(locale(cout.getloc(), facet));
cout << second_clock::local_time() << endl;
}
$ g++ -o /tmp/bft_dyn boost_formatted_time.cpp -lboost_date_time
$ g++ -static -o /tmp/bft_stc boost_formatted_time.cpp -lboost_date_time
$ ls -lh /tmp/bft_*
-rwxr-xr-x 1 edd edd 216K 2010-02-24 12:34 /tmp/bft_dyn
-rwxr-xr-x 1 edd edd 1.5M 2010-02-24 12:34 /tmp/bft_stc
$ /tmp/bft_dyn
24-Feb-2010 12:34:55
$ /tmp/bft_stc
24-Feb-2010 12:34:59
$
Note how the static binary is 1.5mb as opposed to 216kb for the dynamically-linked variant.
All done on Debian testing with the default Boost packages.
Related Topics
How to Create Virtual Environment for Python 3.7.0
Force Gnu Linker to Generate 32 Bit Elf Executables
Linux Combine Two Files by Column
Hardware Acceleration Without X
"Cannot Execute Binary File" When Trying to Run a Shell Script on Linux
Npm Can't Install Appjs. Error: Cannot Find Module 'Graceful-Fs'
How to Set Java Classpath in Linux
How to Search an Image for Subimages Using Linux Console
Equivalent Date from Gnu to Solaris
Shell Script Get Ctrl+Z with Trap
How to Setup and Clone a Remote Git Repo on Windows
How to Compile Glibc 32Bit on an X86_64 MAChine
Ps: Clean Way to Only Get Parent Processes
How to Give Highest Priority to Ethernet Interrupt in Linux
Fork() Failing with Out of Memory Error