Repository: dtolnay/cxx (rust)

Issue:
Split cxx crate into runtime and build.rs components
Right now, the cxx crate contains both runtime components (e.g. `cxx::unique_ptr`) and build time components (e.g. `cxx::gen`, `cxx::Build`).

This is negative because:
* For cross compilation builds, this requires that what should be build-only dependencies be supported on the target.
* This builds more functionality into the target binary than needed. If cxx is linked statically, there's a good chance most of this will be removed, but it will bloat in cases where it's linked dynamically.
* For homogenous build systems (bazel, buck, etc.) this requires them to pull in the `cc` and `link_cplusplus` crates to their source tree, which will never actually be used.

The two ways I see forwards here are:
* Split it using features. Users of homogenous build system, or who cared about binary size, etc. would be expected to disable a default feature to get a support-code-only version of the crate.
* Split it into separate crates, e.g. cxx-support and cxx-build, possibly keeping the main cxx crate as a wrapper that re-exports both.

Opinions?

Pull request description:
Split cxx runtime and build components
This PR moves out the build-related parts of the `cxx` crate to a separate `cxx-build` crate. The two would now be used as:

```diff
  [dependencies]
  cxx = "0.3"

  [build-dependencies]
- cxx = "0.3"
+ cxx-build = "0.3"
```

Closes #144.

Patch:
diff --git a/.travis.yml b/.travis.yml
index 6c0ca544..0243407e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,15 +20,15 @@ matrix:
       rust: nightly-x86_64-pc-windows-gnu
       before_script:
         # windows is bad at symlinks
-        - rm cmd/src/gen cmd/src/syntax gen/include macro/src/syntax src/gen src/syntax
-        - cp -r include gen; cp -r gen cmd/src; cp -r syntax cmd/src; cp -r syntax macro/src; cp -r gen src; cp -r syntax src
+        - rm gen/build/src/gen gen/build/src/syntax gen/cmd/src/gen gen/cmd/src/syntax gen/src/include macro/src/syntax
+        - cp -r include gen/src; cp -r gen/src gen/build/src/gen; cp -r gen/src gen/cmd/src/gen; cp -r syntax gen/build/src; cp -r syntax gen/cmd/src; cp -r syntax macro/src
 
     - name: Windows (msvc)
       os: windows
       rust: nightly-x86_64-pc-windows-msvc
       before_script:
-        - rm cmd/src/gen cmd/src/syntax gen/include macro/src/syntax src/gen src/syntax
-        - cp -r include gen; cp -r gen cmd/src; cp -r syntax cmd/src; cp -r syntax macro/src; cp -r gen src; cp -r syntax src
+        - rm gen/build/src/gen gen/build/src/syntax gen/cmd/src/gen gen/cmd/src/syntax gen/src/include macro/src/syntax
+        - cp -r include gen/src; cp -r gen/src gen/build/src/gen; cp -r gen/src gen/cmd/src/gen; cp -r syntax gen/build/src; cp -r syntax gen/cmd/src; cp -r syntax macro/src
 
     - name: Buck
       rust: nightly
@@ -62,3 +62,7 @@ matrix:
       rust: 1.42.0
       script:
         - cargo run --manifest-path demo-rs/Cargo.toml
