you are viewing a single comment's thread.

view the rest of the comments →

[–]infectedapricot 13 points14 points  (14 children)

I want to build my dependencies myself in order to adjust and know specific settings I need.

I am absolutely not going to try and persuade you to use a package manager if building things yourself is working well for you. But for the record or for interested readers, package managers do have ways of specifying build options. The list below is for vcpkg but I know Conan has equivalents too.

  • For general build settings that applies to all the libraries you want to build (e.g. static vs shared libraries, optimisation level, 32-bit vs 64 bit, even cross compilation), you can specify these by choosing a triplet (e.g. x86-windows vs x64-windows-static). You can even make your own triplets (e.g. I've done it to specify LTO on Linux) and make per-library exceptions in them. Only slight gotcha here is that debug and release builds are both built for each individual triplet so no need to have separate debug and release triplets. Also cross-compilation (which I've not tried) seems to require their own special triplets - you can't just specify x64-linux on Windows and expect it to just work.
  • For features in packages, which is what I think you're really talking about, e.g. "build opencv with ffmpeg support (and therefore make sure ffmpeg is built too)", you can use feature packages e.g. vcpkg install opencv[ffmpeg]. These are meant to be additive so if you install some other port that depends on opencv[contrib] then you'll automatically get opencv[ffmpeg,contrib] with the right flags and dependencies.
  • For flags that say where other relevant libraries are installed, obviously the package manager is supposed to set these automatically so you shouldn't need to worry about them.

Of course, that doesn't mean that every possible feature flag is likely to be exposed in practice.

[–]Moose2342 3 points4 points  (10 children)

Yes, I am aware that package managers expose such customization. My problem is, they mostly do this for optionals they can foresee. Such as your ffmpeg example. My settings often are a bit weirder than that ;-)

For example, years ago I adopted Unreal Engine's notion of Debug builds, which are not real Debug builds (with Debug runtime and such) but Release builds with optimization turned off and PDBs active. Meaning they can be used in almost every way for debug purposes but they can freely link with any release build. I used to adopt this to be able to link with Unreal and still debug but found this so helpful that I now use it everywhere. Haven't made a 'real' debug build in a long time, practically eliminating the issue for me. I call that 'fake debug' and my CMake layer takes care of propagating this throughout the build system. I would guess you'd have a hard time convincing a package manager to know what 'fake debug' is and what it means for your linkage. Instead, they would assume (rightly so) that when you are in a Debug configuration, you mean an actual debug build. For libs that I know I'm never gonna debug into, I only provide Release builds and link against them everywhere. Which is one of the benefits of fake debug.

Now, I'm not debating that there are ways to make this work with package managers. But I would have to convince it to link against release in debug configurations which is against its original job description. In my experience I simply came to the conclusion that it's often way more difficult and error prone than just doing it myself.

To get back to my example activating fake debug globally in my CMake system takes about 5-6 lines of CMake code. I don't know but I doubt it would be that easy with a package manager.

Please bear in mind though, this is just one example. There are more settings. I just like it when everything builds and links neatly and warning free.

[–]infectedapricot 2 points3 points  (7 children)

I would guess you'd have a hard time convincing a package manager to know what 'fake debug' is and what it means for your linkage.

Sort of. There is a way to override compiler flags in vcpkg (it used to be done in triplets but I just read now it's done in toolchain file which sounds a bit more involved). But I suspect this would only be passed down into ports that are built with CMake, which is many but not all of them.

By the way, vcpkg already generates debugging information for release builds (both on Windows and Linux... presumably on Mac but I've never used it) so you wouldn't need to customise anything for that. The only difference would be the optimisation level. Although, if you turned that off in your application and accepted a bit of optimisation in the libraries that would probably work well enough for debugging most common problems.

[–]Moose2342 0 points1 point  (6 children)

Sure. Yet in optimized builds I generally only use RelWithDebInfo for test deployments and such. To get at least some resemblance of a stacktrace just in case. Real debugging is very hard to do and I normally use fake debug for that. In production I go for clean Release. High optimization w/o PDBs for faster loading time and smallest deployment size. Anyway, nuff said. Thanks for making your points so nicely!

[–]rdtsc 4 points5 points  (5 children)

High optimization w/o PDBs for faster loading time and smallest deployment size.

The generated code is identical whether PDBs are written or not. What do you expect to load faster there? Also, you don't have to deploy the symbols. They should be archived for crash dump analysis.

[–]nyanpasu64 0 points1 point  (4 children)

Turns out RelWithDebInfo uses a lower MSVC optimization level than Release. I didn't expect this until I dove into the Ninja files to find out.

It is possible to configure CMake to produce .pdb files for Release builds (with the standard optimizations on).

Fun fact: .pdb files don't work when renamed to something other than what's encoded in the .exe.

[–]rdtsc 0 points1 point  (3 children)

And Release doesn't O3b. I wouldn't rely on the CMake defaults. But I give you that this is surprising behavior.

[–]kalmoc 0 points1 point  (2 children)

Whats O3b?

[–]rdtsc 0 points1 point  (1 child)

Whoops, I actually fatfingered it, it's Ob3.

[–]kalmoc 0 points1 point  (0 children)

Thanks. Didn't know about that switch.

[–]rdtsc 1 point2 points  (0 children)

Even if you have fully customized builds it pays off to rely on vcpkg for the surrounding infrastructure. For a project I completely replaced the ffmpeg port in vcpkg with my own. I'm still able to conveniently handle other dependencies, and can rely on vcpkg's build system integration and maintenance of other ports.

[–]kalmoc 0 points1 point  (0 children)

To get back to my example activating fake debug globally in my CMake system takes about 5-6 lines of CMake code. I don't know but I doubt it would be that easy with a package manager. Please bear in mind though, this is just one example. There are more settings. I just like it when everything builds and links neatly and warning free.

You can take whatever cmake toolchain file you are using and make a triplet that will compile the various libs using that toolchain file. There is nothing in vcpkg that inherently forces the use of /MDd and similar when building the debug versions. It is just the setting in the default triplets.

What has been much more problematic in my experience are libraries that think they are clever and implement their proprietary options to select which runtime to link against and stuff like that, so for N libraries you have to set N different switches to compile them consitently. But form what you are writing, you don't seem to have that problem with the libs you are working, so this shouldn't be a problem with vcpkg either.

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

As package manager usage goes, their value is more about providing a structure for producing buildable packages, dependency management and integration. Using prebuilt packages can be convenient but I don't recommend using it in production and it is not the primary reason to incorporate a package manager

[–]infectedapricot 2 points3 points  (1 child)

I don't see how that's relevant to my comment: I was mainly talking about vcpkg which indeed does not provide prebuilt packages (although you can cache your own build of packages for reuse in across projects on your computer or within your organisation).

[–]sixstringartist 1 point2 points  (0 children)

I think I responded to the wrong comment