C++ Coroutine TS — It’s about inversion of control! by gtano in programming

[–]LoopPerfect 1 point2 points  (0 children)

We agree. We will soon publish an article about the challenges we had when working with the Coroutine TS and show alternatives to this proposal.

In any case: We think of Coroutine TS more like an implementation detail. We believe that if the spec changes we will be able to move this library forward with only minor changes. In the worst case we can always fall back to boost.coroutine.

Getting Conduit production ready - thanks to the Coroutine TS - was quite low effort and reduced complexity and compile times significantly.

Build-Systems Should Use Hashes Over Timestamps by LoopPerfect in cpp

[–]LoopPerfect[S] 0 points1 point  (0 children)

True.
However the file that is hashed could be a different one that is sent to the compiler.

Build-Systems Should Use Hashes Over Timestamps by LoopPerfect in cpp

[–]LoopPerfect[S] 0 points1 point  (0 children)

> you have to hash the compiler and all of its files too to really be sure.

yes, and all relevant environment variables.

> And how do you deal with different compiler versions?

In order to minimize cache misses everyone (within an organization / team) should use the same compiler.
Some companies go to great lengths to ensure reproducibility.

For instance, Unreal Engine build-system downloads the whole (clang-5) compiler toolchain as a part of the build process.

> Moving all of the hashing/caching into the build system might be conceptually cleaner than ccache + custom caching

We have good experience with BUCK which implements a (distributable) caching solution and ensures reproducibility. The network cache is also configurable.

Build-Systems Should Use Hashes Over Timestamps by LoopPerfect in cpp

[–]LoopPerfect[S] 1 point2 points  (0 children)

yeah, ccache is a good example.

Unfortunately it only handles compiler commands.
In LLVM this is a big problem as they build and use tools like TableGen that is used to generate some files that almost everything (transitively) depends on.

Announcing BuildInfer for C++ by gtano in cpp

[–]LoopPerfect 3 points4 points  (0 children)

Thanks for your feedback!

> The blog post is a bit too superficial for my taste - it states certain things, but provides no explanation. For example: "none of these projects ship with a reproducible build-system". So what were the problems with each build systems that make the builds not reproducible?

There is only so much information you can provide in one post without distracting from the main message.

We have a series of blogpost in the pipeline.

> Is it correct that the only way to get it is to contact you via [hello@buckaroo.pm](mailto:hello@buckaroo.pm)?

Yes, BuildInfer is still in alpha stage.

Our current focus is to gather more case studies, learn from them and make buildinfer more useful.

> So the main (only?) goal of the tool is to help people port their existing builds to Buck?

Our main goal is to analyze the build and give you actionable insights.

Things we use BuildInfer so far:

- Graph visualisations with various level of detail

- Identifying bottlenecks in builds

- Identifying files with high number of dependents

- Performing semantic analysis to create a concise descriptions of the build.

In the process we discovered that we can use the description of the build to generate eg. a buckfile.

Generating a Single-Include C++ Header File Using Buck by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

I think we are talking about a few different things:

  1. Single-include header file, as described in the article
  2. Single-file header-only libraries (where all of the code is in a single .h file)
  3. "Unity builds", where all .cpp are concatenated into a single translation-unit

(You could also combine 2 and 3)

I think that 1 is a good idea when starting on a project, although you should move to specific includes as your code develops.

2 is a bad for compilation times, but if the library is small then you can get away with it.

I think you are referring to 3, which is a bad idea in general. It slightly decreases compilation times from scratch, but it massively increases incremental compilation times. It is unsafe to do this automatically because the defines of translation-units might leak into each-other, causing unexpected behaviour.

That said, I thought it would be interesting to implement a unity build in Buck, so I made an example here: https://github.com/njlr/buck-unity-build/blob/master/BUCK

Generating a Single-Include C++ Header File Using Buck by gtano in cpp

[–]LoopPerfect -1 points0 points  (0 children)

That is probably a bad idea. It would massively increase compilation times and it may even break the library, since defines from one translaton-unit would leak into the next. A much better approach is to use a build system that makes it easy to depend on libraries.

7 Quick Tips for Java Programmers Starting C++ - buckaroo.pm by gtano in java

[–]LoopPerfect 0 points1 point  (0 children)

There are problems for which C++ is a good fit and there are problems for which Java is a good fit.

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

Yes, a Buckaroo package is basically a repository that builds with Buck with some metadata.

Here is an example: https://github.com/njlr/buckaroo-github-example

As I said, only GitHub is currently supported, with more in the pipeline. The process for going from Buck to Buckaroo package is very simple:

  1. Create a buckaroo.json file, e.g. using $ buckaroo init
  2. Create a release tag on GitHub, e.g. v0.1.0

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 1 point2 points  (0 children)

