Using Boost as a Library Dependency
I recently decided to refactor my library's API using the benefits given by boost::shared_ptr, so this now means my library uses boost. I'm trying to figure out how my installation process should go. Since I'm only using shared_ptr I've trimmed down a custom boost version that is only a few hundred k (rather than 10 megs) of just the files that I use. I've put the minimum boost files in my own directory structure so that my library can compile on its own. But when using the library, then what would the user do? Ideally I could have the installer for my library by copy the files to the compiler's include directory, but that's not particularly nice, espically since Boost is quite a popular library, and I don't want to litter up their include directory and most espically not overwrite any installation of Boost they have placed there. One thing that might work, if compilers support include directory "overrides" is if the user is using the full Boost library, to place its -I line before (or after?) the -I for my library, so that they can see my includes, but any boost includes will be "overridden" by their full version of Boost. But this leads to another question: If I compile my library with Boost x but the user has Boost y installed when he links with my library (I DO pass shared_ptr back and forth between user code, so it's not just used internally), what will happen? The shared_ptr interface seems to be oft changing, and so right now my code would only compile for Boost 1.30 (or later? Speaking of that, anyone know why there are no files listed for download for Boost 1.30.1 but it was announced a week ago?). I'm new to these things so I appreciate any feedback or answers you have. The library is just an open-source library I'm writing on my own free time, and I don't have a lot of experience from using/installing commercial C++ libraries to draw upon. Jason Winnebeck
In article
I recently decided to refactor my library's API using the benefits given by boost::shared_ptr, so this now means my library uses boost. I'm trying to figure out how my installation process should go.
Since I'm only using shared_ptr I've trimmed down a custom boost version that is only a few hundred k (rather than 10 megs) of just the files that I use. I've put the minimum boost files in my own directory structure so that my library can compile on its own.
That's a reasonable thing to do.
But when using the library, then what would the user do?
Ideally I could have the installer for my library by copy the files to the compiler's include directory, but that's not particularly nice, espically since Boost is quite a popular library, and I don't want to litter up their include directory and most espically not overwrite any installation of Boost they have placed there.
Putting things in the compile directories, any of them, is a really bad thing to do.
One thing that might work, if compilers support include directory "overrides" is if the user is using the full Boost library, to place its -I line before (or after?) the -I for my library, so that they can see my includes, but any boost includes will be "overridden" by their full version of Boost.
If you order them to be: user paths, then you library paths most compilers will search in that order and therefore you would get the override effect you want. CodeWarrior is the one exception I know about since it caches files it doesn't always override includes.
But this leads to another question: If I compile my library with Boost x but the user has Boost y installed when he links with my library (I DO pass shared_ptr back and forth between user code, so it's not just used internally), what will happen? The shared_ptr interface seems to be oft changing, and so right now my code would only compile for Boost 1.30 (or later?
Now that's the rub... Because of ABI incompatabilities you have to be exteremely carefull if you want to allow users to use a different Boost version than the one you provide. My suggestion is don't allow it... Unless you are providing source code to your library. The least problematic solution is to include your mini-Boost right in the same include directory that you are prociding for you library. You then only need to ask users to add your include to their configuration.
Speaking of that, anyone know why there are no files listed for download for Boost 1.30.1 but it was announced a week ago?).
Because of a misunderstanding in the making of the distribution there where serious problems with it. So Dave removed the files to prevent further questions about that release. He's working on a 1.30.2 release to remedy the situation.
I'm new to these things so I appreciate any feedback or answers you have. The library is just an open-source library I'm writing on my own free time, and I don't have a lot of experience from using/installing commercial C++ libraries to draw upon.
Ah, that answers the source question ;-) So you might be better off just telling users that they need to have some minimum Boost version and leave it at that. Most developers are smart enough to go get the Boost source and configure their compiler to know about it, on their own. HTH. -- -- grafik -- Don't Assume Anything
Rene Rivera wrote:
So you might be better off just telling users that they need to have some minimum Boost version and leave it at that. Most developers are smart enough to go get the Boost source and configure their compiler to know about it, on their own.
OK so what does "on their own" mean.
Because Boost headers include themselves with
In article
Here is ideally what I want: My boost is simple boost 1.30 unmodifed whatsoever but just the headers I need. If they don't have Boost at all and don't care about using Boost directly they can install my 100k or so mini-Boost files.
If they are willing to download a 10 meg Boost lib, or have the full Boost, I would like them to use that. My Boost is entirely unmodified and since my lib is open source I encourage them to compile my lib with the latest versions of the dependencies. I'd love nothing more than to see people willing to download the 10meg Boost for my 300k library and delete my mini-Boost.
OK, here's what I would do in your situation... Structure your distribution to have two downloads: one with the mini-boost, and the other without. The distribution with the mini-boot would already be set up to use it when it's used. You already have to tell users to add the include for your library. So include the mini-boost directory tree right in your libraries include directory. The distribution without mini-boost would require that users download, or somehow install a full Boost distribution. You then ask them to configure your library to use that installation. If you use something like autotools you can add some configure option. Or you can ask the user to set a BOOST_ROOT env var. But bassically since the user made the descition to use their own Boost installation they should know how to manage using it. PS. I'm working on a more standardized build+install sequence for Boost. So in the not so distant future it will be easier to tell people to download and install Boost ;-) -- -- grafik -- Don't Assume Anything
Jason Winnebeck
Rene Rivera wrote:
So you might be better off just telling users that they need to have some minimum Boost version and leave it at that. Most developers are smart enough to go get the Boost source and configure their compiler to know about it, on their own.
OK so what does "on their own" mean.
Because Boost headers include themselves with
boost MUST be in the compiler include path. That means it must be installed for the user's compiler path somehow.
I don't know what that means. With the appropriate command-line options you can get all compilers I know of to find them no matter where they're installed.
On Linux there is /usr/include which is OK to install stuff to but what about on Windows? For mingw32 there is no user include directory.
I have no problem using boost with mingw32. I keep my boost installation at c:/boost. My mingw32 is installed at c:/tools/mingw-2.0. -- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams wrote:
Jason Winnebeck
writes: I have no problem using boost with mingw32. I keep my boost installation at c:/boost. My mingw32 is installed at c:/tools/mingw-2.0.
Ok so you download my library. My library needs your boost to compile it. How does it find Boost? I have provided my makefile. What do you expect to have to do to my library to get it to find Boost. What do you want it to do? What is the least you expect it to handle? Unless there is some option I don't know about for Mingw, you are going to have to modify my makefile to point to Boost or define some environment variable so I know where it's at so I can add the proper -I line. Jason
Jason Winnebeck
David Abrahams wrote:
Jason Winnebeck
writes: I have no problem using boost with mingw32. I keep my boost installation at c:/boost. My mingw32 is installed at c:/tools/mingw-2.0. Ok so you download my library. My library needs your boost to compile it. How does it find Boost? I have provided my makefile. What do you expect to have to do to my library to get it to find Boost.
If you're using Boost.Build v2, I have an answer for you, but if you're using make, I can't help. Anyway, even if you're providing Makefiles, these are all standard problems you have to solve when using any 3rd party lib.
What do you want it to do? What is the least you expect it to handle?
?? I don't understand your questions. You're the one with a problem that needs to be solved.
Unless there is some option I don't know about for Mingw, you are going to have to modify my makefile to point to Boost or define some environment variable so I know where it's at so I can add the proper -I line.
Sure, or you're going to have to tell me about a location that gets put in the path used by your makefile so I can drop (a symlink to) my boost tree there. The use of angle-includes is irrelevant to all this, at least as far as GCC/mingw are concerned. -- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams wrote:
Jason Winnebeck
writes: What do you want it to do? What is the least you expect it to handle?
?? I don't understand your questions. You're the one with a problem that needs to be solved.
Perhaps I was unclear. I was asking it in the sense of "were you to download some non-commercial 3rd party library today that required Boost, what would you reasonably expect to be required to do to get it to use your boost?" The next question was sort of a second one asking what you would have to do ideally but the answer there is always nothing ;). Ideally what I would expect is something where it is very simple that requires you to type the path to your Boost once and only once.
Sure, or you're going to have to tell me about a location that gets put in the path used by your makefile so I can drop (a symlink to) my boost tree there. The use of angle-includes is irrelevant to all this, at least as far as GCC/mingw are concerned.
There are no symlinks in Windows. I suppose I can make an "include" makefile where you place your Boost directory in there. For some reason this solution is trivial and I just thought of it. Well that makes makefiles easy. As for Visual Studio... It's a bit more complicated I can look more to see what options I have. I know of at least one solution if I can't find a better one. Jason
Jason Winnebeck wrote:
I recently decided to refactor my library's API using the benefits given by boost::shared_ptr, so this now means my library uses boost. I'm trying to figure out how my installation process should go.
Since I'm only using shared_ptr I've trimmed down a custom boost version that is only a few hundred k (rather than 10 megs) of just the files that I use. I've put the minimum boost files in my own directory structure so that my library can compile on its own. But when using the library, then what would the user do?
Ideally I could have the installer for my library by copy the files to the compiler's include directory, but that's not particularly nice, espically since Boost is quite a popular library, and I don't want to litter up their include directory and most espically not overwrite any installation of Boost they have placed there.
If your installation has an include directory, the user normally must add
that directory to the compiler's include path in order to use your library.
Because of that, the best solution is to put whatever you have distributed
of Boost beneath your installation's include directory using the exact same
structure Boost already has. Now your end user, in order to use your
distributed Boost functionality, merely uses normal Boost include notation,
ie. #include
Edward Diener wrote:
Your only problem is if you distribute your particular subset of Boost with your product and your end user is also using another release of Boost within their product. Then they must take care to partition the functionality which you provide with Boost in separate source files from the functionality which the rest of their modules use with a different version of Boost. This shouldn't be too hard for source files, since it is normally very easy to divide class member function definitions in separate source files.
I really hope this doesn't become an issue. My library is open-source, so I strongly encourage people to recompile the library. If they have the full, real Boost, then I would say to completely delete my mini-Boost. It's only there so people don't have to download a 10 meg huge library, try for an hour to figure out how to compile it then realize they don't need to compile it (I did that!), all for a small-time open-source lib at 300k ;). Jason
Jason Winnebeck wrote:
But this leads to another question: If I compile my library with Boost x but the user has Boost y installed when he links with my library (I DO pass shared_ptr back and forth between user code, so it's not just used internally), what will happen? The shared_ptr interface seems to be oft changing, and so right now my code would only compile for Boost 1.30 (or later?
shared_ptr has recently been accepted into the Library Technical Report: http://std.dkuug.dk/jtc1/sc22/wg21/docs/library_technical_report.html http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1450.html Since modifications to the TR draft require a full committee vote, shared_ptr's interface will be much more stable now. Binary compatibility is another story. 1.30.x, 1.31.x and 1.32.x will likely be incompatible. But this is only an issue if you're shipping prebuilt binaries, not source.
Peter Dimov wrote:
shared_ptr has recently been accepted into the Library Technical Report:
Wow.. That's quite a read. The amount of work you Boost guys put into all of the subtle details is amazing. I found it quite interesting but what I was looking for was some rationale on not allowing comparing shared_ptr to NULL. Typically when I compare pointers, I often like to compare it like "if ( ptr != NULL )" explictly. I like this for three reasons: 1. It strongly shows that you are testing a pointer. 2. It reads better in terms of saying what you want. 3. I program in Java where it's required, so I'm in the habit ;). Although I do see some reasons why shared_ptr doesn't allow this test: 1. "As Close to Raw Pointers as Possible, but no Closer" 2. shared_ptrs after reset or default construction are "empty", a different concept than from "storing NULL". 3. If you allow a comparsion to NULL ( or 0 ), then the code "if ( mySharedPtr == myInt )" will compile but will make no sense. Is that pretty much the line of thinking there? Jason Winnebeck
Jason Winnebeck wrote:
Peter Dimov wrote:
shared_ptr has recently been accepted into the Library Technical Report:
Wow.. That's quite a read. The amount of work you Boost guys put into all of the subtle details is amazing. I found it quite interesting but what I was looking for was some rationale on not allowing comparing shared_ptr to NULL.
Typically when I compare pointers, I often like to compare it like "if ( ptr != NULL )" explictly. I like this for three reasons:
1. It strongly shows that you are testing a pointer. 2. It reads better in terms of saying what you want. 3. I program in Java where it's required, so I'm in the habit ;).
General "minimal but complete" principles, I guess. It is much easier to add a feature to a standard component at a later time than to take one away, and we already have to support if( p ) for declarations in conditions to work.
Peter Dimov wrote:
General "minimal but complete" principles, I guess. It is much easier to add a feature to a standard component at a later time than to take one away, and we already have to support if( p ) for declarations in conditions to work.
I already abstract away the choice of boost::shared_ptr behind my own symbol, partly because someday I wanted to use perhaps an intrusive pointer instead and deriving from a common base class. Because there are no template typedefs :( I had to do this by inheriting my class from boost::shared_ptr. I wonder if it would be "distasteful" in any way to provide an operator ==( int ) and a similar for !=? bool GNE::SmartPtr<T>::operator == ( int rhs ) { assert( rhs == 0 ); return ( *this ); } (Yes I know there is another class called SmartPtr in existance -- I found that out later. But that's why we have namespaces, no?) Jason
participants (5)
-
David Abrahams
-
Edward Diener
-
Jason Winnebeck
-
Peter Dimov
-
Rene Rivera