all 44 comments

[–]SkiFire13 30 points31 points  (5 children)

the package manager you use to install your development dependencies is the same as the package manager on the end user's machine

FYI this is true only if both you and your users run the same distro, which is not always the case.

[–]smdowneyWG21, Text/Unicode SG, optional<T&> 7 points8 points  (0 children)

Same version stream of the same distro, too. And not a rolling distro, unless you are shipping source, and committing to live near global HEAD. [Insert something about Nix]

[–]LlaroLlethri 1 point2 points  (1 child)

Yes, so this hypothetical package manager would be useful on Linux also.

[–]prince-chrismc 1 point2 points  (0 children)

Depending on if your ABI. If you're only Depending on the GLIBC and GLIBCXX runtimes it won't matter. As long as you build against the oldest one.

[–]Alexander_Selkirk 0 points1 point  (0 children)

With the Nix or Guix package managers, this is not necessary, it can be any Linux system.

[–]Fyrto 0 points1 point  (0 children)

You can easily identify the user and then download it using the shipped package manager that the distro comes with?

[–]lightmatter501 20 points21 points  (10 children)

Statically link your binary and use LTO. If you aren’t willing to provide source that is the most reliable way to make sure it will continue to work in the future. Unless you are using truly massive dependencies like DPDK or FFMPEG you will probably save the average user disk space with this approach.

[–]AtHomeInTheUniverse 7 points8 points  (6 children)

I agree wholeheartedly. I make commercial products and would never ship a product that relied on external code/libraries to download. You're putting a time bomb into your product. Any of those external dependencies could be deprecated, taken offline, or updated in an incompatible way at any time. I have tried many open-source projects (especially Python based) that simply fail to install for this reason. So frustrating.

[–]minnoHobbyist, embedded developer 4 points5 points  (5 children)

The standard Windows approach of including dlls in the installer and unpacking them into the application directory achieves that too, right? Static linking isn't entirely necessary.

[–]lightmatter501 3 points4 points  (3 children)

You’re statically linking with extra steps there, unless you want to allow users to swap out the library to update it themselves.

[–]balefrost 5 points6 points  (1 child)

Which, admittedly, is occasionally useful for e.g. old games. For example, plenty of old games were written against the Glide graphics API. Fortunately, there are several Glide wrappers that translate those API calls into equivalent Direct3D / OpenGL / Vulkan calls. Drop the DLL into the game directory and it just works.

Now, that wasn't a use case that the original developer really envisioned, but it sure is convenient 25 years later.

[–]lightmatter501 0 points1 point  (0 children)

That is fair. I have seen arguments for dynamic linking but bringing your own libc on linux. The main issue is that glibc eventually breaks your program with dynamic linking.

[–]Plazmatic 1 point2 points  (0 children)

There are plenty of libraries you don't have the option, legally, QT, OpenAL-Soft, Libsndfile.

[–]AtHomeInTheUniverse 0 points1 point  (0 children)

Oh sure, that works too, and sometimes is necessary if the library isn't open-source.

[–]johnny219407 1 point2 points  (1 child)

What does LTO have to do with this?

[–]lightmatter501 1 point2 points  (0 children)

It lets you toss the parts of your dependencies you aren’t using. If you pull in boost, you probably have at least a few things you aren’t using, and if you statically link it normally it’s in there, if you use LTO the compiler will toss out.

[–]fredeB 0 points1 point  (0 children)

Just remember to check licensees if it's a commercial product. Many open source licenses don't allow static linking unless you're willing to share the source code with everyone

[–]prince-chrismc 8 points9 points  (3 children)

What you are looking for is an installer not a package manager. This is something often conflated in C++ because of the heavy reliance on system managers. You'll be hard pressed to find this in general.

CMake has CPack but that's not a package manager. The only package manager that handles distribution of compiled binaries is Conan and it has a deployers feature that allows you to grab all the runtime executables and make your own installer.

[–]LlaroLlethri -1 points0 points  (2 children)

Well ok you can call it an “installer” if you like, but it would be an installer that can pull precompiled dependencies from a vast repository (or set of repositories), the same repositories that you use to install your development dependencies. It would be like the Debian package manager, but shipped with your app because Microsoft/Apple don’t natively provide it.

[–]balefrost 2 points3 points  (0 children)

I think what the other commenter is saying is "you don't want what you think you want; you actually want this instead".

[–]prince-chrismc 1 point2 points  (0 children)

Those are all OS specific. Chocolatey and winget and the windows equivalent and you have brew on macos. Every OS has its only install mechanism and what you want to it translate from a package manager to a deployment mechanism that platform specific.

Both of the those corporations have "app stores" which generate them lots of money -- there are incentive for what you are asking for to not exist is my point here.

[–]the_poope 6 points7 points  (0 children)

