-
Notifications
You must be signed in to change notification settings - Fork 51
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
Optionally vendor GNUStep's libobjc2
#44
Closed
Closed
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
2023d48
Add initial gnustep_libobjc2_src crate for vendoring GNUStep's libobjc2
madsmtm 21ce6c1
Use clang (> 8 recommended) per default for building libobjc2
madsmtm f0c72ff
Set GNUSTEP_INSTALL_TYPE=NONE to prevent systemwide installation
madsmtm ac5ff55
Add better return type for libobjc2_src `build` function
madsmtm f4fa04b
Use gnustep_libobjc2_src in objc2_sys when the vendor_gnustep feature…
madsmtm a4352ad
Add option to link statically against GNUStep's libobjc2
madsmtm 38da1f3
Print rerun-if-changed in objc2_sys
madsmtm 9cbece0
Add initial gnustep_base_src
madsmtm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[submodule "libobjc2"] | ||
path = gnustep_libobjc2_src/libobjc2 | ||
url = https://github.com/gnustep/libobjc2.git | ||
branch = 2.1 | ||
[submodule "gnustep-base"] | ||
path = gnustep_base_src/libs-base | ||
url = https://github.com/gnustep/libs-base.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
[workspace] | ||
members = [ | ||
"gnustep_libobjc2_src", | ||
"gnustep_base_src", | ||
"objc2", | ||
"objc2_block", | ||
"objc2_encode", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[package] | ||
name = "gnustep_base_src" | ||
version = "0.0.1" | ||
authors = ["Mads Marquart <[email protected]>"] | ||
edition = "2018" | ||
|
||
description = "Source of The GNUstep Base Library and logic to build it" | ||
keywords = ["gnustep", "objc", "gnustep-base", "build-dependencies"] | ||
categories = [ | ||
"development-tools::build-utils", | ||
] | ||
readme = "README.md" | ||
repository = "https://github.com/madsmtm/gnustep_base_src" | ||
documentation = "https://docs.rs/gnustep_base_src/" | ||
license = "MIT/Apache-2.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use std::env; | ||
use std::path::{Path, PathBuf}; | ||
use std::process::Command; | ||
|
||
const NO_SOURCES_MSG: &'static str = r#" | ||
GNUStep Base sources not present, please run: | ||
|
||
$ git submodule update --init --recursive | ||
|
||
If you did not checkout via git, you will | ||
need to fetch the submodule's contents from | ||
https://github.com/gnustep/libs-base | ||
"#; | ||
|
||
pub struct Builder {} | ||
|
||
impl Builder { | ||
pub fn new() -> Self { | ||
Self {} | ||
} | ||
|
||
pub fn build(&mut self) -> Artifacts { | ||
// GNUStep only compiles with clang, so try that first. | ||
// (But let the user specify a different path if they need to). | ||
if env::var_os("CC").is_none() { | ||
env::set_var("CC", "clang"); | ||
} | ||
if env::var_os("CXX").is_none() { | ||
env::set_var("CXX", "clang++"); | ||
} | ||
|
||
let source_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("libs-base"); | ||
if !source_dir.join("Headers/Foundation/Foundation.h").exists() { | ||
panic!("{}", NO_SOURCES_MSG); | ||
} | ||
|
||
let mut configure = Command::new(source_dir.join("configure")); | ||
// .arg("--with-config-file=") | ||
// .arg("--enable-libffi") | ||
// .arg("--with-default-config=") | ||
// .arg("--prefix") // Or GNUSTEP_SYSTEM_ROOT ? | ||
|
||
// run `make` and `make install` | ||
|
||
let dst: PathBuf = todo!(); | ||
|
||
Artifacts { | ||
source_dir, | ||
include_dir: dst.join("include"), | ||
lib_dir: dst.join("lib"), | ||
lib_name: "gnustep-base", | ||
} | ||
} | ||
} | ||
|
||
pub struct Artifacts { | ||
source_dir: PathBuf, | ||
include_dir: PathBuf, | ||
lib_dir: PathBuf, | ||
lib_name: &'static str, | ||
} | ||
|
||
impl Artifacts { | ||
pub fn include_dir(&self) -> &Path { | ||
&self.include_dir | ||
} | ||
|
||
pub fn lib_dir(&self) -> &Path { | ||
&self.lib_dir | ||
} | ||
|
||
pub fn lib_name(&self) -> &str { | ||
&self.lib_name | ||
} | ||
|
||
pub fn print_cargo_metadata(&self) { | ||
println!("cargo:rustc-link-search=native={}", self.lib_dir.display()); | ||
println!("cargo:rustc-link-lib=dylib={}", self.lib_name); | ||
println!("cargo:include={}", self.include_dir.display()); | ||
println!("cargo:lib={}", self.lib_dir.display()); | ||
} | ||
|
||
pub fn print_cargo_rerun_if_changed(&self) { | ||
println!("cargo:rerun-if-env-changed=CC"); | ||
println!("cargo:rerun-if-env-changed=CXX"); | ||
rerun_if(&self.source_dir); | ||
} | ||
} | ||
|
||
// https://github.com/rust-lang/git2-rs/blob/0.13.23/libgit2-sys/build.rs#L228-L236 | ||
fn rerun_if(path: &Path) { | ||
if path.is_dir() { | ||
for entry in std::fs::read_dir(path).expect("read_dir") { | ||
rerun_if(&entry.expect("entry").path()); | ||
} | ||
} else { | ||
println!("cargo:rerun-if-changed={}", path.display()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
name = "gnustep_libobjc2_src" | ||
version = "0.0.1" | ||
authors = ["Mads Marquart <[email protected]>"] | ||
edition = "2018" | ||
|
||
description = "Source of GNUStep's libobjc2 and logic to build it" | ||
keywords = ["gnustep", "objc", "libobjc2", "build-dependencies"] | ||
categories = [ | ||
"development-tools::build-utils", | ||
] | ||
readme = "README.md" | ||
repository = "https://github.com/madsmtm/gnustep_libobjc2_src" | ||
documentation = "https://docs.rs/gnustep_libobjc2_src/" | ||
license = "MIT/Apache-2.0" | ||
|
||
exclude = [ | ||
"libobjc2/ABIDoc/*", | ||
"libobjc2/Test/*", | ||
"libobjc2/third_party/robin-map/tests/*", | ||
] | ||
|
||
[dependencies] | ||
cmake = "0.1.45" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# `gnustep_libobjc2_src` | ||
|
||
Source of GNUStep's libobjc2 and logic to build it for Rust. | ||
|
||
You probably want to use `objc2_sys`, but this is kept separate from that so | ||
that users don't download the entire GNUStep source when they don't need to. | ||
|
||
Using `clang` with at least version `8.0.0` is recommended. You can specify | ||
your desired compiler using the `CC` and `CXX` environment variables. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
//! TODO | ||
//! | ||
//! See | ||
//! - https://github.com/gnustep/libs-base/blob/base-1_28_0/INSTALL | ||
//! - https://github.com/blas-lapack-rs/blis-src/blob/main/blis-src/build.rs | ||
//! - https://github.com/alexcrichton/openssl-src-rs/blob/master/src/lib.rs | ||
//! - https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/autoconf.html#Running-configure-Scripts | ||
//! | ||
//! And gnustep-make would also have to be installed: | ||
//! - https://github.com/gnustep/tools-make/blob/master/Documentation/gnustep-make.texi | ||
//! - http://www.gnustep.org/resources/documentation/Developer/Make/Manual/DESIGN | ||
|
||
use std::env; | ||
use std::path::{Path, PathBuf}; | ||
|
||
const NO_SOURCES_MSG: &'static str = r#" | ||
libobjc2 sources not present, please run: | ||
|
||
$ git submodule update --init --recursive | ||
|
||
If you did not checkout via git, you will | ||
need to fetch the submodule's contents from | ||
https://github.com/gnustep/libobjc2 | ||
"#; | ||
|
||
pub struct Builder { | ||
lib_kind: LibKind, | ||
objcxx: bool, | ||
} | ||
|
||
impl Builder { | ||
pub fn new() -> Self { | ||
Self { | ||
lib_kind: LibKind::Dynamic, | ||
objcxx: true, | ||
} | ||
} | ||
|
||
/// Set the type of library to be built, and how linking is performed. | ||
/// | ||
/// Possible options are [`LibKind::Static`] and [`LibKind::Dynamic`]. | ||
/// | ||
/// Defaults to [`LibKind::Dynamic`]. | ||
pub fn lib_kind(&mut self, kind: LibKind) -> &mut Self { | ||
self.lib_kind = kind; | ||
self | ||
} | ||
|
||
/// Enable support for Objective-C++. | ||
/// | ||
/// Namely interoperability between Objective-C and C++ exceptions. | ||
/// | ||
/// Defaults to [`true`]. | ||
pub fn objcxx(&mut self, objcxx: bool) -> &mut Self { | ||
self.objcxx = objcxx; | ||
self | ||
} | ||
|
||
pub fn build(&mut self) -> Artifacts { | ||
// GNUStep only compiles with clang, so try that first. | ||
// (But let the user specify a different path if they need to). | ||
if env::var_os("CC").is_none() { | ||
env::set_var("CC", "clang"); | ||
} | ||
if env::var_os("CXX").is_none() { | ||
env::set_var("CXX", "clang++"); | ||
} | ||
|
||
let source_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("libobjc2"); | ||
if !source_dir.join("objc/objc.h").exists() { | ||
panic!("{}", NO_SOURCES_MSG); | ||
} | ||
|
||
let dst = cmake::Config::new(&source_dir) | ||
// Default to ignoring `gnustep-config` presence, since they | ||
// usually want to install the libraries globally (which requires | ||
// root). Users that want systemwide installation should just | ||
// install it themselves, and shouldn't need to vendor GNUStep. | ||
.define("GNUSTEP_INSTALL_TYPE", "NONE") | ||
// Don't bother building tests, we're not gonna run them anyways | ||
// (and they're not available when packaged, see Cargo.toml). | ||
.define("TESTS", "OFF") | ||
// Having this on also builds the dynamic library, but not really | ||
// anything we can do to change that. | ||
.define( | ||
"BUILD_STATIC_LIBOBJC", | ||
match self.lib_kind { | ||
LibKind::Static => "ON", | ||
LibKind::Dynamic => "OFF", | ||
}, | ||
) | ||
.define("ENABLE_OBJCXX", if self.objcxx { "ON" } else { "OFF" }) | ||
// Various other defaults | ||
// .define("OLDABI_COMPAT", "ON") | ||
// .define("DEBUG_ARC_COMPAT", "OFF") | ||
// .define("ENABLE_TRACING", "OFF") | ||
// .define("LEGACY_COMPAT", "OFF") | ||
// .define("LIBOBJC_NAME", "objc") | ||
// .define("TYPE_DEPENDENT_DISPATCH", "ON") | ||
// .define("STRICT_APPLE_COMPATIBILITY", "0") // Default none | ||
// TODO: .static_crt(?) | ||
.build_target("install") | ||
.build(); | ||
|
||
Artifacts { | ||
source_dir, | ||
include_dir: dst.join("include"), | ||
lib_dir: dst.join("lib"), | ||
lib_kind: self.lib_kind, | ||
lib_name: "objc", | ||
} | ||
} | ||
} | ||
|
||
pub struct Artifacts { | ||
source_dir: PathBuf, | ||
include_dir: PathBuf, | ||
lib_dir: PathBuf, | ||
lib_kind: LibKind, | ||
lib_name: &'static str, | ||
} | ||
|
||
impl Artifacts { | ||
pub fn source_dir(&self) -> &Path { | ||
&self.source_dir | ||
} | ||
|
||
pub fn include_dir(&self) -> &Path { | ||
&self.include_dir | ||
} | ||
|
||
pub fn lib_dir(&self) -> &Path { | ||
&self.lib_dir | ||
} | ||
|
||
pub fn lib_kind(&self) -> LibKind { | ||
self.lib_kind | ||
} | ||
|
||
pub fn lib_name(&self) -> &str { | ||
&self.lib_name | ||
} | ||
|
||
pub fn print_cargo_metadata(&self) { | ||
let kind = match self.lib_kind { | ||
LibKind::Dynamic => "dylib", | ||
LibKind::Static => "static", | ||
}; | ||
println!("cargo:rustc-link-search=native={}", self.lib_dir.display()); | ||
println!("cargo:rustc-link-lib={}={}", kind, self.lib_name); | ||
println!("cargo:include={}", self.include_dir.display()); | ||
println!("cargo:lib={}", self.lib_dir.display()); | ||
} | ||
|
||
pub fn print_cargo_rerun_if_changed(&self) { | ||
println!("cargo:rerun-if-env-changed=CC"); | ||
println!("cargo:rerun-if-env-changed=CXX"); | ||
rerun_if(&self.source_dir); | ||
} | ||
} | ||
|
||
fn rerun_if(path: &Path) { | ||
if path.is_dir() { | ||
for entry in std::fs::read_dir(path).expect("read_dir") { | ||
rerun_if(&entry.expect("entry").path()); | ||
} | ||
} else { | ||
println!("cargo:rerun-if-changed={}", path.display()); | ||
} | ||
} | ||
|
||
#[non_exhaustive] | ||
#[derive(Clone, Copy)] | ||
pub enum LibKind { | ||
Dynamic, | ||
Static, | ||
// Framework, | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 is probably also a bad idea, though not sure if there's a better alternative...