Skip to content
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

Cargo build #1296

Merged
merged 5 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
build: make cargo build work
  • Loading branch information
piscisaureus committed Dec 19, 2018
commit 73e80b0763cf2e14f7dc26d679d3b457106597cc
7 changes: 2 additions & 5 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ clone_depth: 1

environment:
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CARGO_TARGET_DIR: $(APPVEYOR_BUILD_FOLDER)\target
DENO_BUILD_MODE: release
DENO_BUILD_PATH: $(APPVEYOR_BUILD_FOLDER)\out\release
DENO_BUILD_PATH: $(APPVEYOR_BUILD_FOLDER)\target\release
DENO_THIRD_PARTY_PATH: $(APPVEYOR_BUILD_FOLDER)\third_party
MTIME_CACHE_DB: $(APPVEYOR_BUILD_FOLDER)\mtime_cache.xml
RELEASE_ARTIFACT: deno_win_x64.zip
Expand Down Expand Up @@ -239,7 +238,6 @@ cache:
# Cache file mtimes in the main git repo, also to enable incremental builds.
- $(MTIME_CACHE_DB)
# Build incrementally.
- $(CARGO_TARGET_DIR)
- $(DENO_BUILD_PATH)

init:
Expand Down Expand Up @@ -328,7 +326,6 @@ install:
before_build:
# Mark all files in the build dir 'not needed' until proven otherwise.
# TODO: also track files in third_party that aren't checked into the repo.
# TODO: also track files in $CARGO_TARGET_DIR.
- ps: Start-TraceFilesNeeded $env:DENO_BUILD_PATH -Recurse

# Download clang and gn, generate ninja files.
Expand All @@ -346,7 +343,7 @@ before_build:
build_script:
- python tools\build.py
- ps: Set-FilesNeeded -Auto -Reason "Build finished"
- cargo check --release
- cargo build -vv --release
- ps: Set-FilesNeeded -Auto -Reason "Cargo check finished"

test_script:
Expand Down
4 changes: 2 additions & 2 deletions .gn
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ default_args = {
# for now. See https://clang.llvm.org/docs/ControlFlowIntegrity.html
is_cfi = false

# Disabled due to CRT linking problems in Windows when using prebuilt V8.
# Works in other configurations.
# TODO(ry) Remove this so debug builds can link faster. Currently removing
# this breaks cargo build in debug mode in OSX.
is_component_build = false
ry marked this conversation as resolved.
Show resolved Hide resolved

# Enable Jumbo build for a faster build.
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ script:

- |-
# Cargo check
cargo check -j2 --release --locked
cargo build --release -vv -j2

before_deploy:
- gzip -c target/release/deno > target/release/deno_${TRAVIS_OS_NAME}_x64.gz
Expand Down
9 changes: 2 additions & 7 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ group("default") {
]
}

# Set of targets that need to be built for `cargo check` to succeed.
group("cargo_check_deps") {
deps = [
":msg_rs",
]
}