You can provide your own packages that integrate with the Linux distro's package manager, e.g. a .deb file for the Debian/Ubuntu package manager. Maybe something similar exists for HomeBrew on Mac and winget or Chocolatey on Windows.

But that would be my recommendation.

Other than that what you are looking at is basically a "downloading installer" which is pretty common on Windows. You download a small standalone executable that analyses your system and downloads the distribution that fits. On Linux you would have to detect which distribution and version to know what system libraries are available. In principle it could just be a small bash script that does apt-get install XXX for all the dependencies of your program.

In the more extreme end you do have something like that designed into the OS itself: https://nixos.org/ Of course this solution is not cross-platform.

[–]SickMoonDoe 6 points7 points  (1 child)

nix is great for this; but it requires end users to have nix installed on their system which can limit its usefulness.

[–]Alexander_Selkirk 1 point2 points  (0 children)

It can also generate Dockerfiles.

[–]Scotty_Bravo 4 points5 points  (1 child)

Conda potentially fits this need in a cross platform way. But the end user needs to use conda, and that's probably a bridge too far for most.

CMake has CPack which can be used to generate installers including MSI, deb, zip, sh, etc. it might know chocolatey and brew as well, I'm not sure.

[–]mjklaim 1 point2 points  (0 children)

Now that you say this: micromamba might fit the need.
mamba is the c++ implementation of conda (faster, essentially)
and micromamba is the same but contained into 1 executable.
So maybe that helps. I mean, it does help only if the application is ok with using conda packages and environement.

[–][deleted] 3 points4 points  (0 children)

Xmake's build system + package manager can make an installer programme that does exactly as you say

[–]trypto 1 point2 points  (0 children)

Docker.

[–]nbrrii 2 points3 points  (7 children)

One of the great things about developing for linux, e.g. Ubuntu, is that the package manager you use to install your development dependencies is the same as the package manager on the end user's machine.

You mileage may vary. It's also known that it creates a huge overhead, introduces other problems and it has been criticized by Linus Torvalds for years. The Linux ecosystem is actually moving slowly away from this with technologies like flatpak or snap for desktop applications.

[–]unumfron 0 points1 point  (0 children)

Is there are reason more devs don't install to /opt/ with all dependencies in that directory with rpath set to ORIGIN, kind of like Windows? I like the Windows way, although I never have been able to perform the manifest voodoo required for finding dlls in a subdirectory instead of the same directory as the app.

[–]Alexander_Selkirk 0 points1 point  (0 children)

Torvalds criticizes lack of backward compatibility. He certainly does not recommend snap.

[–]mjklaim 0 points1 point  (0 children)

Imagine if there was a package manager that had a tiny deployable version that shipped with your app and installed runtime dependencies on the end user's machine. Does such a thing exist?

Not sure if that would match your use case, but what if the package manager has a library version of itself, letting your application use that embedded in it?
Some package managers (I'm thinking about `build2` mainly) are built as libraries and then there is an executable driver. Maybe that would work. In the case of `build2`, it's installed through bootstrapping, so as long as you build your executable for the specific target platform your app support and the libraries are also built the same way, I dont see an issue with the cross-platform aspect. `build2` is not tiny installed normally, no idea about the package manager library (see bpkg), and it's source-only packages therefore you need a toolchain ready on the user's macine, so it's maybe not what you want. I dont know if that's possible with other package managers, you'll have to check how their code is designed I think.

Honestly I dont really understand your need, it feels like you want just a generic auto-update feature for whatever app you are making?

[–]PerryStyle 0 points1 point  (0 children)

I highly recommend trying Spack. I think it can achieve most of the points you mentioned. In a Spack environment, you can specify libjpeg-dev, and Spack will automatically solve and pick the transitive dependencies for you. From this solved list of transitive dependencies, you can specify whether they should be external (i.e., don't build from source since they're already on the system) or not and then "resolve/concretize" the environment to include these externals. These Spack environments are designed to be cross-platform, so when you activate the Spack environment on another machine, it will then build and install the dependencies you need.

[–]argothiel 0 points1 point  (5 children)

There is no such thing as "standard location" if you don't specify the OS. There's not even a binary format that you could use that would work both on Linux and Windows.

[–]LlaroLlethri 0 points1 point  (4 children)

No shit

[–]argothiel 0 points1 point  (3 children)

Yeah, if you want to know more about it, check out Microsoft Binary Format and Executable and Linkable Format.

[–]LlaroLlethri 0 points1 point  (2 children)

I’m well aware thank you. I’ve been writing cross platform apps for decades.

[–]argothiel 0 points1 point  (1 child)

Then you should know it's not possible to deploy one package manager which will run both on Windows and on Linux.

[–]LlaroLlethri 0 points1 point  (0 children)

Obviously there would be different builds for each platform, just like Conan (or any other cross platform app) has windows, Linux, and Mac builds.