<div dir="ltr"><div>CMake builds for existing libraries are certainly an interesting and useful thing, and deserve to be posted in a GitHub repo somewhere.  They should also serve as the basis of a campaign to get the library authors to incorporate the CMake build directly in their repos.<div><br></div><div>But any approach that requires every build to be ported to CMake will be difficult and labor-prone to scale.  Writing a meta-build recipe is usually much easier.<div><br></div><div>Spack handles the combinatorial dependencies you mention in a sophisticated, graceful way that most meta-builders do not.  Its only problem is it does not (yet) run on Windows.  There's no fundamental reason why not; we just need someone to get involved and start trying it on Windows.</div><div><br></div><div>-- Elizabeth</div><div><br></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 16, 2016 at 6:52 AM, Florent Castelli <span dir="ltr"><<a href="mailto:florent.castelli@gmail.com" target="_blank">florent.castelli@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">At Spotify, we use CMake a lot for our large C++ library shared by all the clients.<br>
After trying to build libraries for each platform and variant, we basically gave up and we now<br>
use a super-build approach.<br>
<br>
For example, Boost is used by 5 platforms: Windows, OSX, Linux, Android and iOS.<br>
Each platform has a different CPU target (or many 32/64bit, x86/ARM).<br>
Each platform has many compilers.<br>
Some platforms have instrumentation options (Debug / Release, ASan, MSan…) and really need<br>
to be compiled properly, otherwise you’ll end up with false positives.<br>
The matrix of builds is REALLY hard to track. Each time we update Boost, we had to update<br>
a lot of things.<br>
I tried using ExternalProject and use b2 (build tool from Boost) to build it and instead of having<br>
lots of build jobs with a mirror of the flags, you end up mirroring the flags in your CMake files<br>
instead, which is still not good enough.<br>
<br>
In the end, I looked at how Boost is actually built. And for most libraries, it’s plain simple.<br>
A static library with a few files, some define, sometimes a platform specific source file.<br>
What if instead of having an external build tool, I built it from CMake instead?<br>
It would propagate all the build flags, target, instrumentation and compiler information from the main<br>
build to it and just work.<br>
I tried it and it worked in no time! We replaced our Boost 1.59 binary distribution with the source<br>
distribution and it’s much easier. When people build our library for a different target, they don’t have<br>
to download new binaries, they just reuse the same sources.<br>
Later on, we found a bug in Boost 1.59 (fixed in later versions) and patched it. We updated our source<br>
bundle and everything was smooth.<br>
Much later on, we wanted to use 1.61. We just updated the source bundle again, the list of source<br>
files or compilation flags for the libraries we use didn’t change. It was again effortless.<br>
<br>
Overall, building boost takes 10s on our developers’ machines. The sources aren’t changed often,<br>
so the cost is pretty low. It needs attention when we upgrade it, but that’s quite rare.<br>
<br>
We try now to use the same approach for other libraries when we add them. Some of them are<br>
already using CMake and it’s somewhat easier, but since most people still target version 2.8 (or 2.6...),<br>
we find it better to rewrite the build scripts ourselves and use modern features (as in, everything is<br>
a target that propagates requirements, we don’t propagate variables).<br>
It makes it also much easier to build a library for another platform that wasn’t targeted by the original<br>
project.<br>
<br>
If people are interested, I could share the CMakeLists.txt file we use for Boost. It doesn’t build all<br>
the libraries (some are hard like Context) and uses some internal macros, but it should be plain<br>
simple to tweak for your use.<br>
<br>
/Florent<br>
<div><div class="h5"><br>
> On 12 Aug 2016, at 21:59, Robert Dailey <<a href="mailto:rcdailey.lists@gmail.com">rcdailey.lists@gmail.com</a>> wrote:<br>
><br>
> Hello,<br>
><br>
> There is an internal C++ product at the company I work for which I<br>
> have written a series of CMake scripts for. This project actually has<br>
> dependencies on several open source libraries, such as boost,<br>
> freetype, openssl, etc.<br>
><br>
> Right now what we do is build each of these third party libraries *by<br>
> hand*, once for every platform we support (Windows, Linux x86, Android<br>
> NDK). Then we stuff the includes (headers) and libraries<br>
> (static/shared) in a submodule and the primary code base's CMake<br>
> scripts pull them in as interface targets.<br>
><br>
> This works well and is light-weight but is a pain when upgrading or<br>
> changing libraries. It's a pain because if I want to upgrade boost, I<br>
> have to build it up to 6 times (once for each platform and once for<br>
> each configuration).<br>
><br>
> I've been thinking of a different approach for a while. I've done some<br>
> toying around with the "Super Build" concept, where I have a separate<br>
> CMake project that does nothing but use the ExternalProject module to<br>
> build libraries in real time along with our project. So the order of<br>
> operations would be as follows (for our automated build server):<br>
><br>
> 1. Clone our "Third Party" repository<br>
> 2. Use CMake to generate & build the "Super Build" project (this<br>
> builds boost, openssl, freetype, etc for the current platform).<br>
> 3. Clone the main code base's repository<br>
> 4. Use CMake to generate & build, using find_package() to refer to<br>
> interface targets exported by those third party libraries built in<br>
> step 2<br>
><br>
> Obviously this will make builds take significantly longer, because<br>
> we're constantly rebuilding the same third party libraries over and<br>
> over again. However, it virtually eliminates the maintenance burden<br>
> for third party libraries because they are built inherently with<br>
> everything else.<br>
><br>
> Note that I can't refer to pre-built libraries in our build<br>
> environments because we need very specific control over the versions<br>
> of our libraries as well as the toolchains that were used to build<br>
> them. Also we may specifically build our libraries a certain way (such<br>
> as boost). For this reason we do not rely on our external environment<br>
> or external package managers to fulfill third party dependencies, like<br>
> most open source projects do on Linux for example.<br>
><br>
> Does this "Super Build" approach sound like a better idea? What other<br>
> options are available? The downside with the "Super Build" solution is<br>
> that it will become very difficult to make the transition between<br>
> building third party and building our code base seamless. I can't do<br>
> both in the same generate step because find_package() can't be called<br>
> until the libraries are built & installed.<br>
> --<br>
><br>
> Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
><br>
> Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" rel="noreferrer" target="_blank">http://www.cmake.org/Wiki/<wbr>CMake_FAQ</a><br>
><br>
> Kitware offers various services to support the CMake community. For more information on each offering, please visit:<br>
><br>
> CMake Support: <a href="http://cmake.org/cmake/help/support.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/<wbr>support.html</a><br>
> CMake Consulting: <a href="http://cmake.org/cmake/help/consulting.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/<wbr>consulting.html</a><br>
> CMake Training Courses: <a href="http://cmake.org/cmake/help/training.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/<wbr>training.html</a><br>
><br>
> Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/<wbr>opensource/opensource.html</a><br>
><br>
> Follow this link to subscribe/unsubscribe:<br>
</div></div>> <a href="http://public.kitware.com/mailman/listinfo/cmake-developers" rel="noreferrer" target="_blank">http://public.kitware.com/<wbr>mailman/listinfo/cmake-<wbr>developers</a><br>
<span class=""><br>
--<br>
<br>
Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
<br>
Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" rel="noreferrer" target="_blank">http://www.cmake.org/Wiki/<wbr>CMake_FAQ</a><br>
<br>
Kitware offers various services to support the CMake community. For more information on each offering, please visit:<br>
<br>
CMake Support: <a href="http://cmake.org/cmake/help/support.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/<wbr>support.html</a><br>
CMake Consulting: <a href="http://cmake.org/cmake/help/consulting.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/<wbr>consulting.html</a><br>
CMake Training Courses: <a href="http://cmake.org/cmake/help/training.html" rel="noreferrer" target="_blank">http://cmake.org/cmake/help/<wbr>training.html</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/<wbr>opensource/opensource.html</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
</span><a href="http://public.kitware.com/mailman/listinfo/cmake-developers" rel="noreferrer" target="_blank">http://public.kitware.com/<wbr>mailman/listinfo/cmake-<wbr>developers</a></blockquote></div><br></div>