blob: 6592011296224e972651291f0350a890b7347672 [file] [log] [blame]
Brian Silverman4e662aa2022-05-11 23:10:19 -07001#![doc = include_str!("../README.md")]
2
3// Copyright 2020 Google LLC
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11// The crazy macro_rules magic in this file is thanks to dtolnay@
12// and is a way of attaching rustdoc to each of the possible directives
13// within the include_cpp outer macro. None of the directives actually
14// do anything - all the magic is handled entirely by
15// autocxx_macro::include_cpp_impl.
16
17mod rvalue_param;
18pub mod subclass;
19mod value_param;
20
21#[cfg_attr(doc, aquamarine::aquamarine)]
22/// Include some C++ headers in your Rust project.
23///
24/// This macro allows you to include one or more C++ headers within
25/// your Rust code, and call their functions fairly naturally.
26///
27/// # Examples
28///
29/// C++ header (`input.h`):
30/// ```cpp
31/// #include <cstdint>
32///
33/// uint32_t do_math(uint32_t a);
34/// ```
35///
36/// Rust code:
37/// ```
38/// # use autocxx_macro::include_cpp_impl as include_cpp;
39/// include_cpp!(
40/// # parse_only!()
41/// #include "input.h"
42/// generate!("do_math")
43/// safety!(unsafe)
44/// );
45///
46/// # mod ffi { pub fn do_math(a: u32) -> u32 { a+3 } }
47/// # fn main() {
48/// ffi::do_math(3);
49/// # }
50/// ```
51///
52/// The resulting bindings will use idiomatic Rust wrappers for types from the [cxx]
53/// crate, for example [`cxx::UniquePtr`] or [`cxx::CxxString`]. Due to the care and thought
54/// that's gone into the [cxx] crate, such bindings are pleasant and idiomatic to use
55/// from Rust, and usually don't require the `unsafe` keyword.
56///
57/// For full documentation, see [the manual](https://google.github.io/autocxx/).
58///
59/// # The [`include_cpp`] macro
60///
61/// Within the braces of the `include_cpp!{...}` macro, you should provide
62/// a list of at least the following:
63///
64/// * `#include "cpp_header.h"`: a header filename to parse and include
65/// * `generate!("type_or_function_name")`: a type or function name whose declaration
66/// should be made available to C++. (See the section on Allowlisting, below).
67/// * Optionally, `safety!(unsafe)` - see discussion of [`safety`].
68///
69/// Other directives are possible as documented in this crate.
70///
71/// Now, try to build your Rust project. `autocxx` may fail to generate bindings
72/// for some of the items you specified with [generate] directives: remove
73/// those directives for now, then see the next section for advice.
74///
75/// # Allowlisting
76///
77/// How do you inform autocxx which bindings to generate? There are three
78/// strategies:
79///
80/// * *Recommended*: provide various [`generate`] directives in the
81/// [`include_cpp`] macro. This can specify functions or types.
82/// * *Not recommended*: in your `build.rs`, call [`Builder::auto_allowlist`].
83/// This will attempt to spot _uses_ of FFI bindings anywhere in your Rust code
84/// and build the allowlist that way. This is experimental and has known limitations.
85/// * *Strongly not recommended*: use [`generate_all`]. This will attempt to
86/// generate Rust bindings for _any_ C++ type or function discovered in the
87/// header files. This is generally a disaster if you're including any
88/// remotely complex header file: we'll try to generate bindings for all sorts
89/// of STL types. This will be slow, and some may well cause problems.
90/// Effectively this is just a debug option to discover such problems. Don't
91/// use it!
92///
93/// # Internals
94///
95/// For documentation on how this all actually _works_, see
96/// `IncludeCppEngine` within the `autocxx_engine` crate.
97#[macro_export]
98macro_rules! include_cpp {
99 (
100 $(#$include:ident $lit:literal)*
101 $($mac:ident!($($arg:tt)*))*
102 ) => {
103 $($crate::$include!{__docs})*
104 $($crate::$mac!{__docs})*
105 $crate::include_cpp_impl! {
106 $(#include $lit)*
107 $($mac!($($arg)*))*
108 }
109 };
110}
111
112/// Include a C++ header. A directive to be included inside
113/// [include_cpp] - see [include_cpp] for details
114#[macro_export]
115macro_rules! include {
116 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
117}
118
119/// Generate Rust bindings for the given C++ type or function.
120/// A directive to be included inside
121/// [include_cpp] - see [include_cpp] for general information.
122/// See also [generate_pod].
123#[macro_export]
124macro_rules! generate {
125 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
126}
127
128/// Generate as "plain old data" and add to allowlist.
129/// Generate Rust bindings for the given C++ type such that
130/// it can be passed and owned by value in Rust. This only works
131/// for C++ types which have trivial move constructors and no
132/// destructor - you'll encounter a compile error otherwise.
133/// If your type doesn't match that description, use [generate]
134/// instead, and own the type using [UniquePtr][cxx::UniquePtr].
135/// A directive to be included inside
136/// [include_cpp] - see [include_cpp] for general information.
137#[macro_export]
138macro_rules! generate_pod {
139 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
140}
141
142/// Generate Rust bindings for all C++ types and functions
143/// in a given namespace.
144/// A directive to be included inside
145/// [include_cpp] - see [include_cpp] for general information.
146/// See also [generate].
147#[macro_export]
148macro_rules! generate_ns {
149 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
150}
151
152/// Generate Rust bindings for all C++ types and functions
153/// found. Highly experimental and not recommended.
154/// A directive to be included inside
155/// [include_cpp] - see [include_cpp] for general information.
156/// See also [generate].
157#[macro_export]
158macro_rules! generate_all {
159 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
160}
161
162/// Generate as "plain old data". For use with [generate_all]
163/// and similarly experimental.
164#[macro_export]
165macro_rules! pod {
166 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
167}
168
169/// Skip the normal generation of a `make_string` function
170/// and other utilities which we might generate normally.
171/// A directive to be included inside
172/// [include_cpp] - see [include_cpp] for general information.
173#[macro_export]
174macro_rules! exclude_utilities {
175 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
176}
177
178/// Entirely block some type from appearing in the generated
179/// code. This can be useful if there is a type which is not
180/// understood by bindgen or autocxx, and incorrect code is
181/// otherwise generated.
182/// This is 'greedy' in the sense that any functions/methods
183/// which take or return such a type will _also_ be blocked.
184///
185/// A directive to be included inside
186/// [include_cpp] - see [include_cpp] for general information.
187#[macro_export]
188macro_rules! block {
189 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
190}
191
192/// Avoid generating implicit constructors for this type.
193/// The rules for when to generate C++ implicit constructors
194/// are complex, and if autocxx gets it wrong, you can block
195/// such constructors using this.
196///
197/// A directive to be included inside
198/// [include_cpp] - see [include_cpp] for general information.
199#[macro_export]
200macro_rules! block_constructors {
201 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
202}
203
204/// The name of the mod to be generated with the FFI code.
205/// The default is `ffi`.
206///
207/// A directive to be included inside
208/// [include_cpp] - see [include_cpp] for general information.
209#[macro_export]
210macro_rules! name {
211 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
212}
213
214/// A concrete type to make, for example
215/// `concrete!("Container<Contents>")`.
216/// All types msut already be on the allowlist by having used
217/// `generate!` or similar.
218///
219/// A directive to be included inside
220/// [include_cpp] - see [include_cpp] for general information.
221#[macro_export]
222macro_rules! concrete {
223 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
224}
225
226/// Specifies a global safety policy for functions generated
227/// from these headers. By default (without such a `safety!`
228/// directive) all such functions are marked as `unsafe` and
229/// therefore can only be called within an `unsafe {}` block
230/// or some `unsafe` function which you create.
231///
232/// Alternatively, by specifying a `safety!` block you can
233/// declare that most generated functions are in fact safe.
234/// Specifically, you'd specify:
235/// `safety!(unsafe)`
236/// or
237/// `safety!(unsafe_ffi)`
238/// These two options are functionally identical. If you're
239/// unsure, simply use `unsafe`. The reason for the
240/// latter option is if you have code review policies which
241/// might want to give a different level of scrutiny to
242/// C++ interop as opposed to other types of unsafe Rust code.
243/// Maybe in your organization, C++ interop is less scary than
244/// a low-level Rust data structure using pointer manipulation.
245/// Or maybe it's more scary. Either way, using `unsafe` for
246/// the data structure and using `unsafe_ffi` for the C++
247/// interop allows you to apply different linting tools and
248/// policies to the different options.
249///
250/// Irrespective, C++ code is of course unsafe. It's worth
251/// noting that use of C++ can cause unexpected unsafety at
252/// a distance in faraway Rust code. As with any use of the
253/// `unsafe` keyword in Rust, *you the human* are declaring
254/// that you've analyzed all possible ways that the code
255/// can be used and you are guaranteeing to the compiler that
256/// no badness can occur. Good luck.
257///
258/// Generated C++ APIs which use raw pointers remain `unsafe`
259/// no matter what policy you choose.
260#[macro_export]
261macro_rules! safety {
262 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
263}
264
265/// Whether to avoid generating [`cxx::UniquePtr`] and [`cxx::Vector`]
266/// implementations. This is primarily useful for reducing test cases and
267/// shouldn't be used in normal operation.
268///
269/// A directive to be included inside
270/// [include_cpp] - see [include_cpp] for general information.
271#[macro_export]
272macro_rules! exclude_impls {
273 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
274}
275
276/// Indicates that a C++ type is not to be generated by autocxx in this case,
277/// but instead should refer to some pre-existing Rust type.
278/// Note that the size and alignment of this type *must* be correct.
279/// If you wish for the type to be POD, you can use a `pod!` directive too.
280///
281/// The syntax is:
282/// `extern_cpp_type!("CppNameGoesHere", path::to::rust::type)`
283///
284/// A directive to be included inside
285/// [include_cpp] - see [include_cpp] for general information.
286#[macro_export]
287macro_rules! extern_cpp_type {
288 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
289}
290
291/// Indicates that a C++ type is not to be generated by autocxx in this case,
292/// but instead should refer to some pre-existing Rust type. Unlike
293/// `extern_cpp_type!`, there's no need for the size and alignment of this
294/// type to be correct.
295///
296/// The syntax is:
297/// `extern_cpp_opaque_type!("CppNameGoesHere", path::to::rust::type)`
298///
299/// A directive to be included inside
300/// [include_cpp] - see [include_cpp] for general information.
301#[macro_export]
302macro_rules! extern_cpp_opaque_type {
303 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
304}
305
306/// Deprecated - use [`extern_rust_type`] instead.
307#[macro_export]
308#[deprecated]
309macro_rules! rust_type {
310 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
311}
312
313/// See [`extern_rust::extern_rust_type`].
314#[macro_export]
315macro_rules! extern_rust_type {
316 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
317}
318
319/// See [`subclass::subclass`].
320#[macro_export]
321macro_rules! subclass {
322 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
323}
324
325/// Indicates that a C++ type can definitely be instantiated. This has effect
326/// only in a very specific case:
327/// * the type is a typedef to something else
328/// * the 'something else' can't be fully inspected by autocxx, possibly
329/// becaue it relies on dependent qualified types or some other template
330/// arrangement that bindgen cannot fully understand.
331/// In such circumstances, autocxx normally has to err on the side of caution
332/// and assume that some type within the 'something else' is itself a forward
333/// declaration. That means, the opaque typedef won't be storable within
334/// a [`cxx::UniquePtr`]. If you know that no forward declarations are involved,
335/// you can declare the typedef type is instantiable and then you'll be able to
336/// own it within Rust.
337///
338/// The syntax is:
339/// `instantiable!("CppNameGoesHere")`
340///
341/// A directive to be included inside
342/// [include_cpp] - see [include_cpp] for general information.
343#[macro_export]
344macro_rules! instantiable {
345 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
346}
347
348#[doc(hidden)]
349#[macro_export]
350macro_rules! usage {
351 (__docs) => {};
352 ($($tt:tt)*) => {
353 compile_error! {r#"usage: include_cpp! {
354 #include "path/to/header.h"
355 generate!(...)
356 generate_pod!(...)
357 }
358"#}
359 };
360}
361
362use std::pin::Pin;
363
364#[doc(hidden)]
365pub use autocxx_macro::include_cpp_impl;
366
367#[doc(hidden)]
368pub use autocxx_macro::cpp_semantics;
369
370macro_rules! ctype_wrapper {
371 ($r:ident, $c:expr, $d:expr) => {
372 #[doc=$d]
373 #[derive(Debug, Eq, Copy, Clone, PartialEq, Hash)]
374 #[allow(non_camel_case_types)]
375 #[repr(transparent)]
376 pub struct $r(pub ::std::os::raw::$r);
377
378 /// # Safety
379 ///
380 /// We assert that the namespace and type ID refer to a C++
381 /// type which is equivalent to this Rust type.
382 unsafe impl cxx::ExternType for $r {
383 type Id = cxx::type_id!($c);
384 type Kind = cxx::kind::Trivial;
385 }
386
387 impl From<::std::os::raw::$r> for $r {
388 fn from(val: ::std::os::raw::$r) -> Self {
389 Self(val)
390 }
391 }
392
393 impl From<$r> for ::std::os::raw::$r {
394 fn from(val: $r) -> Self {
395 val.0
396 }
397 }
398 };
399}
400
401ctype_wrapper!(
402 c_ulonglong,
403 "c_ulonglong",
404 "Newtype wrapper for an unsigned long long"
405);
406ctype_wrapper!(c_longlong, "c_longlong", "Newtype wrapper for a long long");
407ctype_wrapper!(c_ulong, "c_ulong", "Newtype wrapper for an unsigned long");
408ctype_wrapper!(c_long, "c_long", "Newtype wrapper for a long");
409ctype_wrapper!(
410 c_ushort,
411 "c_ushort",
412 "Newtype wrapper for an unsigned short"
413);
414ctype_wrapper!(c_short, "c_short", "Newtype wrapper for an short");
415ctype_wrapper!(c_uint, "c_uint", "Newtype wrapper for an unsigned int");
416ctype_wrapper!(c_int, "c_int", "Newtype wrapper for an int");
417ctype_wrapper!(c_uchar, "c_uchar", "Newtype wrapper for an unsigned char");
418
419/// Newtype wrapper for a C void. Only useful as a `*c_void`
420#[allow(non_camel_case_types)]
421#[repr(transparent)]
422pub struct c_void(pub ::std::os::raw::c_void);
423
424/// # Safety
425///
426/// We assert that the namespace and type ID refer to a C++
427/// type which is equivalent to this Rust type.
428unsafe impl cxx::ExternType for c_void {
429 type Id = cxx::type_id!(c_void);
430 type Kind = cxx::kind::Trivial;
431}
432
433/// A C++ `char16_t`
434#[allow(non_camel_case_types)]
435#[repr(transparent)]
436pub struct c_char16_t(pub u16);
437
438/// # Safety
439///
440/// We assert that the namespace and type ID refer to a C++
441/// type which is equivalent to this Rust type.
442unsafe impl cxx::ExternType for c_char16_t {
443 type Id = cxx::type_id!(c_char16_t);
444 type Kind = cxx::kind::Trivial;
445}
446
447/// autocxx couldn't generate these bindings.
448/// If you come across a method, type or function which refers to this type,
449/// it indicates that autocxx couldn't generate that binding. A documentation
450/// comment should be attached indicating the reason.
451pub struct BindingGenerationFailure {
452 _unallocatable: [*const u8; 0],
453 _pinned: core::marker::PhantomData<core::marker::PhantomPinned>,
454}
455
456/// Tools to export Rust code to C++.
457// These are in a mod to avoid shadowing the definitions of the
458// directives above, which, being macro_rules, are unavoidably
459// in the crate root but must be function-style macros to keep
460// the include_cpp impl happy.
461pub mod extern_rust {
462
463 /// Declare that this is a Rust type which is to be exported to C++.
464 /// You can use this in two ways:
465 /// * as an attribute macro on a Rust type, for instance:
466 /// ```
467 /// # use autocxx_macro::extern_rust_type as extern_rust_type;
468 /// #[extern_rust_type]
469 /// struct Bar;
470 /// ```
471 /// * as a directive within the [include_cpp] macro, in which case
472 /// provide the type path in brackets:
473 /// ```
474 /// # use autocxx_macro::include_cpp_impl as include_cpp;
475 /// include_cpp!(
476 /// # parse_only!()
477 /// #include "input.h"
478 /// extern_rust_type!(Bar)
479 /// safety!(unsafe)
480 /// );
481 /// struct Bar;
482 /// ```
483 /// These may be used within references in the signatures of C++ functions,
484 /// for instance. This will contribute to an `extern "Rust"` section of the
485 /// generated `cxx` bindings, and this type will appear in the C++ header
486 /// generated for use in C++.
487 pub use autocxx_macro::extern_rust_type;
488
489 /// Declare that a given function is a Rust function which is to be exported
490 /// to C++. This is used as an attribute macro on a Rust function, for instance:
491 /// ```
492 /// # use autocxx_macro::extern_rust_function as extern_rust_function;
493 /// #[extern_rust_function]
494 /// pub fn call_me_from_cpp() { }
495 /// ```
496 pub use autocxx_macro::extern_rust_function;
497}
498
499/// Equivalent to [`std::convert::AsMut`], but returns a pinned mutable reference
500/// such that cxx methods can be called on it.
501pub trait PinMut<T>: AsRef<T> {
502 /// Return a pinned mutable reference to a type.
503 fn pin_mut(&mut self) -> std::pin::Pin<&mut T>;
504}
505
506/// Provides utility functions to emplace any [`moveit::New`] into a
507/// [`cxx::UniquePtr`]. Automatically imported by the autocxx prelude
508/// and implemented by any (autocxx-related) [`moveit::New`].
509pub trait WithinUniquePtr {
510 type Inner: UniquePtrTarget + MakeCppStorage;
511 fn within_unique_ptr(self) -> cxx::UniquePtr<Self::Inner>;
512}
513
514/// Provides utility functions to emplace any [`moveit::New`] into a
515/// [`Box`]. Automatically imported by the autocxx prelude
516/// and implemented by any (autocxx-related) [`moveit::New`].
517pub trait WithinBox {
518 type Inner;
519 fn within_box(self) -> Pin<Box<Self::Inner>>;
520}
521
522use cxx::kind::Trivial;
523use cxx::ExternType;
524use moveit::MakeCppStorage;
525use moveit::{Emplace, EmplaceUnpinned};
526
527impl<N, T> WithinUniquePtr for N
528where
529 N: New<Output = T>,
530 T: UniquePtrTarget + MakeCppStorage,
531{
532 type Inner = T;
533 fn within_unique_ptr(self) -> cxx::UniquePtr<T> {
534 UniquePtr::emplace(self)
535 }
536}
537
538impl<N, T> WithinBox for N
539where
540 N: New<Output = T>,
541{
542 type Inner = T;
543 fn within_box(self) -> Pin<Box<T>> {
544 Box::emplace(self)
545 }
546}
547
548/// Emulates the [`WithinUniquePtr`] trait, but for trivial (plain old data) types.
549/// This allows such types to behave identically if a type is changed from
550/// `generate!` to `generate_pod!`.
551///
552/// (Ideally, this would be the exact same trait as [`WithinUniquePtr`] but this runs
553/// the risk of conflicting implementations. Negative trait bounds would solve
554/// this!)
555pub trait WithinUniquePtrTrivial: UniquePtrTarget + Sized + Unpin {
556 fn within_unique_ptr(self) -> cxx::UniquePtr<Self>;
557}
558
559impl<T> WithinUniquePtrTrivial for T
560where
561 T: UniquePtrTarget + ExternType<Kind = Trivial> + Sized + Unpin,
562{
563 fn within_unique_ptr(self) -> cxx::UniquePtr<T> {
564 UniquePtr::new(self)
565 }
566}
567
568/// Emulates the [`WithinBox`] trait, but for trivial (plain old data) types.
569/// This allows such types to behave identically if a type is changed from
570/// `generate!` to `generate_pod!`.
571///
572/// (Ideally, this would be the exact same trait as [`WithinBox`] but this runs
573/// the risk of conflicting implementations. Negative trait bounds would solve
574/// this!)
575pub trait WithinBoxTrivial: Sized + Unpin {
576 fn within_box(self) -> Pin<Box<Self>>;
577}
578
579impl<T> WithinBoxTrivial for T
580where
581 T: ExternType<Kind = Trivial> + Sized + Unpin,
582{
583 fn within_box(self) -> Pin<Box<T>> {
584 Pin::new(Box::new(self))
585 }
586}
587
588use cxx::memory::UniquePtrTarget;
589use cxx::UniquePtr;
590use moveit::New;
591pub use rvalue_param::RValueParam;
592pub use rvalue_param::RValueParamHandler;
593pub use value_param::as_copy;
594pub use value_param::as_mov;
595pub use value_param::as_new;
596pub use value_param::ValueParam;
597pub use value_param::ValueParamHandler;
598
599/// Imports which you're likely to want to use.
600pub mod prelude {
601 pub use crate::as_copy;
602 pub use crate::as_mov;
603 pub use crate::as_new;
604 pub use crate::c_int;
605 pub use crate::c_long;
606 pub use crate::c_longlong;
607 pub use crate::c_short;
608 pub use crate::c_uchar;
609 pub use crate::c_uint;
610 pub use crate::c_ulong;
611 pub use crate::c_ulonglong;
612 pub use crate::c_ushort;
613 pub use crate::c_void;
614 pub use crate::cpp_semantics;
615 pub use crate::include_cpp;
616 pub use crate::PinMut;
617 pub use crate::RValueParam;
618 pub use crate::ValueParam;
619 pub use crate::WithinBox;
620 pub use crate::WithinBoxTrivial;
621 pub use crate::WithinUniquePtr;
622 pub use crate::WithinUniquePtrTrivial;
623 pub use cxx::UniquePtr;
624 pub use moveit::moveit;
625 pub use moveit::new::New;
626 pub use moveit::Emplace;
627 pub use moveit::EmplaceUnpinned;
628}
629
630/// Re-export moveit for ease of consumers.
631pub use moveit;
632
633/// Re-export cxx such that clients can use the same version as
634/// us. This doesn't enable clients to avoid depending on the cxx
635/// crate too, unfortunately, since generated cxx::bridge code
636/// refers explicitly to ::cxx. See
637/// <https://github.com/google/autocxx/issues/36>
638pub use cxx;