Skip to content

Commit 9585be4

Browse files
committed
Have a "docs-only" feature that should be enabled when building the doc
The build may fail while building the docs because the necessary C++ dependencies might be missing. So just ignore the failling build when building the documentation For example: woboq/qmetaobject-rs#27
1 parent f9c8046 commit 9585be4

File tree

4 files changed

+82
-7
lines changed

4 files changed

+82
-7
lines changed

cpp_build/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ syn = { version = "0.15", features=["full", "visit"] }
1818
proc-macro2 = "0.4"
1919
regex = "1"
2020
unicode-xid = "0.1"
21+
22+
[package.metadata.docs.rs]
23+
features = [ "docs-only" ]

cpp_build/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,11 @@ In order to provide a better error message, the build script will exit successfu
644644
self.cc.flag_if_supported("-std=c++11");
645645
}
646646
// Build the C++ library
647-
self.cc.file(filename).compile(LIB_NAME);
647+
if let Err(e) = self.cc.file(filename).try_compile(LIB_NAME) {
648+
let _ = writeln!(std::io::stderr(), "\n\nerror occurred: {:?}\n\n", e);
649+
#[cfg(not(feature = "docs-only"))]
650+
std::process::exit(1);
651+
}
648652
}
649653
}
650654

cpp_macros/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ quote = "0.6"
2121
proc-macro2 = "0.4"
2222
aho-corasick = "0.6"
2323
byteorder = "1.0"
24+
25+
[package.metadata.docs.rs]
26+
features = [ "docs-only" ]

cpp_macros/src/lib.rs

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,25 @@ impl MetaData {
4848

4949
lazy_static! {
5050
static ref METADATA: HashMap<u64, Vec<MetaData>> = {
51-
let file = open_lib_file().expect(
51+
let file = match open_lib_file() {
52+
Ok(x) => x,
53+
Err(e) => {
54+
#[cfg(not(feature = "docs-only"))]
55+
panic!(
5256
r#"
5357
-- rust-cpp fatal error --
5458
5559
Failed to open the target library file.
56-
NOTE: Did you make sure to add the rust-cpp build script?"#,
57-
);
60+
NOTE: Did you make sure to add the rust-cpp build script?
61+
{}"#,
62+
e);
63+
#[cfg(feature = "docs-only")]
64+
{
65+
eprintln!("Error while opening target library: {}", e);
66+
return Default::default()
67+
};
68+
}
69+
};
5870

5971
read_metadata(file).expect(
6072
r#"
@@ -191,10 +203,19 @@ pub fn expand_internal(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
191203
let size_data = match METADATA.get(&closure.sig.name_hash()) {
192204
Some(x) => x,
193205
None => {
206+
#[cfg(not(feature = "docs-only"))]
194207
return quote!(compile_error!{
195208
r#"This cpp! macro is not found in the library's rust-cpp metadata.
196209
NOTE: Only cpp! macros found directly in the program source will be parsed -
197-
NOTE: They cannot be generated by macro expansion."#}).into()
210+
NOTE: They cannot be generated by macro expansion."#}).into();
211+
#[cfg(feature = "docs-only")]
212+
{
213+
return quote!{
214+
macro_rules! __cpp_closure_impl {
215+
($($x:tt)*) => { panic!("docs-only"); }
216+
}
217+
}.into()
218+
};
198219
}
199220
};
200221

@@ -362,15 +383,60 @@ pub fn expand_wrap_class(input: proc_macro::TokenStream) -> proc_macro::TokenStr
362383
};
363384

364385
let hash = class.name_hash();
386+
let class_name = class.name.clone();
365387

366388
// Get the size data compiled by the build macro
367389
let size_data = match METADATA.get(&hash) {
368390
Some(x) => x,
369391
None => {
392+
#[cfg(not(feature = "docs-only"))]
370393
return quote!(compile_error!{
371394
r#"This cpp_class! macro is not found in the library's rust-cpp metadata.
372395
NOTE: Only cpp_class! macros found directly in the program source will be parsed -
373-
NOTE: They cannot be generated by macro expansion."#}).into()
396+
NOTE: They cannot be generated by macro expansion."#}).into();
397+
#[cfg(feature = "docs-only")]
398+
{
399+
let mut result = quote!{
400+
#[doc(hidden)]
401+
impl ::cpp::CppTrait for #class_name {
402+
type BaseType = usize;
403+
const ARRAY_SIZE: usize = 1;
404+
const CPP_TYPE: &'static str = stringify!(#class_name);
405+
}
406+
#[doc = "NOTE: this trait will only be enabled if the C++ underlying type is trivially copyable"]
407+
impl ::std::marker::Copy for #class_name { }
408+
#[doc = "NOTE: this trait will only be enabled if the C++ underlying type is copyable"]
409+
impl ::std::clone::Clone for #class_name { fn clone(&self) -> Self { panic!("docs-only") } }
410+
#[doc = "NOTE: this trait will only be enabled if the C++ underlying type is default constructible"]
411+
impl ::std::default::Default for #class_name { fn default() -> Self { panic!("docs-only") } }
412+
};
413+
if class.derives("PartialEq") {
414+
result = quote!{ #result
415+
impl ::std::cmp::PartialEq for #class_name {
416+
fn eq(&self, other: &#class_name) -> bool { panic!("docs-only") }
417+
}
418+
};
419+
}
420+
if class.derives("PartialOrd") {
421+
result = quote!{ #result
422+
impl ::std::cmp::PartialOrd for #class_name {
423+
fn partial_cmp(&self, other: &#class_name) -> ::std::option::Option<::std::cmp::Ordering> {
424+
panic!("docs-only")
425+
}
426+
}
427+
};
428+
}
429+
if class.derives("Ord") {
430+
result = quote!{ #result
431+
impl ::std::cmp::Ord for #class_name {
432+
fn cmp(&self, other: &#class_name) -> ::std::cmp::Ordering {
433+
panic!("docs-only")
434+
}
435+
}
436+
};
437+
}
438+
return result.into()
439+
};
374440
}
375441
};
376442

@@ -387,7 +453,6 @@ NOTE: They cannot be generated by macro expansion."#}).into()
387453
let destructor_name = Ident::new(&format!("__cpp_destructor_{}", hash), Span::call_site());
388454
let copyctr_name = Ident::new(&format!("__cpp_copy_{}", hash), Span::call_site());
389455
let defaultctr_name = Ident::new(&format!("__cpp_default_{}", hash), Span::call_site());
390-
let class_name = class.name.clone();
391456

392457
let mut result = quote! {
393458
#[doc(hidden)]

0 commit comments

Comments
 (0)