7 ms·
I mean, Visual Studio does this (compiles against its own version of the C/C++ standard library) to avoid the classic nonsense that every Linux user sees when t
by anaisbetts 5y ago
I mean, Visual Studio does this (compiles against its own version of the C/C++ standard library) to avoid the classic nonsense that every Linux user sees when they build a binary and bring it to an older OS then it demands a newer version of glibc and segfaults - this is why every commercial Linux app has to compile on the oldest Linux they can possibly find, and it's frustrating.
You can either:
* Statically link, so you don't need these DLLs at all
* Just copy the DLLs along with your app in the same folder
* Ask users to install the VC Redist package
Option #2 is typically the best one and is pretty easy to do. macOS typically does #2 implicitly (i.e. libswift.framework et al), but ships all of those binaries in a "bundle" that is hidden from users.
- tonyedgecombe 5y ago>Just copy the DLLs along with your app in the same folder I think the license precludes distributing the DLL's with your application. You are supposed to use the VC Redist package.
- plorkyeran 5y agoThe redist installer is recommended but not required.
- anaisbetts 5y agoI'm not sure it's even recommended any more. It's technically better because it means that Microsoft can apply security patches out-of-band, but on the other hand, it means that Microsoft can change The Code Your App Executes without you testing it, and tbh if you're writing a production app you should probably make sure your libraries are up-to-date anyways
- rezonant 5y agoNo you can redistribute them, that's why they are called redistributable. See here: https://docs.microsoft.com/en-us/cpp/windows/determining-which-dlls-to-redistribute?view=msvc-170 https://docs.microsoft.com/en-us/cpp/windows/determining-whi...
- Terry_Roll 5y ago> Option #2 is typically the best one and is pretty easy to do Your app's manifest is more important than you realise and I wonder if the OP is aware of this? Its SxS not SxSW. :-) http://tinyurl.com/y3q8h3ks http://tinyurl.com/y3q8h3ks This might be useful as well https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-... IIRC Windows has been UTF-16 for ages which this link suggests has been since 2000. https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows I always treat UTF-8 as internet territory like web pages because its reportedly easier to recover from corruption which occurs more often online than with the components inside a computer.
- temac 5y ago> compiles against its own version of the C/C++ standard library The C++ library yes. However IIRC Windows now ships a conforming somehow-modern C standard library (ucrt) and modern MSVCs link to it. It is probably also included in current redistributables for the still supported (by MSVC) old versions of Windows that did not have it. Also, the forever binary incompatible C++ standard lib had its limit regardless of the platform (more because of 3rd party binary libs) and MS has switched to a backward binary compatible C++ redistributable for a few years now (they may rebreak in the future). So on some points (but not all, and it is likely to never be all) the situation is converging. > to avoid the classic nonsense that every Linux user sees when they build a binary and bring it to an older OS The thing with building a binary-only program for "Linux" is that "Linux" is not a single OS, and you don't really have cross-distro binary compat except by luck, and for the different versions of a same distro they concentrate on rebuilding everything from source, plus you have a unified namespace of symbols in ELFs so you would not be able to load 2 different C++ libs anyway. This brings drawbacks, but also advantages (for ex you can use C++ libraries of the platform, with an unconstrained C++ API) So the end result is kind of what you say, except if you want things to work really well you should probably even do: * a specific native package for each distro (maybe × version) * try to dynamically link to the fewest possible libs of the platform, ideally only glibc (and yes, an old enough one), maybe also libstdc++ if you want to support plugins, and maybe others if they come with a compatibility policy (so on a case by case basis) * or target something else than a native distro (ex: flatpak, appimage), although it is sometimes kind of equivalent to yet other distros -- anyway at this point it starts to resemble to how you would distribute a binary for Windows -- so with those possibilities existing it is just that under a GNU/Linux distro you also have the classic/more-integrated ones. Anyway, Chrome manages to do binary packages for various version of Debian, and probably other distros; likewise for VS Code and Virtual Box. And building for multiple targets is arguably less a pain today than 10 years ago.
- wahern 5y ago> macOS typically does #2 implicitly On macOS libSystem.dylib provides the C runtime (i.e. libc). It cannot be statically linked, and AFAIU you cannot ship it with your own project.[1] To support older environments you declare an ABI/API target using MACOSX_DEPLOYMENT_TARGET, -miphoneos-version-min, or similar toolchain option. It's normative for projects targeting an Apple platform to explicitly declare a target several releases in the past, but without an explicit declaration the default is to build a binary targeting the version of the SDK you're using, which would normally be the most recently released. Bundling your own dynamic libraries is trivial on Linux by simply defining the run-time search path (aka rpath) when building your application. In general, the systems's dynamic linker is entirely agnostic. And this is even easier on Linux than most other platforms as you can use the $ORIGIN macro to define paths relative to the main binary rather than using fixed absolute paths. $ORIGIN was supported several years before the similar capability on macOS, @loader_path and @executable_path. Bundling dynamic libraries is extremely simple on Linux, it's just not common. Linking to an older glibc ABI is also possible--glibc rigorously utilizes ELF symbol versioning--but admittedly very difficult. None of the build toolchains provide built-in facilities (i.e. not even anything similar to the musl-gcc wrapper for cross-compiling against musl on glibc-based systems), and for the most part glibc only versions its run-time binary symbols, not its compile-time header API. That means you basically need to download old glibc headers or, as most people tend to do, build on old distributions. OTOH, on Linux you can at least statically link your own libc on account of the kernel's [relatively] stable ABI. In practice neither Linux, macOS, nor Windows provide an ideal situation. But at least in principle Linux supports all the common permutations anyone may want, excepting the absence of any singularly blessed system libc. (But to reiterate both musl libc and especially glibc provide strong backwards ABI compatibility, notwithstanding the absence of compile-time knobs for selecting older ABIs.) [1] Perhaps you can hack things to load a bundled libSystem copy. I have a vague memory of someone pointing that out on HN before. But in any event that's definitely not a supported feature.
- anaisbetts 5y ago"In principle it should work, but in reality it doesn't", boy isn't that the Linux story in a nutshell :)
- ur-whale 5y ago> * Just copy the DLLs along with your app in the same folder Gosh I wish things worked like this by default on Linux (dynamic linker search path by default starts with the directory where the binary is located)
- stagger87 5y agoFor people who don't know, it's common to launch your Linux app through a proxy to do just this. Super easy to do.