diff --git a/build/common.rs b/build/common.rs
new file mode 100644
index 0000000..958ef9b
--- /dev/null
+++ b/build/common.rs
@@ -0,0 +1,221 @@
+// Copyright 2018 Kyle Mayes
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+extern crate glob;
+
+use std::env;
+use std::path::{Path, PathBuf};
+use std::process::Command;
+
+use glob::MatchOptions;
+
+/// `libclang` directory patterns for FreeBSD and Linux.
+const DIRECTORIES_LINUX: &[&str] = &[
+    "/usr/lib*",
+    "/usr/lib*/*",
+    "/usr/lib*/*/*",
+    "/usr/local/lib*",
+    "/usr/local/lib*/*",
+    "/usr/local/lib*/*/*",
+    "/usr/local/llvm*/lib*",
+];
+
+/// `libclang` directory patterns for macOS.
+const DIRECTORIES_MACOS: &[&str] = &[
+    "/usr/local/opt/llvm*/lib",
+    "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
+    "/Library/Developer/CommandLineTools/usr/lib",
+    "/usr/local/opt/llvm*/lib/llvm*/lib",
+];
+
+/// `libclang` directory patterns for Windows.
+const DIRECTORIES_WINDOWS: &[&str] = &[
+    "C:\\LLVM\\lib",
+    "C:\\Program Files*\\LLVM\\lib",
+    "C:\\MSYS*\\MinGW*\\lib",
+];
+
+/// Executes the supplied console command, returning the `stdout` output if the
+/// command was successfully executed.
+fn run_command(command: &str, arguments: &[&str]) -> Option<String> {
+    macro_rules! warn {
+        ($error:expr) => {
+            println!(
+                "cargo:warning=couldn't execute `{} {}` ({})",
+                command,
+                arguments.join(" "),
+                $error,
+            );
+        };
+    }
+
+    let output = match Command::new(command).args(arguments).output() {
+        Ok(output) => output,
+        Err(error) => {
+            warn!(format!("error: {}", error));
+            return None;
+        }
+    };
+
+    if !output.status.success() {
+        warn!(format!("exit code: {}", output.status));
+        return None;
+    }
+
+    Some(String::from_utf8_lossy(&output.stdout).into_owned())
+}
+
+/// Executes `llvm-config`, returning the `stdout` output if the command was
+/// successfully executed.
+pub fn run_llvm_config(arguments: &[&str]) -> Option<String> {
+    let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into());
+
+    let output = run_command(&path, arguments);
+    if output.is_none() {
+        println!(
+            "cargo:warning=set the LLVM_CONFIG_PATH environment variable to \
+            the full path to a valid `llvm-config` executable (including the \
+            executable itself)"
+        );
+    }
+
+    output
+}
+
+/// Returns the paths to and the filenames of the files matching the supplied
+/// filename patterns in the supplied directory.
+fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> {
+    // Join the directory to the filename patterns to obtain the path patterns.
+    let paths = filenames
+        .iter()
+        .filter_map(|f| directory.join(f).to_str().map(ToOwned::to_owned));
+
+    // Prevent wildcards from matching path separators.
+    let mut options = MatchOptions::new();
+    options.require_literal_separator = true;
+
+    paths
+        .flat_map(|p| {
+            if let Ok(paths) = glob::glob_with(&p, options) {
+                paths.filter_map(Result::ok).collect()
+            } else {
+                vec![]
+            }
+        })
+        .filter_map(|p| {
+            let filename = p.file_name().and_then(|f| f.to_str())?;
+
+            // The `libclang_shared` library has been renamed to `libclang-cpp`
+            // in Clang 10. This can cause instances of this library (e.g.,
+            // `libclang-cpp.so.10`) to be matched by patterns looking for
+            // instances of `libclang`.
+            if filename.contains("-cpp.") {
+                return None;
+            }
+
+            Some((directory.to_owned(), filename.into()))
+        })
+        .collect::<Vec<_>>()
+}
+
+/// Returns the paths to and the filenames of the files matching the supplied
+/// filename patterns in the supplied directory, checking any relevant sibling
+/// directories.
+fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> {
+    let mut results = search_directory(directory, filenames);
+
+    // On Windows, `libclang.dll` is usually found in the LLVM `bin` directory
+    // while `libclang.lib` is usually found in the LLVM `lib` directory. To
+    // keep things consistent with other platforms, only LLVM `lib` directories
+    // are included in the backup search directory globs so we need to search
+    // the LLVM `bin` directory here.
+    if cfg!(target_os = "windows") && directory.ends_with("lib") {
+        let sibling = directory.parent().unwrap().join("bin");
+        results.extend(search_directory(&sibling, filenames).into_iter());
+    }
+
+    results
+}
+
+/// Returns the paths to and the filenames of the `libclang` static or dynamic
+/// libraries matching the supplied filename patterns.
+pub fn search_libclang_directories(files: &[String], variable: &str) -> Vec<(PathBuf, String)> {
+    // Use the path provided by the relevant environment variable.
+    if let Ok(path) = env::var(variable).map(|d| Path::new(&d).to_path_buf()) {
+        // Check if the path is referring to a matching file already.
+        if let Some(parent) = path.parent() {
+            let filename = path.file_name().unwrap().to_str().unwrap();
+            let libraries = search_directories(parent, files);
+            if libraries.iter().any(|(_, f)| f == filename) {
+                return vec![(parent.into(), filename.into())];
+            }
+        }
+
+        return search_directories(&path, files);
+    }
+
+    let mut found = vec![];
+
+    // Search the `bin` and `lib` directories in directory provided by
+    // `llvm-config --prefix`.
+    if let Some(output) = run_llvm_config(&["--prefix"]) {
+        let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
+        found.extend(search_directories(&directory.join("bin"), files));
+        found.extend(search_directories(&directory.join("lib"), files));
+        found.extend(search_directories(&directory.join("lib64"), files));
+    }
+
+    // Search the toolchain directory in the directory provided by
+    // `xcode-select --print-path`.
+    if cfg!(target_os = "macos") {
+        if let Some(output) = run_command("xcode-select", &["--print-path"]) {
+            let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
+            let directory = directory.join("Toolchains/XcodeDefault.xctoolchain/usr/lib");
+            found.extend(search_directories(&directory, files));
+        }
+    }
+
+    // Search the directories provided by the `LD_LIBRARY_PATH` environment
+    // variable.
+    if let Ok(path) = env::var("LD_LIBRARY_PATH") {
+        for directory in path.split(':').map(Path::new) {
+            found.extend(search_directories(&directory, files));
+        }
+    }
+
+    // Determine the `libclang` directory patterns.
+    let directories = if cfg!(any(target_os = "freebsd", target_os = "linux")) {
+        DIRECTORIES_LINUX
+    } else if cfg!(target_os = "macos") {
+        DIRECTORIES_MACOS
+    } else if cfg!(target_os = "windows") {
+        DIRECTORIES_WINDOWS
+    } else {
+        &[]
+    };
+
+    // Search the directories provided by the `libclang` directory patterns.
+    let mut options = MatchOptions::new();
+    options.case_sensitive = false;
+    options.require_literal_separator = true;
+    for directory in directories.iter().rev() {
+        if let Ok(directories) = glob::glob_with(directory, options) {
+            for directory in directories.filter_map(Result::ok).filter(|p| p.is_dir()) {
+                found.extend(search_directories(&directory, files));
+            }
+        }
+    }
+
+    found
+}
diff --git a/build/dynamic.rs b/build/dynamic.rs
new file mode 100644
index 0000000..2054ba0
--- /dev/null
+++ b/build/dynamic.rs
@@ -0,0 +1,244 @@
+// Copyright 2018 Kyle Mayes
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use std::env;
+use std::fs::File;
+use std::io::{self, Error, ErrorKind, Read, Seek, SeekFrom};
+use std::path::{Path, PathBuf};
+
+use super::common;
+
+/// Returns the ELF class from the ELF header in the supplied file.
+fn parse_elf_header(path: &Path) -> io::Result<u8> {
+    let mut file = File::open(path)?;
+    let mut buffer = [0; 5];
+    file.read_exact(&mut buffer)?;
+    if buffer[..4] == [127, 69, 76, 70] {
+        Ok(buffer[4])
+    } else {
+        Err(Error::new(ErrorKind::InvalidData, "invalid ELF header"))
+    }
+}
+
+/// Returns the magic number from the PE header in the supplied file.
+fn parse_pe_header(path: &Path) -> io::Result<u16> {
+    let mut file = File::open(path)?;
+
+    // Determine the header offset.
+    let mut buffer = [0; 4];
+    let start = SeekFrom::Start(0x3C);
+    file.seek(start)?;
+    file.read_exact(&mut buffer)?;
+    let offset = i32::from_le_bytes(buffer);
+
+    // Determine the validity of the header.
+    file.seek(SeekFrom::Start(offset as u64))?;
+    file.read_exact(&mut buffer)?;
+    if buffer != [80, 69, 0, 0] {
+        return Err(Error::new(ErrorKind::InvalidData, "invalid PE header"));
+    }
+
+    // Find the magic number.
+    let mut buffer = [0; 2];
+    file.seek(SeekFrom::Current(20))?;
+    file.read_exact(&mut buffer)?;
+    Ok(u16::from_le_bytes(buffer))
+}
+
+/// Validates the header for the supplied `libclang` shared library.
+fn validate_header(path: &Path) -> Result<(), String> {
+    if cfg!(any(target_os = "freebsd", target_os = "linux")) {
+        let class = parse_elf_header(path).map_err(|e| e.to_string())?;
+
+        if cfg!(target_pointer_width = "32") && class != 1 {
+            return Err("invalid ELF class (64-bit)".into());
+        }
+
+        if cfg!(target_pointer_width = "64") && class != 2 {
+            return Err("invalid ELF class (32-bit)".into());
+        }
+
+        Ok(())
+    } else if cfg!(target_os = "windows") {
+        let magic = parse_pe_header(path).map_err(|e| e.to_string())?;
+
+        if cfg!(target_pointer_width = "32") && magic != 267 {
+            return Err("invalid DLL (64-bit)".into());
+        }
+
+        if cfg!(target_pointer_width = "64") && magic != 523 {
+            return Err("invalid DLL (32-bit)".into());
+        }
+
+        Ok(())
+    } else {
+        Ok(())
+    }
+}
+
+/// Returns the components of the version in the supplied `libclang` shared
+// library filename.
+fn parse_version(filename: &str) -> Vec<u32> {
+    let version = if filename.starts_with("libclang.so.") {
+        &filename[12..]
+    } else if filename.starts_with("libclang-") {
+        &filename[9..filename.len() - 3]
+    } else {
+        return vec![];
+    };
+
+    version.split('.').map(|s| s.parse().unwrap_or(0)).collect()
+}
+
+/// Returns the paths to, the filenames, and the versions of the `libclang`
+// shared libraries.
+fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Vec<u32>)>, String> {
+    let mut files = vec![format!(
+        "{}clang{}",
+        env::consts::DLL_PREFIX,
+        env::consts::DLL_SUFFIX
+    )];
+
+    if cfg!(target_os = "linux") {
+        // Some Linux distributions don't create a `libclang.so` symlink, so we
+        // need to look for versioned files (e.g., `libclang-3.9.so`).
+        files.push("libclang-*.so".into());
+
+        // Some Linux distributions don't create a `libclang.so` symlink and
+        // don't have versioned files as described above, so we need to look for
+        // suffix versioned files (e.g., `libclang.so.1`). However, `ld` cannot
+        // link to these files, so this will only be included when linking at
+        // runtime.
+        if runtime {
+            files.push("libclang.so.*".into());
+            files.push("libclang-*.so.*".into());
+        }
+    }
+
+    if cfg!(any(
+        target_os = "openbsd",
+        target_os = "freebsd",
+        target_os = "netbsd"
+    )) {
+        // Some BSD distributions don't create a `libclang.so` symlink either,
+        // but use a different naming scheme for versioned files (e.g.,
+        // `libclang.so.7.0`).
+        files.push("libclang.so.*".into());
+    }
+
+    if cfg!(target_os = "windows") {
+        // The official LLVM build uses `libclang.dll` on Windows instead of
+        // `clang.dll`. However, unofficial builds such as MinGW use `clang.dll`.
+        files.push("libclang.dll".into());
+    }
+
+    // Validate the `libclang` shared libraries and collect the versions.
+    let mut valid = vec![];
+    let mut invalid = vec![];
+    for (directory, filename) in common::search_libclang_directories(&files, "LIBCLANG_PATH") {
+        let path = directory.join(&filename);
+        match validate_header(&path) {
+            Ok(()) => {
+                let version = parse_version(&filename);
+                valid.push((directory, filename, version))
+            }
+            Err(message) => invalid.push(format!("({}: {})", path.display(), message)),
+        }
+    }
+
+    if !valid.is_empty() {
+        return Ok(valid);
+    }
+
+    let message = format!(
+        "couldn't find any valid shared libraries matching: [{}], set the \
+         `LIBCLANG_PATH` environment variable to a path where one of these files \
+         can be found (invalid: [{}])",
+        files
+            .iter()
+            .map(|f| format!("'{}'", f))
+            .collect::<Vec<_>>()
+            .join(", "),
+        invalid.join(", "),
+    );
+
+    Err(message)
+}
+
+/// Returns the directory and filename of the "best" available `libclang` shared
+/// library.
+pub fn find(runtime: bool) -> Result<(PathBuf, String), String> {
+    search_libclang_directories(runtime)?
+        .iter()
+        .max_by_key(|f| &f.2)
+        .cloned()
+        .map(|(path, filename, _)| (path, filename))
+        .ok_or_else(|| "unreachable".into())
+}
+
+/// Find and link to `libclang` dynamically.
+#[cfg(not(feature = "runtime"))]
+pub fn link() {
+    use std::fs;
+
+    let (directory, filename) = find(false).unwrap();
+    println!("cargo:rustc-link-search={}", directory.display());
+
+    if cfg!(all(target_os = "windows", target_env = "msvc")) {
+        // Find the `libclang` stub static library required for the MSVC
+        // toolchain.
+        let lib = if !directory.ends_with("bin") {
+            directory
+        } else {
+            directory.parent().unwrap().join("lib")
+        };
+
+        if lib.join("libclang.lib").exists() {
+            println!("cargo:rustc-link-search={}", lib.display());
+        } else if lib.join("libclang.dll.a").exists() {
+            // MSYS and MinGW use `libclang.dll.a` instead of `libclang.lib`.
+            // It is linkable with the MSVC linker, but Rust doesn't recognize
+            // the `.a` suffix, so we need to copy it with a different name.
+            //
+            // FIXME: Maybe we can just hardlink or symlink it?
+            let out = env::var("OUT_DIR").unwrap();
+            fs::copy(
+                lib.join("libclang.dll.a"),
+                Path::new(&out).join("libclang.lib"),
+            )
+            .unwrap();
+            println!("cargo:rustc-link-search=native={}", out);
+        } else {
+            panic!(
+                "using '{}', so 'libclang.lib' or 'libclang.dll.a' must be \
+                 available in {}",
+                filename,
+                lib.display(),
+            );
+        }
+
+        println!("cargo:rustc-link-lib=dylib=libclang");
+    } else {
+        let name = filename.trim_start_matches("lib");
+
+        // Strip extensions and trailing version numbers (e.g., the `.so.7.0` in
+        // `libclang.so.7.0`).
+        let name = match name.find(".dylib").or_else(|| name.find(".so")) {
+            Some(index) => &name[0..index],
+            None => &name,
+        };
+
+        println!("cargo:rustc-link-lib=dylib={}", name);
+    }
+}
diff --git a/build/static.rs b/build/static.rs
new file mode 100644
index 0000000..bacd4ad
--- /dev/null
+++ b/build/static.rs
@@ -0,0 +1,136 @@
+// Copyright 2018 Kyle Mayes
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+extern crate glob;
+
+use std::path::{Path, PathBuf};
+
+use common;
+
+/// Returns the name of an LLVM or Clang library from a path to such a library.
+fn get_library_name(path: &Path) -> Option<String> {
+    path.file_stem().map(|p| {
+        let string = p.to_string_lossy();
+        if string.starts_with("lib") {
+            string[3..].to_owned()
+        } else {
+            string.to_string()
+        }
+    })
+}
+
+/// Returns the LLVM libraries required to link to `libclang` statically.
+fn get_llvm_libraries() -> Vec<String> {
+    common::run_llvm_config(&["--libs"])
+        .unwrap()
+        .split_whitespace()
+        .filter_map(|p| {
+            // Depending on the version of `llvm-config` in use, listed
+            // libraries may be in one of two forms, a full path to the library
+            // or simply prefixed with `-l`.
+            if p.starts_with("-l") {
+                Some(p[2..].into())
+            } else {
+                get_library_name(Path::new(p))
+            }
+        })
+        .collect()
+}
+
+/// Clang libraries required to link to `libclang` 3.5 and later statically.
+const CLANG_LIBRARIES: &[&str] = &[
+    "clang",
+    "clangAST",
+    "clangAnalysis",
+    "clangBasic",
+    "clangDriver",
+    "clangEdit",
+    "clangFrontend",
+    "clangIndex",
+    "clangLex",
+    "clangParse",
+    "clangRewrite",
+    "clangSema",
+    "clangSerialization",
+];
+
+/// Returns the Clang libraries required to link to `libclang` statically.
+fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> {
+    let pattern = directory
+        .as_ref()
+        .join("libclang*.a")
+        .to_string_lossy()
+        .to_string();
+    if let Ok(libraries) = glob::glob(&pattern) {
+        libraries
+            .filter_map(|l| l.ok().and_then(|l| get_library_name(&l)))
+            .collect()
+    } else {
+        CLANG_LIBRARIES.iter().map(|l| (*l).to_string()).collect()
+    }
+}
+
+/// Returns a directory containing `libclang` static libraries.
+fn find() -> PathBuf {
+    let name = if cfg!(target_os = "windows") {
+        "libclang.lib"
+    } else {
+        "libclang.a"
+    };
+
+    let files = common::search_libclang_directories(&[name.into()], "LIBCLANG_STATIC_PATH");
+    if let Some((directory, _)) = files.into_iter().nth(0) {
+        directory
+    } else {
+        panic!("could not find any static libraries");
+    }
+}
+
+/// Find and link to `libclang` statically.
+pub fn link() {
+    let directory = find();
+
+    // Specify required Clang static libraries.
+    println!("cargo:rustc-link-search=native={}", directory.display());
+    for library in get_clang_libraries(directory) {
+        println!("cargo:rustc-link-lib=static={}", library);
+    }
+
+    // Determine the shared mode used by LLVM.
+    let mode = common::run_llvm_config(&["--shared-mode"]).map(|m| m.trim().to_owned());
+    let prefix = if mode.map_or(false, |m| m == "static") {
+        "static="
+    } else {
+        ""
+    };
+
+    // Specify required LLVM static libraries.
+    println!(
+        "cargo:rustc-link-search=native={}",
+        common::run_llvm_config(&["--libdir"]).unwrap().trim_end()
+    );
+    for library in get_llvm_libraries() {
+        println!("cargo:rustc-link-lib={}{}", prefix, library);
+    }
+
+    // Specify required system libraries.
+    // MSVC doesn't need this, as it tracks dependencies inside `.lib` files.
+    if cfg!(target_os = "freebsd") {
+        println!("cargo:rustc-flags=-l ffi -l ncursesw -l c++ -l z");
+    } else if cfg!(target_os = "linux") {
+        println!("cargo:rustc-flags=-l ffi -l ncursesw -l stdc++ -l z");
+    } else if cfg!(target_os = "macos") {
+        println!("cargo:rustc-flags=-l ffi -l ncurses -l c++ -l z");
+    }
+}
