Show HN: Buckaroo – A decentralized C++ package manager
github.com
github.com
https://github.com/LoopPerfect/buckaroo/blob/2714cd4c9e20235c4a090d21d0f60a0a9f17e82f/buckaroo-cli/Program.fs#L9-L13
https://github.com/LoopPerfect/buckaroo/blob/master/buckaroo/Telemetry.fs
This should be opt-in not opt-out or be clearly mentioned in the docs how to turn it off.https://github.com/LoopPerfect/buckaroo/wiki/Installation#te...
https://github.com/LoopPerfect/buckaroo/wiki/Telemetry
We gather this data so we can improve Buckaroo and it's ecosystem.
My experience using buckaroo in a large project over the past year has been extremely positive, and I'd say addresses most of the problems raised here. It's far and away better than anything else I've used.
Your experience (using buckaroo ...) adresses most of the problems raised here? You could perhaps share at least how your experience adressess some of these problems raised here: how does your experience address the hidden telemetry for example?
I've finished reading manual on Nix and just started with documentation on packaging. I want to have total control on dependencies, together with compiler versions and standard library implementations (effectively cross compiling everything x86_64 -> x86_64). From Buckaroo, Conan and Nix, only Nix gets this right...
The main problem seems to be that because there is no standard C++ build system, every library uses a different one. Wrangling all those together without requiring the library authors to do anything is extremely difficult.
Hell many C++ libraries still use autotools or hand-written Makefiles. I don't really see how it is even possible to automatically download and build those projects.
However we have seen more than 300 ports back in 2017 [1] and saw many emerging patterns. This enabled us to write rules to transpile and optimize 100s of build-systems to buck using buildinfer [2] [3]. We hope that more sane decisions will be made regarding build-systems in new projects. We discovered analyzing over 300 projects that a lot of complexity is not needed and often a non-turing complete language for describing the build is sufficient. In fact we found that over 90% of projects can be described solely by using glob expressions.
[1] https://hackernoon.com/lessons-learned-from-porting-300-proj...
[2] https://hackernoon.com/announcing-buildinfer-for-c-3dfa3eb15...
OpenSSL buildsystem is over 6k lines of perl scripts which communicate over pipes.
OpenCV uses cmake, python and prolog for it's build. Until this day, I have no clue why there is prolog involved.
You can read some bits about it in our initial announcement of buildinfer: https://hackernoon.com/announcing-buildinfer-for-c-3dfa3eb15...
You could structure something around CMake.
One immediate issue is compilation flags and platforms management. You may need to use some custom flags, for example, you need to compile against a specific architecture. You want those flags to be passed to all libraries uniformly.
But the horrible problem is quickly the compatibility matrix.
In other words, if you are making available, let's say you are using alib v1 and blib v2, you need to check the two libraries compile, link, and work together nicely. So when you upgrade one of the libraries, you need to check that compatibility again.
It's an important problem because if you're working on production software, you need to be able to build all versions and maintain them. And maybe you will have to upgrade only one library. You can't always be "current" everywhere.
So very quickly, using a package manager becomes more painful than having the libraries management manually with a couple of custom scripts.
I'll be happily be proven wrong by a package manager (and we tried a lot).
I mostly work in Windows development. CMake scripts created by a professional build engineer caused a lot of havoc. It injected itself into the project files in such an insidious fashion, that it was nearly impossible to tell if dependencies were correct. It completely broke Intellisense, making code navigation an exercise in frustration.
I was not happy, and wound up ripping out the scripts and creating new solution and project files that actually supported the needs of the developers.
(Edited to remove typos and improve grammar)
so i mean what e.g. conan does is acknowledge this and require that package creators provide "recipes" that tell conan how to build the project.
buckaroo seems to take a similar approach: https://github.com/LoopPerfect/buckaroo/wiki/Creating-a-Pack...
i will say that in my time using conan to attempt to solve for compiling an application for x86 and a few flavors of ARM, this is NOT a silver bullet.. a huge fraction of third party libraries we tried to pull in needed to have their recipes modified to build correctly.
1. Conan does not require a server. If a project contains a conanfile.py with build instructions, you can also run `conan create` from a project's source repository (no server required).
2. You can easily force build dependencies with the `--build *` flag
What we really need are automated porting tools to fix this mess!
The wildcard is cross-platform. vcpkg doesn't seem to be 100% there and has many bugs for example the folders where includes and libraries are kept changes based on platform.
The other problem is static vs dynamic linking, as well as conflicts between different combinations of cmt libs etc. it gets very messy quickly.
Its almost like you're spending more time trying to get all the libraries you want working together than actually coding.
[1] https://buckbuild.com/files-and-dirs/buckconfig.html#cache
Lastly I'd like to note that Buck and Bazel are converging to Skylark for describing builds. The differences between Buck and Bazel should become smaller over time
> just one file, download here...
Later on:
> You'll need Buck on your system
Then, on Buck's site:
> Buck requirements: Java 8, Apache Ant, Python 2.7, ...
Well, that does not seems too honest, would be best to warn upfront about all these dependencies.
So in order to include some library I'll put
#include source "libpng/png.c";
in my main.c file. And that png.c may look as: #include source "png-a.c"
#include source "png-b.c"
#ifdef PNG_FEATURE_C
#include source "png-b.c"
#endif
...
And that would be it.C/C++ preprocessor is enough for configuration.
#include source "path.c"; compiles and includes path.c as a new compilation unit ( https://en.wikipedia.org/wiki/Single_Compilation_Unit ) .
So if a-file.c and b-file.c are both have
static int foo = 42;
then these two files can be successfully included as #include source "a-file.c"
#include source "b-file.c"
But this: #include "a-file.c"
#include "b-file.c"
will produce the error "foo is already defined"This small feature will allow 99% of existing libraries to be included this way - without any makefile, GUP, GIP and the rest of the zoo.
Now I can put in Microsoft VC++ this
#pragma comment(lib, "some.lib")
to include the library into final binary.#include source is just a generalization of the idea.
> as a new compilation unit ( https://en.wikipedia.org/wiki/Single_Compilation_Unit )
> Single Compilation Unit (SCU) is a computer programming technique [...] The technique can be applied to an entire program or to some subset of source files; when applied to an entire program, it is also known as a unity build.
Who came up with that? I would say this "technique" doesn't even justify having a wikipedia page. In modern c++ you can be glad if you have a c++ unit that doesn't need to recompile on change because of all the header-only stuff. No one would include .cpp-files by choice.
That's how C and C++ work.
And if you will have this (no static):
int foo = 45;
then linker will complain - "multiple 'foo' entities" as non-static entities have global visibility.not so, static declaration are local for the compilation unit so you may have as many different foo's as files you have in your project.
The Buckaroo workflow looks like this:
# Create your project file
$ buckaroo init
# Install dependencies
$ buckaroo add github.com/buckaroo-pm/boost-thread@branch=master
# Run your code
$ buck run :my-app
And yet another development tool that wants to hijack my workflow. No thanksConan.io already does decentralization right and is well on the way on becoming the defacto standard package manager for C++. And all of that without constraining my workflows
Afaik this is not supported by conan
Any other recipe can then depend on any package that is already in the cache.
You can even just export any recipes into your local cache without manually building the package and then let conan do the work when you require the package as a dependency (using --build all)
So to see if I have this right:
With Conan, to use a package from GitHub, I must download the recipe and add it to my local cache ("cache" seems like the wrong term here, maybe "registry" would be better?) and then I can install it?
What about the transitive dependencies? Do I need to repeat the process for each of those?
Yeah, the term conan "cache" may be a bit misleading, as it is not only a cache but really your "local remote". As soon as a recipe is in your cache, you can depend on it from your own recipes/conan builds. The actual building of the package may happen during the registration of the recipe or during resolve time when you depend on a certain package configuration. Any transitive dependencies will be resolved and, in case of --build missing, the packages will be built automatically according to the recipe.
So no, you do not need to build any dependency packages (including transitive dependencies)
This is impractical if a complex dependency graph as it would require the user to solve a SAT problem just to determine which packages and versions to put into the conan cache to avoid pulling from the conan server.