+
+  # https://github.com/dtolnay/cxx/pull/167
+  allow_failures:
+    - name: Buck
diff --git a/BUCK b/BUCK
index 6a9870ef..2339f714 100644
--- a/BUCK
+++ b/BUCK
@@ -5,19 +5,13 @@ rust_library(
     deps = [
         ":core",
         ":macro",
-        "//third-party:anyhow",
-        "//third-party:cc",
-        "//third-party:codespan-reporting",
         "//third-party:link-cplusplus",
-        "//third-party:proc-macro2",
-        "//third-party:quote",
-        "//third-party:syn",
     ],
 )
 
 rust_binary(
     name = "codegen",
-    srcs = glob(["cmd/src/**"]),
+    srcs = glob(["gen/cmd/src/**"]),
     crate = "cxxbridge",
     visibility = ["PUBLIC"],
     deps = [
@@ -52,3 +46,17 @@ rust_library(
         "//third-party:syn",
     ],
 )
+
+rust_library(
+    name = "build",
+    srcs = glob(["gen/build/src/**"]),
+    visibility = ["PUBLIC"],
+    deps = [
+        "//third-party:anyhow",
+        "//third-party:cc",
+        "//third-party:codespan-reporting",
+        "//third-party:proc-macro2",
+        "//third-party:quote",
+        "//third-party:syn",
+    ],
+)
diff --git a/BUILD b/BUILD
index 2eea8c73..d63fea7e 100644
--- a/BUILD
+++ b/BUILD
@@ -3,25 +3,18 @@ load("//tools/bazel:rust.bzl", "rust_binary", "rust_library")
 rust_library(
     name = "cxx",
     srcs = glob(["src/**/*.rs"]),
-    data = ["src/gen/include/cxx.h"],
     visibility = ["//visibility:public"],
     deps = [
         ":core-lib",
         ":cxxbridge-macro",
-        "//third-party:anyhow",
-        "//third-party:cc",
-        "//third-party:codespan-reporting",
         "//third-party:link-cplusplus",
-        "//third-party:proc-macro2",
-        "//third-party:quote",
-        "//third-party:syn",
     ],
 )
 
 rust_binary(
     name = "codegen",
-    srcs = glob(["cmd/src/**/*.rs"]),
-    data = ["cmd/src/gen/include/cxx.h"],
+    srcs = glob(["gen/cmd/src/**/*.rs"]),
+    data = ["gen/cmd/src/gen/include/cxx.h"],
     visibility = ["//visibility:public"],
     deps = [
         "//third-party:anyhow",
@@ -57,3 +50,18 @@ rust_library(
         "//third-party:syn",
     ],
 )
+
+rust_library(
+    name = "build",
+    srcs = glob(["gen/build/src/**/*.rs"]),
+    data = ["gen/build/src/gen/include/cxx.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//third-party:anyhow",
+        "//third-party:cc",
+        "//third-party:codespan-reporting",
+        "//third-party:proc-macro2",
+        "//third-party:quote",
+        "//third-party:syn",
+    ],
+)
diff --git a/Cargo.toml b/Cargo.toml
index a47a8421..ea97712e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,25 +15,20 @@ exclude = ["/demo-cxx", "/gen", "/syntax", "/third-party"]
 travis-ci = { repository = "dtolnay/cxx" }
 
 [dependencies]
-anyhow = "1.0"
-cc = "1.0.49"
-codespan-reporting = "0.9"
 cxxbridge-macro = { version = "=0.2.12", path = "macro" }
 link-cplusplus = "1.0"
-proc-macro2 = { version = "1.0", features = ["span-locations"] }
-quote = "1.0"
-syn = { version = "1.0", features = ["full"] }
 
 [build-dependencies]
 cc = "1.0.49"
 
 [dev-dependencies]
+cxx-build = { version = "=0.2.12", path = "gen/build" }
 cxx-test-suite = { version = "0", path = "tests/ffi" }
 rustversion = "1.0"
 trybuild = { version = "1.0.21", features = ["diff"] }
 
 [workspace]
-members = ["cmd", "demo-rs", "macro", "tests/ffi"]
+members = ["demo-rs", "gen/build", "gen/cmd", "macro", "tests/ffi"]
 
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
diff --git a/README.md b/README.md
index 7dc7c8b3..59bcdac0 100644
--- a/README.md
+++ b/README.md
@@ -219,8 +219,7 @@ set up any additional source files and compiler flags as normal.
 // build.rs
 
 fn main() {
-    cxx::Build::new()
-        .bridge("src/main.rs")  // returns a cc::Build
+    cxx_build::bridge("src/main.rs")  // returns a cc::Build
         .file("../demo-cxx/demo.cc")
         .flag("-std=c++11")
         .compile("cxxbridge-demo");
diff --git a/cmd/LICENSE-APACHE b/cmd/LICENSE-APACHE
deleted file mode 120000
index 965b606f..00000000
--- a/cmd/LICENSE-APACHE
+++ /dev/null
@@ -1,1 +0,0 @@
-../LICENSE-APACHE
\ No newline at end of file
diff --git a/cmd/LICENSE-MIT b/cmd/LICENSE-MIT
deleted file mode 120000
index 76219eb7..00000000
--- a/cmd/LICENSE-MIT
+++ /dev/null
@@ -1,1 +0,0 @@
-../LICENSE-MIT
\ No newline at end of file
diff --git a/cmd/src/gen b/cmd/src/gen
deleted file mode 120000
index eb225777..00000000
--- a/cmd/src/gen
+++ /dev/null
@@ -1,1 +0,0 @@
-../../gen
\ No newline at end of file
diff --git a/cmd/src/syntax b/cmd/src/syntax
deleted file mode 120000
index 83b00802..00000000
--- a/cmd/src/syntax
+++ /dev/null
@@ -1,1 +0,0 @@
-../../syntax
\ No newline at end of file
diff --git a/demo-rs/Cargo.toml b/demo-rs/Cargo.toml
index f7e7f843..d2147ab8 100644
--- a/demo-rs/Cargo.toml
+++ b/demo-rs/Cargo.toml
@@ -9,4 +9,4 @@ publish = false
 cxx = { path = ".." }
 
 [build-dependencies]
-cxx = { path = ".." }
+cxx-build = { path = "../gen/build" }
diff --git a/demo-rs/build.rs b/demo-rs/build.rs
index 71def718..edbb2819 100644
--- a/demo-rs/build.rs
+++ b/demo-rs/build.rs
@@ -1,6 +1,5 @@
 fn main() {
-    cxx::Build::new()
-        .bridge("src/main.rs")
+    cxx_build::bridge("src/main.rs")
         .file("../demo-cxx/demo.cc")
         .flag("-std=c++11")
         .compile("cxxbridge-demo");
diff --git a/gen/README.md b/gen/README.md
new file mode 100644
index 00000000..9786911b
--- /dev/null
+++ b/gen/README.md
@@ -0,0 +1,4 @@
+This directory contains CXX's C++ code generator. This code generator has two
+public frontends, one a command-line application (binary) in the *cmd* directory
+and the other a library intended to be used from a build.rs in the *build*
+directory.
diff --git a/gen/build/Cargo.toml b/gen/build/Cargo.toml
new file mode 100644
index 00000000..3552524d
--- /dev/null
+++ b/gen/build/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "cxx-build"
+version = "0.2.12"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+edition = "2018"
+license = "MIT OR Apache-2.0"
+description = "C++ code generator for integrating `cxx` crate into a Cargo build."
+repository = "https://github.com/dtolnay/cxx"
+
+[badges]
+travis-ci = { repository = "dtolnay/cxx" }
+
+[dependencies]
+anyhow = "1.0"
+cc = "1.0.49"
+codespan-reporting = "0.9"
+proc-macro2 = { version = "1.0", features = ["span-locations"] }
+quote = "1.0"
+syn = { version = "1.0", features = ["full"] }
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gen/build/LICENSE-APACHE b/gen/build/LICENSE-APACHE
new file mode 120000
index 00000000..1cd601d0
--- /dev/null
+++ b/gen/build/LICENSE-APACHE
@@ -0,0 +1,1 @@
+../../LICENSE-APACHE
\ No newline at end of file
diff --git a/gen/build/LICENSE-MIT b/gen/build/LICENSE-MIT
new file mode 120000
index 00000000..b2cfbdc7
--- /dev/null
+++ b/gen/build/LICENSE-MIT
@@ -0,0 +1,1 @@
+../../LICENSE-MIT
\ No newline at end of file
diff --git a/src/error.rs b/gen/build/src/error.rs
similarity index 100%
rename from src/error.rs
rename to gen/build/src/error.rs
diff --git a/gen/build/src/gen b/gen/build/src/gen
new file mode 120000
index 00000000..929cb3dc
--- /dev/null
+++ b/gen/build/src/gen
@@ -0,0 +1,1 @@
+../../src
\ No newline at end of file
diff --git a/gen/build/src/lib.rs b/gen/build/src/lib.rs
new file mode 100644
index 00000000..5bee67f0
--- /dev/null
+++ b/gen/build/src/lib.rs
@@ -0,0 +1,96 @@
+//! The CXX code generator for constructing and compiling C++ code.
+//!
+//! This is intended to be used from Cargo build scripts to execute CXX's
+//! C++ code generator, set up any additional compiler flags depending on
+//! the use case, and make the C++ compiler invocation.
+//!
+//! <br>
+//!
+//! # Example
+//!
+//! Example of a canonical Cargo build script that builds a CXX bridge:
+//!
+//! ```no_run
+//! // build.rs
+//!
+//! fn main() {
+//!     cxx_build::bridge("src/main.rs")
+//!         .file("../demo-cxx/demo.cc")
+//!         .flag("-std=c++11")
+//!         .compile("cxxbridge-demo");
+//!
+//!     println!("cargo:rerun-if-changed=src/main.rs");
+//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.h");
+//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.cc");
+//! }
+//! ```
+//!
+//! A runnable working setup with this build script is shown in the
+//! *demo-rs* and *demo-cxx* directories of [https://github.com/dtolnay/cxx].
+//!
+//! [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx
+//!
+//! <br>
+//!
+//! # Alternatives
+//!
+//! For use in non-Cargo builds like Bazel or Buck, CXX provides an
+//! alternate way of invoking the C++ code generator as a standalone command
+//! line tool. The tool is packaged as the `cxxbridge-cmd` crate.
+//!
+//! ```bash
+//! $ cargo install cxxbridge-cmd  # or build it from the repo
+//!
+//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
+//! $ cxxbridge src/main.rs > path/to/mybridge.cc
+//! ```
+
+mod error;
+mod gen;
+mod paths;
+mod syntax;
+
+use crate::error::Result;
+use crate::gen::Opt;
+use anyhow::anyhow;
+use std::fs;
+use std::io::{self, Write};
+use std::path::Path;
+use std::process;
+
+/// This returns a [`cc::Build`] on which you should continue to set up any
+/// additional source files or compiler flags, and lastly call its [`compile`]
+/// method to execute the C++ build.
+///
+/// [`compile`]: https://docs.rs/cc/1.0.49/cc/struct.Build.html#method.compile
+#[must_use]
+pub fn bridge(rust_source_file: impl AsRef<Path>) -> cc::Build {
+    match try_generate_bridge(rust_source_file.as_ref()) {
+        Ok(build) => build,
+        Err(err) => {
+            let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {:?}\n\n", anyhow!(err));
+            process::exit(1);
+        }
+    }
+}
+
+fn try_generate_bridge(rust_source_file: &Path) -> Result<cc::Build> {
+    let header = gen::do_generate_header(rust_source_file, Opt::default());
+    let header_path = paths::out_with_extension(rust_source_file, ".h")?;
+    fs::create_dir_all(header_path.parent().unwrap())?;
+    fs::write(&header_path, header)?;
+    paths::symlink_header(&header_path, rust_source_file);
+
+    let bridge = gen::do_generate_bridge(rust_source_file, Opt::default());
+    let bridge_path = paths::out_with_extension(rust_source_file, ".cc")?;
+    fs::write(&bridge_path, bridge)?;
+    let mut build = paths::cc_build();
+    build.file(&bridge_path);
+
+    let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
+    let _ = fs::create_dir_all(cxx_h.parent().unwrap());
+    let _ = fs::remove_file(cxx_h);
+    let _ = fs::write(cxx_h, gen::include::HEADER);
+
+    Ok(build)
+}
diff --git a/src/paths.rs b/gen/build/src/paths.rs
similarity index 100%
rename from src/paths.rs
rename to gen/build/src/paths.rs
diff --git a/gen/build/src/syntax b/gen/build/src/syntax
new file mode 120000
index 00000000..a6fe06cd
--- /dev/null
+++ b/gen/build/src/syntax
@@ -0,0 +1,1 @@
+../../../syntax
\ No newline at end of file
diff --git a/cmd/Cargo.toml b/gen/cmd/Cargo.toml
similarity index 100%
rename from cmd/Cargo.toml
rename to gen/cmd/Cargo.toml
diff --git a/gen/cmd/LICENSE-APACHE b/gen/cmd/LICENSE-APACHE
new file mode 120000
index 00000000..1cd601d0
--- /dev/null
+++ b/gen/cmd/LICENSE-APACHE
@@ -0,0 +1,1 @@
+../../LICENSE-APACHE
\ No newline at end of file
diff --git a/gen/cmd/LICENSE-MIT b/gen/cmd/LICENSE-MIT
new file mode 120000
index 00000000..b2cfbdc7
--- /dev/null
+++ b/gen/cmd/LICENSE-MIT
@@ -0,0 +1,1 @@
+../../LICENSE-MIT
\ No newline at end of file
diff --git a/gen/cmd/src/gen b/gen/cmd/src/gen
new file mode 120000
index 00000000..929cb3dc
--- /dev/null
+++ b/gen/cmd/src/gen
@@ -0,0 +1,1 @@
+../../src
\ No newline at end of file
diff --git a/cmd/src/lib.rs b/gen/cmd/src/lib.rs
similarity index 100%
rename from cmd/src/lib.rs
rename to gen/cmd/src/lib.rs
diff --git a/cmd/src/main.rs b/gen/cmd/src/main.rs
similarity index 100%
rename from cmd/src/main.rs
rename to gen/cmd/src/main.rs
diff --git a/gen/cmd/src/syntax b/gen/cmd/src/syntax
new file mode 120000
index 00000000..a6fe06cd
--- /dev/null
+++ b/gen/cmd/src/syntax
@@ -0,0 +1,1 @@
+../../../syntax
\ No newline at end of file
diff --git a/gen/include b/gen/include
deleted file mode 120000
index f5030fe8..00000000
--- a/gen/include
+++ /dev/null
@@ -1,1 +0,0 @@
-../include
\ No newline at end of file
diff --git a/gen/error.rs b/gen/src/error.rs
similarity index 100%
rename from gen/error.rs
rename to gen/src/error.rs
diff --git a/gen/src/include b/gen/src/include
new file mode 120000
index 00000000..fcffffbe
--- /dev/null
+++ b/gen/src/include
@@ -0,0 +1,1 @@
+../../include
\ No newline at end of file
diff --git a/gen/include.rs b/gen/src/include.rs
similarity index 100%
rename from gen/include.rs
rename to gen/src/include.rs
diff --git a/gen/mod.rs b/gen/src/mod.rs
similarity index 100%
rename from gen/mod.rs
rename to gen/src/mod.rs
diff --git a/gen/out.rs b/gen/src/out.rs
similarity index 100%
rename from gen/out.rs
rename to gen/src/out.rs
diff --git a/gen/write.rs b/gen/src/write.rs
similarity index 100%
rename from gen/write.rs
rename to gen/src/write.rs
diff --git a/macro/Cargo.toml b/macro/Cargo.toml
index 82401eef..c7c48ec1 100644
--- a/macro/Cargo.toml
+++ b/macro/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2018"
 license = "MIT OR Apache-2.0"
 description = "Implementation detail of the `cxx` crate."
 repository = "https://github.com/dtolnay/cxx"
+exclude = ["README.md"]
 
 [lib]
 proc-macro = true
diff --git a/macro/README.md b/macro/README.md
new file mode 100644
index 00000000..b9c17798
--- /dev/null
+++ b/macro/README.md
@@ -0,0 +1,3 @@
+This directory contains CXX's Rust code generator, which is a procedural macro.
+Users won't depend on this crate directly. Instead they'll invoke its macro
+through the reexport in the main `cxx` crate.
diff --git a/src/gen b/src/gen
deleted file mode 120000
index 334e0fbd..00000000
--- a/src/gen
+++ /dev/null
@@ -1,1 +0,0 @@
-../gen
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index cff1e88d..7e8e9ecc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -224,8 +224,7 @@
 //! // build.rs
 //!
 //! fn main() {
-//!     cxx::Build::new()
-//!         .bridge("src/main.rs")  // returns a cc::Build
+//!     cxx_build::bridge("src/main.rs")  // returns a cc::Build
 //!         .file("../demo-cxx/demo.cc")
 //!         .flag("-std=c++11")
 //!         .compile("cxxbridge-demo");
@@ -363,18 +362,14 @@ mod concat;
 
 mod cxx_string;
 mod cxx_vector;
-mod error;
 mod exception;
 mod function;
-mod gen;
 mod opaque;
-mod paths;
 mod result;
 mod rust_sliceu8;
 mod rust_str;
 mod rust_string;
 mod rust_vec;
-mod syntax;
 mod unique_ptr;
 mod unwind;
 
@@ -398,107 +393,3 @@ pub mod private {
     pub use crate::unique_ptr::UniquePtrTarget;
     pub use crate::unwind::catch_unwind;
 }
-
-use crate::error::Result;
-use crate::gen::Opt;
-use anyhow::anyhow;
-use std::fs;
-use std::io::{self, Write};
-use std::path::Path;
-use std::process;
-
-/// The CXX code generator for constructing and compiling C++ code.
-///
-/// This is intended to be used from Cargo build scripts to execute CXX's
-/// C++ code generator, set up any additional compiler flags depending on
-/// the use case, and make the C++ compiler invocation.
-///
-/// <br>
-///
-/// # Example
-///
-/// Example of a canonical Cargo build script that builds a CXX bridge:
-///
-/// ```no_run
-/// // build.rs
-///
-/// fn main() {
-///     cxx::Build::new()
-///         .bridge("src/main.rs")
-///         .file("../demo-cxx/demo.cc")
-///         .flag("-std=c++11")
-///         .compile("cxxbridge-demo");
-///
-///     println!("cargo:rerun-if-changed=src/main.rs");
-///     println!("cargo:rerun-if-changed=../demo-cxx/demo.h");
-///     println!("cargo:rerun-if-changed=../demo-cxx/demo.cc");
-/// }
-/// ```
-///
-/// A runnable working setup with this build script is shown in the
-/// *demo-rs* and *demo-cxx* directories of [https://github.com/dtolnay/cxx].
-///
-/// [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx
-///
-/// <br>
-///
-/// # Alternatives
-///
-/// For use in non-Cargo builds like Bazel or Buck, CXX provides an
-/// alternate way of invoking the C++ code generator as a standalone command
-/// line tool. The tool is packaged as the `cxxbridge-cmd` crate.
-///
-/// ```bash
-/// $ cargo install cxxbridge-cmd  # or build it from the repo
-///
-/// $ cxxbridge src/main.rs --header > path/to/mybridge.h
-/// $ cxxbridge src/main.rs > path/to/mybridge.cc
-/// ```
-#[must_use]
-pub struct Build {
-    _private: (),
-}
-
-impl Build {
-    /// Begin with a [`cc::Build`] in its default configuration.
-    pub fn new() -> Self {
-        Build { _private: () }
-    }
-
-    /// This returns a [`cc::Build`] on which you should continue to set up
-    /// any additional source files or compiler flags, and lastly call its
-    /// [`compile`] method to execute the C++ build.
-    ///
-    /// [`compile`]: https://docs.rs/cc/1.0.49/cc/struct.Build.html#method.compile
-    #[must_use]
-    pub fn bridge(&self, rust_source_file: impl AsRef<Path>) -> cc::Build {
-        match try_generate_bridge(rust_source_file.as_ref()) {
-            Ok(build) => build,
-            Err(err) => {
-                let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {:?}\n\n", anyhow!(err));
-                process::exit(1);
-            }
-        }
-    }
-}
-
-fn try_generate_bridge(rust_source_file: &Path) -> Result<cc::Build> {
-    let header = gen::do_generate_header(rust_source_file, Opt::default());
-    let header_path = paths::out_with_extension(rust_source_file, ".h")?;
-    fs::create_dir_all(header_path.parent().unwrap())?;
-    fs::write(&header_path, header)?;
-    paths::symlink_header(&header_path, rust_source_file);
-
-    let bridge = gen::do_generate_bridge(rust_source_file, Opt::default());
-    let bridge_path = paths::out_with_extension(rust_source_file, ".cc")?;
-    fs::write(&bridge_path, bridge)?;
-    let mut build = paths::cc_build();
-    build.file(&bridge_path);
-
-    let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
-    let _ = fs::create_dir_all(cxx_h.parent().unwrap());
-    let _ = fs::remove_file(cxx_h);
-    let _ = fs::write(cxx_h, gen::include::HEADER);
-
-    Ok(build)
-}
diff --git a/src/syntax b/src/syntax
deleted file mode 120000
index f4007125..00000000
--- a/src/syntax
+++ /dev/null
@@ -1,1 +0,0 @@
-../syntax
\ No newline at end of file
diff --git a/third-party/Cargo.lock b/third-party/Cargo.lock
index 0bd470b9..f4068d95 100644
--- a/third-party/Cargo.lock
+++ b/third-party/Cargo.lock
@@ -67,17 +67,25 @@ dependencies = [
 name = "cxx"
 version = "0.2.12"
 dependencies = [
- "anyhow",
  "cc",
- "codespan-reporting",
+ "cxx-build",
  "cxx-test-suite",
  "cxxbridge-macro",
  "link-cplusplus",
+ "rustversion",
+ "trybuild",
+]
+
+[[package]]
+name = "cxx-build"
+version = "0.2.12"
+dependencies = [
+ "anyhow",
+ "cc",
+ "codespan-reporting",
  "proc-macro2",
  "quote",
- "rustversion",
  "syn",
- "trybuild",
 ]
 
 [[package]]
@@ -85,6 +93,7 @@ name = "cxx-test-suite"
 version = "0.0.0"
 dependencies = [
  "cxx",
+ "cxx-build",
 ]
 
 [[package]]
@@ -104,6 +113,7 @@ name = "cxxbridge-demo"
 version = "0.0.0"
 dependencies = [
  "cxx",
+ "cxx-build",
 ]
 
 [[package]]


Test patch:
diff --git a/tests/ffi/Cargo.toml b/tests/ffi/Cargo.toml
index c84df61f..c2d82276 100644
--- a/tests/ffi/Cargo.toml
+++ b/tests/ffi/Cargo.toml
@@ -11,4 +11,4 @@ path = "lib.rs"
 cxx = { path = "../.." }
 
 [build-dependencies]
-cxx = { path = "../.." }
+cxx-build = { path = "../../gen/build" }
diff --git a/tests/ffi/build.rs b/tests/ffi/build.rs
index 5c1bec36..b970362a 100644
--- a/tests/ffi/build.rs
+++ b/tests/ffi/build.rs
@@ -3,8 +3,7 @@ fn main() {
         return;
     }
 
-    cxx::Build::new()
-        .bridge("lib.rs")
+    cxx_build::bridge("lib.rs")
         .file("tests.cc")
         .flag("-std=c++11")
         .compile("cxx-test-suite");