main_extern = [
"$rust_build:atty",
"$rust_build:dirs",
Expand Down Expand Up @@ -112,6 +105,8 @@ ts_sources = [
"third_party/yarn.lock",
]

# When Cargo is driving the build, GN/Ninja are used to produce these non-Rust
# targets. Cargo handles all Rust source files and the final linking step.
group("deno_deps") {
deps = [
":msg_rs",
Expand Down
88 changes: 49 additions & 39 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,23 @@ use std::path::{self, Path, PathBuf};
use std::process::Command;

fn main() {
// Cargo sets PROFILE to either "debug" or "release", which conveniently
// matches the build modes we support.
let mode = env::var("PROFILE").unwrap();

let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = env::current_dir().unwrap().join(out_dir);

// Normally we configure GN+Ninja to build into Cargo's OUT_DIR.
// However, when DENO_BUILD_PATH is set, perform the ninja build in that dir
// instead. This is used by CI to avoid building V8 etc twice.
let gn_out_dir = match env::var_os("DENO_BUILD_PATH") {
None => {
// out_dir looks like: "target/debug/build/deno-26d2b5325de0f0cf/out"
// The gn build is "target/debug"
// So we go up two directories. Blame cargo for these hacks.
let d = out_dir.parent().unwrap();
let d = d.parent().unwrap();
let d = d.parent().unwrap();
PathBuf::from(d)
}
Some(deno_build_path) => PathBuf::from(deno_build_path),
let gn_mode = if cfg!(target_os = "windows") {
// On Windows, we need to link with a release build of libdeno, because
// rust always uses the release CRT.
// TODO(piscisaureus): make linking with debug libdeno possible.
String::from("release")
} else {
// Cargo sets PROFILE to either "debug" or "release", which conveniently
// matches the build modes we support.
env::var("PROFILE").unwrap()
};

// Give cargo some instructions. We do this first so the `rerun-if-*-changed`
// directives can take effect even if something the build itself fails.
println!("cargo:rustc-env=GN_OUT_DIR={}", normalize_path(&gn_out_dir));
println!(
"cargo:rustc-link-search=native={}/obj",
normalize_path(&gn_out_dir)
);
println!("cargo:rustc-link-lib=static=deno_deps");
let gn_out_dir = env::current_dir().unwrap();
let gn_out_dir = gn_out_dir.join(format!("target/{}", gn_mode));
let gn_out_dir = normalize_path(gn_out_dir);

// Tell Cargo when to re-run this file. We do this first, so these directives
// can take effect even if something goes wrong later in the build process.
println!("cargo:rerun-if-env-changed=DENO_BUILD_PATH");
// TODO: this is obviously not appropriate here.
println!("cargo:rerun-if-env-changed=APPVEYOR_REPO_COMMIT");
Expand All @@ -55,29 +40,53 @@ fn main() {
.map(|s| s.starts_with("rls"))
.unwrap_or(false);

// If we're being invoked by the RLS, build only the targets that are needed
// for `cargo check` to succeed.
let gn_target = if check_only {
"cargo_check_deps"
} else {
"deno_deps"
};
// This helps Rust source files locate the snapshot, source map etc.
println!("cargo:rustc-env=GN_OUT_DIR={}", gn_out_dir);

let gn_target;

if check_only {
// When RLS is running "cargo check" to analyze the source code, we're not
// trying to build a working executable, rather we're just compiling all
// rust code. Therefore, make ninja build only 'msg_generated.rs'.
gn_target = "msg_rs";

// Enable the 'check_only' feature, which enables some workarounds in the
// rust source code to compile successfully without a bundle and snapshot
println!("cargo:rustc-cfg=feature=\"check-only\"");
} else {
// "Full" (non-RLS) build.
gn_target = "deno_deps";

// Link with libdeno.a/.lib, which includes V8.
println!("cargo:rustc-link-search=native={}/obj/libdeno", gn_out_dir);
if cfg!(target_os = "windows") {
println!("cargo:rustc-link-lib=static=libdeno");
} else {
println!("cargo:rustc-link-lib=static=deno");
}

// Link the system libraries that libdeno and V8 depend on.
if cfg!(any(target_os = "macos", target_os = "freebsd")) {
println!("cargo:rustc-link-lib=dylib=c++");
} else if cfg!(target_os = "windows") {
for lib in vec!["dbghelp", "shlwapi", "winmm", "ws2_32"] {
println!("cargo:rustc-link-lib={}", lib);
}
}
}

let status = Command::new("python")
.env("DENO_BUILD_PATH", &gn_out_dir)
.env("DENO_BUILD_MODE", &mode)
.env("DENO_BUILD_MODE", &gn_mode)
.arg("./tools/setup.py")
.status()
.expect("setup.py failed");
assert!(status.success());

let status = Command::new("python")
.env("DENO_BUILD_PATH", &gn_out_dir)
.env("DENO_BUILD_MODE", &mode)
.env("DENO_BUILD_MODE", &gn_mode)
.arg("./tools/build.py")
.arg(gn_target)
.arg("-v")
Expand All @@ -88,8 +97,9 @@ fn main() {

// Utility function to make a path absolute, normalizing it to use forward
// slashes only. The returned value is an owned String, otherwise panics.
fn normalize_path(path: &Path) -> String {
fn normalize_path<T: AsRef<Path>>(path: T) -> String {
path
.as_ref()
.to_str()
.unwrap()
.to_owned()
Expand Down
27 changes: 21 additions & 6 deletions libdeno/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,37 @@ config("deno_config") {
}
}

v8_static_library("v8") {
public_deps = [
"//build/win:default_exe_manifest",
# The `/Zl` ("omit default library name") flag makes the compiler produce object
# files that can link with both static and dynamic libc.
config("win_crt_agnostic") {
piscisaureus marked this conversation as resolved.
Show resolved Hide resolved
if (is_win) {
cflags = [ "/Zl" ]
}
}
piscisaureus marked this conversation as resolved.
Show resolved Hide resolved

v8_source_set("v8") {
configs = [
":deno_config",
":win_crt_agnostic",
]
deps = [
"//third_party/v8:v8",
"//third_party/v8:v8_libbase",
"//third_party/v8:v8_libplatform",
"//third_party/v8:v8_libsampler",
]
configs = [ ":deno_config" ]
}

# Only functionality needed for libdeno_test and snapshot_creator
# In particular no flatbuffers, no assets, no rust, no msg handlers.
# Because snapshots are slow, it's important that snapshot_creator's
# dependencies are minimal.
# The cargo-driven build links with libdeno to pull in all non-rust code.
v8_static_library("libdeno") {
configs = [ ":deno_config" ]
configs = [
":deno_config",
":win_crt_agnostic",
]
sources = [
"api.cc",
"binding.cc",
Expand All @@ -41,8 +55,9 @@ v8_static_library("libdeno") {
"file_util.h",
"internal.h",
]
public_deps = [
deps = [
":v8",
"//build/config:shared_library_deps",
]
}

Expand Down