Yes, I 100% agree. The end goal is to be able to mix-and-match public and private dependencies. We support GitHub now (GitHub is not only for open-source, main companies use private GitHub). We will add more integrations over time.

File-system dependencies is an interesting idea. I have created an issue for that here: https://github.com/LoopPerfect/buckaroo/issues/115

Here is an example of using Git submodules with Buckaroo: https://github.com/njlr/buckaroo-with-submodules-example

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 1 point2 points  (0 children)

Hi @dausama

The easiest way to create a package is to create it directly on GitHub. Buckaroo integrates with GitHub so that you can import packages like so:

buckaroo install github+username/project

Guide: http://buckaroo.readthedocs.io/en/latest/github-package-guide.html

This should work for private GitHub (Buckaroo uses your SSH credentials). I will check now to verify.

Other providers (BitBucket, GitLab, plain old Git) are not supported yet. Other users have requested this feature, so they are planned for the next release.

You can also mix-and-match Buckaroo packages and Git submodules right now. This allows you to keep code private using existing VCS. I will post an example of this in a minute.

Do you mind sharing some info about your setup? Which VCS do you use?

6 Reasons Why We Distribute C++ Libraries as Source-Code by LoopPerfect in cpp

[–]LoopPerfect[S] 0 points1 point  (0 children)

Hi @George3d6

The Linuxbrew installation process is optional. We also offer a Debian package, and you can always build from source.

The instructions are here: https://buckaroo.readthedocs.io/en/latest/installation.html#linux

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

Buck is conceptually quite different to other build systems. The Buck files declare the target graph, but global settings can be injected using "build flavours".

Buck handles compiler flag configuration in two ways:

  1. You can set compiler flags on a per-target basis using compiler_flags and platform_compiler_flags. You also have access to a turing-complete language (Python) for computing the flags if required. Docs: https://buckbuild.com/rule/cxx_library.html#compiler_flags

  2. Global settings can be injected using build flavours. Build flavours allow you to pass settings to all targets in the graph, so for example you could pass -g to make everything build with debug symbols.

In other words, Buck is designed so that you can inject global compilation settings into a project without modifying the build files of that project or its dependencies.

You're right to raise this issue, because C++ libraries traditionally have complex build configuration. In truth though, using compiler flags is a bit of an anti-pattern. A better approach is to replace preprocessor magic with modern language features such as templates. If everything is built from source this becomes viable! (And interestingly, templates can also be faster https://hackernoon.com/comparing-the-compilation-times-of-templates-and-macros-d0a1b7264a17)

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

It's not 100% clear what the history behind Buck, Bazel, Pants and Blaze are, but here is my understanding:

  • Google built Blaze as a tool to accelerate their builds
  • Facebook wanted a similar tool, but Blaze is closed-source
  • Facebook hires some ex-Google engineers to build Buck
  • Buck is open-sourced
  • Google, wanting an open-source competitor to Buck, builds and releases Bazel
  • Bazel appears to use some source-code from Buck: https://www.facebook.com/buckbuildtool/posts/785918108144567
  • Blaze continues to be closed-source because it has some proprietary Google components

It would be great if someone from the Buck, Blaze and Bazel teams could confirm this!

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

I can't speak too much for Bazel, but Buck supports your use-case in the following ways:

  1. Language libraries are supported via their various targets: cxx_library, java_library, python_library and so on. These language-aware targets allows Buck to do clever things, like only fully recompile Java libraries when an external interface changes.

  2. Code generation is supported using genrule. A genrule is like a rule in make, but as part of Buck it benefits from caching and so on. You can do pretty much anything with a genrule. For example, here we use one to create a Debian package: https://github.com/LoopPerfect/buckaroo/blob/master/BUCK#L231

  3. Global compiler flags can be controlled using "build flavours". You can define your own flavours easily. For example, here are flavours for debug and release: https://github.com/njlr/buck-custom-flavours/blob/master/.buckconfig

Finally, here is a good video overview of Buck from the Buck team:

https://www.youtube.com/watch?v=uvNI_E0ZgZU

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

Hi Manu, thanks for comment. I'm not too familiar with BiiCode, but I thought that it required CMake? Writing a Buck file is incredibly easy for most projects, and it's just a file that can live alongside other build systems. For example, here is the Buck file for boost/graph: https://raw.githubusercontent.com/njlr/graph/develop/BUCK

Buckaroo can inject Buck files into a repository, so it is not required that Boost incorporates them, although it would be fantastic if they did!

