Skip to content
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

Merged
merged 3 commits into from Mar 6, 2021
Merged

Conversation

Jake-Shadle
Copy link
Contributor

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

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```ini
```toml

Copy link
Contributor Author

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.

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.

@repi
Copy link

repi commented Feb 21, 2021

Possible to get this merged in and publish a new release? Thanks!

@repi
Copy link

repi commented Mar 4, 2021

@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

Copy link
Contributor

@thomcc thomcc left a 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.

Comment on lines +6 to +26
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)),
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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:

  1. Faster builds and links, only one object file produced, all headers can only be parsed once.
  2. 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)
  3. More robust against changes to the mimalloc C source, as we just have to worry about one .c file.
  4. 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") {
Copy link
Contributor

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)

See https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts

(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");
Copy link
Contributor

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() {
Copy link
Contributor

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") {
Copy link
Contributor

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.

Copy link
Contributor

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");
Copy link
Contributor

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.

Copy link
Contributor

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" {
Copy link
Contributor

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

@thomcc
Copy link
Contributor

thomcc commented Mar 4, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove CMake dependency
5 participants