Feedback of someone who is used to manage large (>1500) software stack in C / C++ / Fortran / Python / Rust / etc:

- (1) Provide a way to compile without internet access and specify the associated dependencies path manually. This is absolutely critical.

Most 'serious' multi-language package managers and integration systems are building in a sandbox without internet access for security reasons and reproducibility reasons.

If your build system does not allow to build offline and with manually specified dependencies, you will make life of integrators and package managers miserable and they will avoid your project.

(2) Never ever build in '-03 -march=native' by default. This is always a red flag and a sign of immaturity. People expect code to be portable and shippable.

Good default options should be CMake equivalent of "RelWithDebInfo" (meaning: -O2 -g -DNDEBUG ).

-O3 can be argued. -march=native is always always a mistake.

- (3) Allow your build tool to be built by an other build tool (e.g CMake).

Anybody caring about reproducibility will want to start from sources, not from a pre-compiled binary. This also matter for cross compilation.

- (4) Please offer a compatibility with pkg-config (https://en.wikipedia.org/wiki/Pkg-config) and if possible CPS (https://cps-org.github.io/cps/overview.html) for both consumption and generation.

They are what will allow interoperability between your system and other build systems.

- (5) last but not least: Consider seriously the cross-compilation use case.

It is common in the world of embedded systems to cross compile. Any build system that does not support cross-compilation will be de facto banned from the embedded domain.

> Never ever build in '-03 -march=native' by default. This is always a red flag and a sign of immaturity.

Perhaps you can see how there are some assumptions baked into that statement.

What assumptions would that be?

Shipping anything built with -march=native is a horrible idea. Even on homogeneous targets like one of the clouds, you never know if they'll e.g. switch CPU vendors.

The correct thing to do is use microarch levels (e.g. x86-64-v2) or build fully generic if the target architecture doesn't have MA levels.

I build on the exact hardware I intend to deploy my software to and ship it to another machine with the same specs as the one it was built on.

I am willing to hear arguments for other approaches.

The only time I used -march=native was for a university assignment which was built and evaluated on the same server, and it allowed juicing an extra bit of performance. Using it basically means locking the program to the current CPU only.

However I'm not sure about -O3. I know it can make the binary larger, not sure about other downsides.

-O3 also makes build times longer (sometimes significantly), and occasionally the resulting program is actually slightly slower than -O2.

IME -O3 should only be used if you have benchmarks that show -O3 actually produces a speedup for your specific codebase.

Not assumptions, experience.

I fully concur with that whole post as someone who also maintained a C++ codebase used in production.

[deleted]

> -march=native is always always a mistake

Gentoo user: hold my beer.

Gentoo binaries aren't shipped that way

It's also an option on NixOS but I haven't managed to get it working unlike Gentoo.

>15000

15000 what?

1500 C/C++ individual software components.

The 15000 was a typo on my side. Fixed.

I see, thanks. I didn't mind the number it just wasn't clear what was it about.