cmake-rs
cmake-rs copied to clipboard
opt-level = 0 + debug=false does not produce no-debuginfo bins
cmake-rs tries to translate cargo settings to cmake settings, but there are two cases where the debuginfio settings are ignored. The first is opt-level=0 + debug=false. This picks the CMake Debug profile, which always has debuginfo on.
The second is opt-level=s + debug=true. This picks MinSizeRel, which always has debuginfo off.
Solving this in the general case looks hard. I have begun trying to do it by running the cmake configure step once with the -LA flags, to list the configured values of CMAKE_C_FLAGS_DEBUG (etc); modify those flags, then run the actual configuration.
I think it's a viable solution, but I haven't quite gotten there: https://github.com/brson/cmake-rs/tree/dev-nodebug
This is a problem in TiKV where we are turning off debuginfo to improve compile times, but RocksDB makes up a huge chunk of that debuginfo. cc https://github.com/tikv/tikv/issues/4711
We could probably solve this one-off in librocksdb_sys, but it would seem better to solve it for everybody.
I'm not personally intimately familiar enough with cmake to know how to fix this myself, but your patch seems reasonable to me! I sort of wish we could just tell it what flags we want in the axes that we have, but having a workaround in the meantime should be fine. Want to send a PR for those changes?
Yeah, I'll send a patch when I get it working.
It may be reasonable to just translate rust's options directly to CMAKE_C_FLAGS_DEBUG, but I also don't know enough about CMake to know whether that is ok.
I don't have an answer, but I just wanted to put this thought out there.
Currently, cmake-rs does this:
- if
opt-level ≡ 0thenCMAKE_BUILD_TYPE=Debug, - if
opt-level ∈ {1, 2, 3}then:- if
debug ≡ falsethenCMAKE_BUILD_TYPE=Release - if
debug ≡ truethenCMAKE_BUILD_TYPE=RelWithDebInfo
- if
- if
opt-level ∈ {s, z}thenCMAKE_BUILD_TYPE=MinSizeRel
Here's one alternative that gives debug a higher precedence:
- if
debug ≡ truethen:- if
opt-level ∈ {0, s, z}thenCMAKE_BUILD_TYPE=Debug - if
opt-level ∈ {1, 2, 3}thenCMAKE_BUILD_TYPE=RelWithDebInfo
- if
- if
debug ≡ falsethen:- if
opt-level ∈ {0, 1, 2, 3}thenCMAKE_BUILD_TYPE=Release - if
opt-level ∈ {s, z}thenCMAKE_BUILD_TYPE=MinSizeRel
- if
Perhaps you could move the {s, z} around a bit, but I guess one shouldn't expect to get a minimized build with debug info compiled in, so as long as debug ≡ true, you won't get CMAKE_BUILD_TYPE=MinSizeRel.
I think that the algorithm I suggested in https://github.com/alexcrichton/cmake-rs/issues/79#issuecomment-494676960 is a reasonable and simple change that would handle the corner cases mentioned by @brson, but I'm not sure if it's the best way to go in the long term.
If it's given that the goal of a -sys crate is to build a non-Rust library under the control of a Rust library, I think it makes sense to have Rust, via cmake-rs, decide certain aspects of building. The CMAKE_<LANG>_FLAGS and CMAKE_<LANG>_FLAGS_<CONFIG> seem to be good candidates for those aspects. Unfortunately, CMake does not appear to make it easy/desirable to do this, and the general advice I've read is to not override these but use CMAKE_<LANG>_FLAGS_INIT and CMAKE_<LANG>_FLAGS_<CONFIG>_INIT instead. Plus, you might run into conflicts with particularly picky CMakeLists.txt.
With that in mind, perhaps it would be useful to have cmake::Config functions that allow one to choose how to override certain variables, giving different mechanisms as arguments. The options could include:
- Don't override. That is, let CMake or the
CMakeLists.txtdecide. - Override by letting
cmake-rschoose a value that best fits thecargosettings.
Having more options seems reasonable to me! I'm not really sure which is the best way but having a few to try seems reasonable.
Thanks for the suggestions @spl
From the linked tikv thread, it may end up that we use debuginfo=1 for release mode. CMake itself doesn't seem to make any distinction between debuginfo levels, just on or off. And furthermore, by my recollection, cargo itself doesn't provide the debuginfo level to the build script, just on or off.
So for the tikv use case we may not be able to get what we want out of cargo and cmake-rs. (the equivalent of opt-level=3 + debuginfo=1 for cmake projects).
Unfortunately rocksdb is a big chunk of our binary and our debuginfo. If the above scenario happens we may just have to hack up or build script for our fork of rocksdb.