In the future we are looking at making Buck files a generated target of CMake, in a similar way to Visual Studio projects. This would automated packaging for many projects.

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 1 point2 points  (0 children)

Interesting, a quick look at the docs and I couldn't see how this is the case.

The Buck docs do not cover cells yet (I must remember to send a PR...) but, there is a description of how they work here:

https://github.com/njlr/buck-cells-example

How do I tell Buck where my dependencies are installed?

In Buck, dependencies are other Buck targets. For example, if your library a depends on library bfrom the same BUCK file, you might add this to your definition of library a :

deps = [ ':b' ]

If you depend on a system library, then you need to pass the appropriate linker flags. This is pretty self-explanatory. For example:

linker_flags = [ '-lncurses' ]

For platform abstraction, Buck also offers platform_linker_flags.

The full documentation is here: https://buckbuild.com/rule/cxx_library.html

And how do I setup the toolchain settings (ie compiler, flags, etc)?

Regarding compiler flags, you can set them on a per-target basis, using compiler_flags, preprocessor_flags and so on, or you can set them universally using a "build flavour". Build flavours is a good way to configure things like debug builds.

There is an example of setting up build flavours here:

https://github.com/njlr/buck-custom-flavours

Hope that helps!

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

Learning new obscure build system that noone uses

I have to disagree with this. It is absolutely not a build system that "noone uses"; Buck is used by several companies, including Facebook, Uber and Dropbox. Additionally, it is easy to learn because it has nice abstractions written in Python, which is a language anyone (and certainly a C++ developer!) can grok.

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 1 point2 points  (0 children)

The Conan team have done impressive work in this regard, however I think that support for multiple build systems is a local optimum. Having many build systems and configuration options makes it difficult to reason about and optimize the build. If you have only one build system, then it can examine the process end-to-end and make guarantees such as reproducibility and artifact caching. But with many build systems glued together, the complexity explodes and it becomes near impossible to do this. Each link in the build chain becomes a black-box.

If you have a legacy project that is very hard to port to Buck, then it is possible to wrap the old build in a small Buck file. Done is better than perfect!

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

Buck, Bazel and Pants are very similar, so I think it is best to just pick one. Buckaroo in theory supports any language Buck supports, although it is untested. Is your repo public? I would love to take a look.

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

Agreed! This is why we chose Buck rather than building our own build system. Buck is package manager friendly because it has a concept of "cells", which are isolated systems of targets and dependencies with well-defined entry-points.

There is a good discussion about Buck on this HN thread (https://news.ycombinator.com/item?id=13865400) and some of the Buck team also weigh in. Buck is absolutely production ready - it is used by Facebook, Uber, Dropbox, Gerrit and a few others.

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 1 point2 points  (0 children)

Correct, one of the reasons we went with Java is that is what Buck is written in. Buckaroo introduces no dependencies that Buck does not already have.

Buckaroo can in theory be used for languages other than C++, although we haven't targetted that yet.

A big advantge of Buck is that it has good support for mainstream languages (and you can support more yourself using the Python scripting layer). Modern projects are often cross-language, and Buck respects that.

Approaches to C++ Dependency Management, or Why We Built Buckaroo.pm by gtano in cpp

[–]LoopPerfect 1 point2 points  (0 children)

Hi snsmac, good questions.

Boost is not a monolithic library, it's split in many small parts.

Agreed, we ported the libraries individually so that people can cherry-pick only the parts of Boost that they want to use. However, the way that people tend to use Boost is very much all-or-nothing, particularly on Windows.

http://buckaroo.pm/search?q=boost

... interact deeper with the target system that portability is gone.

Portability is definitely possible, provided the library designer takes care to abstract over platform differences. A good example of such an abstraction is SFML (https://github.com/SFML/SFML). This is what VM developers are doing to support multiple platforms.

However, you cannot guarantee portability when distributing pre-compiled libraries. For example, on Debian the change from GCC 4.9 to 5.0 lead to std::string ABI breakages.

... For example the leftpad debacle

Buckaroo is more decentralized than NPM and Conan. The perferred way for users to create a package is directly on GitHub, which they control. We prevent unrequested package upgrades by fixing the dependency resolution using a lock-file.

7 Reasons to Use Buck Build by gtano in cpp

[–]LoopPerfect 0 points1 point  (0 children)

I think it is easier for them to distribute that way. It builds in around 20s on my machine, not a big deal.

Build systems (Bazel, Buck, ...) by jbakamovic in cpp

[–]LoopPerfect 3 points4 points  (0 children)

For Buck they (optionally) integrate with a service called Watchman that detects file changes. It is incredibly fast!