What does the -MM flag do in g++? - c++

I have read the explanation on the manual page (https://linux.die.net/man/1/g++) but I still do not understand its use cases. I have seen it used in the example below:
g++ -MM -w --std=c++14 `pkg-config fuse3 --cflags` -fpermissive -I.. hello.cpp > .obj/hello.d
I would like to understand when and why it is used.

The .obj/hello.d file you obtain probably looks like this.
hello.o: hello.cpp something.h stuff.h ...
This is a dependency rule for a makefile.
If your makefile uses something like
-include .obj/*.d
then it will be the same as if you explicitly wrote these dependencies.
If a generic rule knows how to generate a .o from the corresponding .cpp, then it will be triggered everytime one of those automaticaly listed header files is changed.

Related

Understanding Makefile. make cannot link armadillo library

I am new to C++ and I am having trouble understanding how Makefiles do their thing with the g++ compiler.
I have successfully installed armadillo library (via apt) and have a very simple c++ program test.cpp, like the one below:
#include <iostream>
#include <armadillo>
using namespace std;
int main()
{
arma::mat A;
A << -1 << 2 << arma::endr
<< 3 << 5;
cout << A << endl;
arma::fmat B;
B.randu(4,5);
cout << B;
return 0;
}
This works just fine if I compile manually like this:
g++ src/test.cpp -std=c++11 -Wall -o test -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
I can manually run the program and it delivers the matrices as expected.
On the other hand, I have the Makefile template from the VSCode C/C++ Extension, which I have modifed slightly for including the LAPACK an BLAS Fortran libraries:
########################################################################
####################### Makefile Template ##############################
########################################################################
# Compiler settings - Can be customized.
CC = g++
CXXFLAGS = -std=c++11 -Wall
LDFLAGS = -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
# Makefile settings - Can be customized.
APPNAME = test
EXT = .cpp
SRCDIR = src
OBJDIR = obj
############## Do not change anything from here downwards! #############
SRC = $(wildcard $(SRCDIR)/*$(EXT))
OBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP = $(OBJ:$(OBJDIR)/%.o=%.d)
# UNIX-based OS variables & settings
RM = rm
DELOBJ = $(OBJ)
# Windows OS variables & settings
DEL = del
EXE = .exe
WDELOBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)\\%.o)
########################################################################
####################### Targets beginning here #########################
########################################################################
all: $(APPNAME)
# Builds the app
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
# Creates the dependecy rules
%.d: $(SRCDIR)/%$(EXT)
#$(CPP) $(CFLAGS) $< -MM -MT $(#:%.d=$(OBJDIR)/%.o) >$#
# Includes all .h files
-include $(DEP)
# Building rule for .o files and its .c/.cpp in combination with all .h
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $# -c $<
################### Cleaning rules for Unix-based OS ###################
# Cleans complete project
.PHONY: clean
clean:
$(RM) $(DELOBJ) $(DEP) $(APPNAME)
# Cleans only all files with the extension .d
.PHONY: cleandep
cleandep:
$(RM) $(DEP)
#################### Cleaning rules for Windows OS #####################
# Cleans complete project
.PHONY: cleanw
cleanw:
$(DEL) $(WDELOBJ) $(DEP) $(APPNAME)$(EXE)
# Cleans only all files with the extension .d
.PHONY: cleandepw
cleandepw:
$(DEL) $(DEP)
I have passed the needed libraries under LDFLAGS = -DARMA_DONT_USE_WRAPPER -lopenblas -llapack. Nevertheless, this solution does not work. It looks to me like the compiler is unable to find the armadillo library, so I must have linked it somehow wrongly. It delivers:
g++ -std=c++11 -Wall -o test obj/test.o -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
/usr/bin/ld: obj/test.o: in function `TLS wrapper function for arma::arma_rng_cxx11_instance':
test.cpp:(.text._ZTWN4arma23arma_rng_cxx11_instanceE[_ZTWN4arma23arma_rng_cxx11_instanceE]+0x25): undefined reference to `arma::arma_rng_cxx11_instance'
collect2: error: ld returned 1 exit status
make: *** [Makefile:36: test] Error 1
So, aside from the obvious question (Why does this not work?), I would as well appreciate if someone could help me clarify as well the following aspects:
On the one hand, rom the message error it seems that the command run g++ -std=c++11 -Wall -o test obj/test.o -DARMA_DONT_USE_WRAPPER -lopenblas -llapack does not include the name of the cpp file I wrote (as opposed to in my manual compilation, in which it works). Nevertheless, if I do not use armadillo, the Makefile recipe above works just fine. I see the Makefile somehow looking for all cpp files in the source code folder SRC = $(wildcard $(SRCDIR)/*$(EXT)), but I cannot see where is this forwarded to the compiler. Can someone help me with that?
The other thing is that, in my manual compilation, it seems to make no difference to pass the LAPACK and BLAS libraries as CXXFLAGS or LDFLAGS, meaning both of the following commands:
g++ src/test.cpp -std=c++11 -Wall -DARMA_DONT_USE_WRAPPER -lopenblas -llapack -o test
and
g++ src/test.cpp -std=c++11 -Wall -o test -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
work just fine. As far as I have been able to read, I understood the flags before -o are meant for the compiler, and those after are meant for the "linker" (whatever that is). Can someone explain me what are the main differences between the CXXFLAGS and LDFLAGS? Why both combinations work? And what is the linker?
Thank you very much for your help.
Best,
D.
The other answer is a good general introduction to compilation but if you want to know what is happening in your situation you need to first understand that answer and the difference between source files, object files, and executable files and the way that they work, then go deeper to figure out what's wrong.
As far as I have been able to read, I understood the flags before -o are meant for the compiler, and those after are meant for the "linker" (whatever that is)
No, that is not right.
Turning source files into an executable involves several steps each managed by a different tool. The compiler front-end (e.g., g++) manages the order of these. Each of these may use different options, and whenever the compiler front-end invokes one of these tools it will pass the appropriate flags from the command line for that tool. It's not the case that "only" flags before or after -o are passed to different tools; it doesn't matter where on the command line they live.
The tools involved with compilation, in the order in which they're invoked, are:
Preprocessor: this handles #include and #ifdef and #define, etc. (the lines that start with # in your source). The preprocessor takes the options -D, -I, and some others.
Compiler: this turns your source code (after preprocessing to handle all the included files etc.) into assembly code which is very low-level: basically machine code but in ASCII form. This does the bulk of the work including optimization etc. Flags like -O2, -g, and many others are used by this tool.
Assembler: this turns the assembly code into a binary format for your CPU and generates an object file (foo.o).
Linker: this takes one or more object files plus libraries and turns them into an executable. This tool uses options like -L and -l to find libraries.
There's a separate tool, the archiver (ar) which is not invoked by the compiler front-end, which is used to turn object files (foo.o) into static libraries (libfoo.a).
Note, the above is a "classical" view of building: newer compilers munge the above steps together sometimes to get either better error messages or better optimization or both.
Most of the time the first three steps are all done by a single invocation of the compiler front-end: it turns a source file into an object file. You do this once for each source file. Then at the end, another invocation of the compiler front-end takes those object files and builds an executable.
If you look at the output make prints you'll see these two steps. First you'll see the compilation step, which is controlled by this make rule:
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $# -c $<
and runs this command:
g++ -std=c++11 -Wall -o obj/test.o -c src/test.cpp
The -c option here tells the compiler, "do all the steps up to and including the compile step, then stop and don't do the link step".
Then you will see your link command, which is controlled by this make rule:
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
and runs this command:
g++ -std=c++11 -Wall -o test obj/test.o -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
What do you notice about this? The -DARMA_DONT_USE_WRAPPER is a preprocessor option, but you're passing it to the link step and not passing it to the compile step. That means when the source is compiled, that option is not present and so whatever operation it was intended to suppress (using a wrapper apparently) is not being suppressed.
You need to put preprocessor options in a make variable that is sent to the compiler / preprocessor, so it should be this:
CXXFLAGS = -std=c++11 -Wall -DARMA_DONT_USE_WRAPPER
LDFLAGS = -lopenblas -llapack
Be sure to run clean before trying to build again.
One minor thing, but generally you should use CXX for your C++ compiler and CC for your C compiler (these are the usual conventions). If you do end up trying to compile C++ source with a C compiler you are likely to have problems. Less so the other way round.
So what it happening? Roughly speaking, you have two steps:
Compilation
Linking
When you compile a small exe, you can combine these into a single steps. Makefiles generally don't as two steps is more general.
For compilation the input has a .cpp suffix and you are passing the -c flag to tell the compiler to just compile. This will result in an object file (.o suffix).
For linking, there is no -c. The inputs are object files and the output is your application.
Other suffixes are possible (.cxx, .CC etc.).
There are 4 commonly used make variables
CPPFLAGS for preprocessor flags, can be used for C and C++ compilation
CFLAGS for flags specific to C compilation
CXXFLAGS for flags specific to C++ compilation
LDFLAGS for flags specific to linking
Historically, ld was the linker (and hence LDFLAGS), but it isn't smart enough to handle C++ linking well on its own. So now it is usually the C++ compiler that performs the task of "linker driver", that is g++ controls the linking that ld does.
Finally, your specific problem. You should add the armadillo library to LDFLAGS. The best way to do that is to just add -larmadillo. If armadillo is not installed in a 'standard' location like /usr/lib then you may need to additional arguments such as
-L/path//to/armadillo_lib -Wl,-rpath,/path//to/armadillo_lib
(the first one tells the linker where the library is, the second one puts that path into the executable so that is also knows where the library is).

How to write makefile for a target that includes a header file?

I have two files "create-exercise.cpp" and "exercise.hpp". I want to write a makefile to use gnu++17 and g++ to compile them. exercise.hpp is included in create-exercise.cpp. I only want to get a binary out of create-exercise.cpp. the command I would use is g++ -std=gnu++17 create-exercise.cpp -o create-exercise and it works well. I tried using the following in a make file.
CXXFLAGS=-Wall -std=gnu++17
create-exercise: create-exercise.cpp exercise.hpp
but that generated the following g++ -Wall -std=gnu++17 create-exercise.cpp exercise.hpp -o create-exercise I don't want exercise.hpp to be included in the compilation command. I also tried to use the following instead.
CXXFLAGS=-Wall -std=gnu++17
create-exercise.o: create-exercise.cpp exercise.hpp
That generated g++ -Wall -std=gnu++17 -c -o create-exercise.o create-exercise.cpp. I don't want the -c flag. because when I try to run create-exercise.o that results in permission denied error. I tried the following as well:
CXXFLAGS=-Wall -std=gnu++17
create-exercise.o: create-exercise.cpp exercise.hpp
$(CXX) $(CXXFLAGS) create-exercise.cpp -o create-exercise.o
but when I edit exercise.hpp make says 'create-exercise.o' is up to date. and doesn't recompile it. what should I do?
The rule to write in your makefile would be:
create-exercise.o: exercise.hpp
This is a rule without a recipe, and it simply adds one more prerequisite (exercise.hpp) to the target create-exercise.o, i.e., whenever exercise.hpp changes, create-exercise.o should be rebuilt.
However, the problem when providing that rule is that GNU Make assumes create-exercise.o is an object file generated from a C source file when building create-exercise. Therefore, it doesn't link the C++ library but the C library instead, that's why you are having the liking error of undefined reference to std::cout.
GNU Make has the following implicit rule for generating an executable from a C++ source file:
%: %.cpp
# commands to execute (built-in):
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
You can use that rule's recipe to build create-exercise from creating-exercise.o and still treat creating-exercise.o as an object file that was generated from a C++ source file:
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
The whole makefile would be then:
CXXFLAGS = -Wall -std=gnu++17
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
create-exercise.o: exercise.hpp
The target create-exercise also becomes the default goal because it's the first rule in the makefile. It's the target to build if you don't specify any to make.
You can do this:
CXXFLAGS = -Wall -std=gnu++17
create-exercise: create-exercise.o
$(LINK.cpp) $^ $(LDLIBS) -o $#
create-exercise.o: exercise.hpp
This says: build create-exercise from the object file create-exercise.o, if it's changed. And it says rebuild create-exercise.o if the header file exercise.hpp changes; it's not right to modify or rebuild a source file if a header changes. It's the object file that depends on the header.
Make has a number of built in rules. Among them are rules that know how to link a program but unfortunately that assumes your object files were built from C files, so if you're using C++ you have to create a specific recipe. But you can still use GNU make's default variables.
It also knows how to build a .o file from a .cpp file on its own: you don't need to write that recipe.
I am not sure, but maybe try to include the .hpp file instead of compiling it with the other file. You can do so by using g++ *.cpp -I *.hpp -o output
Try it out and let me know if it works for you.

Getting Cplex example to run: Undefined references

I am trying to get the Cplex basic LP example to work. The code can be found here. I am completely new with c++, but hope to be able to get this running.
I am trying to compile it on linux. I am using the following command to run it
g++ -D IL_STD -I /opt/ibm/ILOG/CPLEX_Studio1271/opl/include ilolpex1.cpp
The -D IL_STD was put there to solve an error as found here. The -I ... was put there to specify the location of the header files. I came up with this myself after a lot of trying and googling, so i am in no way sure this is correct.
Anyway, i when i run it i get errors of undefined references:
/tmp/ccl9O1YF.o: In function `populatebyrow(IloModel, IloNumVarArray, IloRangeArray)':
ilolpex1.cpp:(.text+0x18f): undefined reference to `IloNumVar::IloNumVar(IloEnv, double, double, IloNumVar::Type, char const*)'
I did not make any changes in the file, so i assume the only thing which can be wrong is how the files are linked. I have the feeling it probably just is a simple setting, but after hours of looking i still have no idea how to fix it.
The easiest way to compile the ilolpex1.cpp example is to use the Makefile that is included with the installation. For example, you should do the following:
$ cd /opt/ibm/ILOG/CPLEX_Studio1271/cplex/examples/x86-64_linux/static_pic
$ make ilolpex1
This will produce output, like the following:
g++ -O0 -c -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include ../../../examples/src/cpp/ilolpex1.cpp -o ilolpex1.o
g++ -O0 -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include -L../../../lib/x86-64_linux/static_pic -L../../../../concert/lib/x86-64_linux/static_pic -o ilolpex1 ilolpex1.o -lconcert -lilocplex -lcplex -lm -lpthread
This will tell you everything you'll need to know if you choose to compile your own application by hand in the future. The details about this are described in the documentation (e.g., here).
Obviously, the iloplex1.cpp file is just a demo how to use IloCplex.
What you yet need is IloCplex itself. This should come either as (a) further source file(s) you have to compile with the demo or as a library you link against.
Have a look at your cplex directories, you might find a lib[...].a file somewhere there, possibly in /opt/ibm/ILOG/CPLEX_Studio1271/opl/lib.
You can link against using GCC's (clang's) -l and -L options. Be aware that when using -l, you leave out lib and .a (-l [...] with above (invalid) sample name).

Can't make automake to use C++11

I'm working on some project and it seems that I can't make automake script to use C++11.
In rootdir of my project I have file Makefile.am which look like this (it was automade by eclipse):
SUBDIRS=src
Then in /rootdir/src I have Makefile.am that looks like this:
AM_CXXFLAGS=-Wall -fPIC -std=gnu++11 -DVERSION=\"$(VERSION)\" -DPROG="\"$(PACKAGE)\""
bin_PROGRAMS = algatorc
algatorc_SOURCES = algatorc.cpp
include_HEADERS = Timer.hpp TestSetIterator.hpp TestCase.hpp ETestSet.hpp EParameter.hpp Entity.hpp ParameterSet.hpp AbsAlgorithm.hpp Log.hpp JSON.hpp JSONValue.hpp
lib_LIBRARIES = libAlgatorc.a
libAlgatorc_a_SOURCES = ParameterSet.cpp TestCase.cpp EParameter.cpp ETestSet.cpp TestSetIterator.cpp Entity.cpp Timer.cpp JSON.cpp JSONValue.cpp AbsAlgorithm.cpp
algatorc_LDADD=libAlgatorc.a
So, I added -std=gnu++11 for C++11 support but I still get this error:
g++ -DPACKAGE_NAME=\"algatorc\" -DPACKAGE_TARNAME=\"algatorc\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"algatorc\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"algatorc\" -DVERSION=\"1.0\" -I. -g -O2 -MT algatorc.o -MD -MP -MF .deps/algatorc.Tpo -c -o algatorc.o algatorc.cpp
In file included from /usr/include/c++/4.8/thread:35:0,
from Log.hpp:281,
from algatorc.cpp:18:
/usr/include/c++/4.8/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \
^
And from this error I can see that g++ doesn't use -Wall -fPIC -std=gnu++11 but I don't see why. It's using something completely else.
This is my configure.ac script which is located in rootdir of my project
AC_PREREQ([2.69])
AC_INIT([algatorc], [0.1], [my_mail])
AC_CONFIG_SRCDIR([src/TestCase.hpp])
#AC_CONFIG_HEADERS([config.h])
LT_INIT
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h sys/time.h unistd.h wchar.h wctype.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_MKTIME
AC_CHECK_FUNCS([gettimeofday memset mkdir])
LIBS=-ldl
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
I have also tried to add AX_CXX_COMPILE_STDCXX_11 to configure.ac script but error still occurs. Any idea how to fix this?
I am using Ubuntu 12.04 x64, and Eclipse (Version: Mars Release (4.5.0))
A quick test shows that everything is working correctly for me, with a similar configuration, so you're going to have to figure out what's going on with your Makefile simply by rolling up your sleeves, looking into your final Makefile.
Look inside the automake-d Makefile. You should find somewhere inside it, the final build rule for .cpp.o. Search for ".cpp.o". It should look something like this:
.cpp.o:
$(AM_V_CXX)$(CXXCOMPILE) -MT $# -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $# $<
$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
After verifying this, the next step is to look at what your CXXCOMPILE macro is defined to. It should look something like this:
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
And that's your AM_CXXFLAGS variable being used. Finally, confirm how it's defined in the actual Makefile.
In my case, for my simple test, it was simply:
AM_CXXFLAGS = -std=gnu++11
In my case, it was just that, in your case, obviously you'll have your other flags in there.
That's it. The automake-d Makefile is obviously quite large, and looks intimidating, but when you get down to it, it's not very complicated at all.
It's going to be one of two things. Either another part of your Makefile.am clobbers the value of AM_CXXFLAGS, or the CXXCOMPILE macro is clobbered. One thing about automake, is that it generally doesn't complain if a macro or a variable is redefined. It'll simply generate the final Makefile using the final value of the variable. So, I would guess that somewhere later, in your Makefile.am, you set AM_CXXFLAGS to something else, without being aware of it here.
Note: the actual macros often get tweaked, with each successive version of automake, so yours may look slightly different, but the general idea should be the same. The .cpp.o build rule runs the CXXCOMPILE macro, which uses AM_CXXFLAGS.
First of all, automake will not generate Makefile until executing automake
So, I added -std=gnu++11 for C++11 support but I still get this error:
g++ -DPACKAGE_NAME=\"algatorc\" -DPACKAGE_TARNAME=\"algatorc\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"algatorc\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"algatorc\" -DVERSION=\"1.0\" -I. -g -O2 -MT algatorc.o -MD -MP -MF .deps/algatorc.Tpo -c -o algatorc.o algatorc.cpp
In file included from /usr/include/c++/4.8/thread:35:0,
from Log.hpp:281,
from algatorc.cpp:18:
/usr/include/c++/4.8/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \
^
Your log said there is no statement of -std=gnu++11 in gcc`s compile time. In other words, automake didn't generate Makefile containing statement of -std=gnu++11.
So, all you need to do is, in your project root with command line:
$ autoreconf
This will automatically execute aclocal, autoconf, automake and blah blah...
About checking the -std=c++11 flag
is good to use ax_cxx_compile_stdcxx_11.m4
To use it, you need to download it from the above link and set it in $(project_top)/m4/
Next, you write like below in configure.ac:
AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])
And exec, you can check it's possible or not to use C++11 feature in the platform
$ autoreconf -vi -I m4
$ ./configure

g++, creating static library for distribution

I have code that compiles well using the following makefile
all: sample
sample: sample.o mylib.o
g++ -Wall -O3 -ffast-math -funroll-loops -ansi -pedantic-errors -o sample -L/usr/lib sample.o mylib.o -lboost_serialization -lboost_iostreams -lz -I /usr/include/boost
sample.o: sample.cpp
g++ -O3 -ffast-math -funroll-loops -ansi -pedantic-errors -I /usr/include/boost -c -o sample.o sample.cpp
mylib.o: mylib.cc mylib.h
g++ -O3 -ffast-math -funroll-loops -ansi -pedantic-errors -I /usr/include/boost -c -o mylib.o mylib.cc
Now, mylib.cc and mylib.h contains a lot of useful code that I would like to share. However, it depends on Boost which my target audience might not have or know how to install properly.
Is there a way for me to distribute a mylib.o that is static with a mylib.h that my end user can just compile into their own code without needing to install Boost?
ADDITIONAL CLARIFICATION: mylib.h does not contain any BOOST headers, but mylib.cc DOES contain boost headers.
If mylib.h includes Boost header files, those will need to be present in some form on the developer's system. At a minimum, you would have to ship that part of Boost with your code.
However, if you can create a smaller header file that exposes just the pieces of your library and does not include nor reference anything in Boost, then you can. Most of Boost is header-only (the required Boost code will be compiled into your library already).
If you're able to create a "boost-free" header, you can do that.
As soon, as you have any references to boost stuff within the header (which you need to redistribute), you can't.
If your cc file uses boost classes which are not header-only, you need to distribute those files, too - either in sourcecode, or within an object-file - which however can lead to strange behavior, if an user uses another version of the boost library and tries to instantiate classes, which are already defined within your object files.
One possible solution would be to find out, which cc-files of boost are required and compile them within a different namespace, e.g. using -Dboost=my_boost:
g++ -Dboost=my_boost <put additional compiler options here> my_boost_file.cc -c my_boost_file.o
You also should compile your own object file with that define.
Finally create an archive containing all the required object files;
ar rvs my_archive.a mylib.o my_boost_file.o