-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace cmake with cc #58
Conversation
randomized allocation, encrypted free lists, etc. The performance penalty is usually | ||
around 10% according to [mimalloc](https://github.com/microsoft/mimalloc) | ||
own benchmarks. | ||
|
||
To disable secure mode, put in `Cargo.toml`: | ||
```rust | ||
|
||
```ini |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
```ini | |
```toml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was actually intentional, some markdown renderers don't actually handle the toml
code fence, whereas ini
is usually recognized and tends to be highlighted correctly, at least for simpler code blocks such as this, but I can of course change it to be toml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, TIL. I have no stake in this either way. It just struck me as odd.
Possible to get this merged in and publish a new release? Thanks! |
@octavonce any thoughts on getting this in? think it would be beneficial to most and we would be really happy getting rid of our fork |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I was working on this at one point and got too busy to continue (and forgot), so I'm thrilled to see it picked up. The version I had was more complex since it kept the cmake
support under a flag, but I think this is better.
That said, there are a few nits I have.
The most important one is probably mimicing MI_BUILD_OBJECT rather than MI_BUILD_STATIC, since it has many upsides and basically no downsides compared to what we're doing here.
build.include("c_src/mimalloc/include"); | ||
build.files( | ||
[ | ||
"alloc-aligned", | ||
"alloc-posix", | ||
"alloc", | ||
"arena", | ||
"bitmap", | ||
"heap", | ||
"init", | ||
"options", | ||
"os", | ||
"page", | ||
"random", | ||
"region", | ||
"segment", | ||
"stats", | ||
] | ||
.iter() | ||
.map(|fname| format!("c_src/mimalloc/src/{}.c", fname)), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
build.include("c_src/mimalloc/include"); | |
build.files( | |
[ | |
"alloc-aligned", | |
"alloc-posix", | |
"alloc", | |
"arena", | |
"bitmap", | |
"heap", | |
"init", | |
"options", | |
"os", | |
"page", | |
"random", | |
"region", | |
"segment", | |
"stats", | |
] | |
.iter() | |
.map(|fname| format!("c_src/mimalloc/src/{}.c", fname)), | |
); | |
build.include("c_src/mimalloc/include"); | |
build.include("c_src/mimalloc/src"); | |
build.file("c_src/mimalloc/src/static.c"); |
We should just compile https://github.com/microsoft/mimalloc/blob/master/src/static.c as a single compilation unit build. This mimics the MI_BUILD_OBJECT
setting, not the MI_BUILD_STATIC
setting, but the cc
crate will produce a static lib from it anyway.
This has several benefits:
- Faster builds and links, only one object file produced, all headers can only be parsed once.
- Faster at runtime, compiler can see the whole source and inline across .o files (note that C code (unless you set up cross-lang LTO which is very nontrivial) doesn't benefit from rust's LTO, so this is very nice)
- More robust against changes to the mimalloc C source, as we just have to worry about one
.c
file. - When static overriding is used, this will be more robust on some unix platforms, which is the reason
MI_BUILD_OBJECT
exists. While we're still using a.a
file, and not a.o
file, the way Rust code is linked means we still benefit here.
|
||
build.define("MI_STATIC_LIB", None); | ||
|
||
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("target_os not defined!"); | ||
|
||
if cfg!(feature = "override") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: prefer std::env::var("CARGO_FEATURE_FOO").is_ok()
to cfg!(feature = "foo")
in build scripts, since using the latter requires the build script to be recompiled and not just rerun when features change. (not a huge deal, but no reason not to do this)
(Thanks for doing this for CARGO_CFG_TARGET_*
too! It's more important for those admittedly)
&& target_os != "haiku" | ||
{ | ||
if dynamic_tls { | ||
build.flag_if_supported("-ftls-model=local-dynamic"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, this is dubious since it goes against the settings rustc uses, but I'll file another issue about it.
(OptLevel::Size, _) => CMakeBuildType::MinSizeRel, | ||
}) | ||
} | ||
|
||
fn main() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add
println!("cargo:rerun-if-changed=c_src/mimalloc");
here, so that when changing the code in the -sys crate it doesnt rebuild each time (by default it's any change in the folder containing the build.rs).
|
||
build.define("MI_STATIC_LIB", None); | ||
|
||
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("target_os not defined!"); | ||
|
||
if cfg!(feature = "override") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we should consider disabling the override on at least macOS (probably other platforms too...) until #41 is resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Actually, probably best to address that separately)
out_dir.push_str(win_folder); | ||
} | ||
// Remove heavy debug assertions etc | ||
build.define("MI_DEBUG", "0"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should eventually have an option to turn this on. That said, we should set build.define("NDEBUG", None)
here too if we're doing this. Note that cmake
will do this automatically, but cc
does not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, while mimalloc does use NDEBUG, it's not for assertions and just for a couple extra things. I'll file an issue with mimalloc, what we have here is fine actually.
cfg = cfg.define("MI_OVERRIDE", "OFF"); | ||
// Overriding malloc is only available on windows in shared mode, but we | ||
// only ever build a static lib. | ||
if target_os != "windows" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should check the target family, not target_os
Here's a (tested at least on my machines) patch containing all my suggestions that are actually worth doing in this PR: https://gist.github.com/thomcc/3a499f95c68ad8c8698f61235b1a0fa5 |
This PR replaces the usage of cmake with just straight usage of cc. It replicates some of the logic in the cmakelists but is simplified since this crate only builds a static lib.
Resolves: #51