Skip to content

Commit

Permalink
Native MSVC windows build, convert to cmake
Browse files Browse the repository at this point in the history
  • Loading branch information
vvuk committed Aug 17, 2016
1 parent fc7053e commit 5bbec74
Show file tree
Hide file tree
Showing 17 changed files with 394 additions and 73 deletions.
2 changes: 1 addition & 1 deletion components/gfx/Cargo.toml
Expand Up @@ -57,7 +57,7 @@ core-foundation = "0.2"
core-graphics = "0.4"
core-text = "2.0"

[target.'cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))'.dependencies]
[target.'cfg(any(target_os = "linux", target_os = "android", all(target_os = "windows", target_env = "gnu")))'.dependencies]
freetype = {git = "https://github.com/servo/rust-freetype"}
servo-fontconfig = "0.2.1"

Expand Down
4 changes: 2 additions & 2 deletions components/gfx/lib.rs
Expand Up @@ -37,9 +37,9 @@ extern crate euclid;
extern crate fnv;

// Platforms that use Freetype/Fontconfig library dependencies
#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
#[cfg(any(target_os = "linux", target_os = "android", all(target_os = "windows", target_env = "gnu")))]
extern crate fontconfig;
#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
#[cfg(any(target_os = "linux", target_os = "android", all(target_os = "windows", target_env = "gnu")))]
extern crate freetype;

extern crate gfx_traits;
Expand Down
80 changes: 80 additions & 0 deletions components/gfx/platform/dummy/font.rs
@@ -0,0 +1,80 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use app_units::Au;
use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::{FontTableTag, FractionalPixel};
use platform::font_context::FontContextHandle;
use platform::font_template::FontTemplateData;
use std::sync::Arc;
use style::computed_values::{font_stretch, font_weight};
use text::glyph::GlyphId;

#[derive(Debug)]
pub struct FontTable {
buffer: Vec<u8>,
}

impl FontTableMethods for FontTable {
fn buffer(&self) -> &[u8] {
&self.buffer
}
}

#[derive(Debug)]
pub struct FontHandle {
handle: FontContextHandle,
}

impl Drop for FontHandle {
fn drop(&mut self) {
}
}

impl FontHandleMethods for FontHandle {
fn new_from_template(fctx: &FontContextHandle,
template: Arc<FontTemplateData>,
pt_size: Option<Au>)
-> Result<FontHandle, ()> {
Err(())
}

fn template(&self) -> Arc<FontTemplateData> {
unimplemented!()
}
fn family_name(&self) -> String {
String::from("Unknown")
}
fn face_name(&self) -> String {
String::from("Unknown")
}
fn is_italic(&self) -> bool {
false
}
fn boldness(&self) -> font_weight::T {
font_weight::T::Weight400
}
fn stretchiness(&self) -> font_stretch::T {
font_stretch::T::normal
}
fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
None
}
fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId)
-> FractionalPixel {
0.0
}
fn can_do_fast_shaping(&self) -> bool {
false
}
fn glyph_h_advance(&self, glyph: GlyphId) -> Option<FractionalPixel> {
None
}
fn metrics(&self) -> FontMetrics {
unimplemented!()
}
fn table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
None
}
}
13 changes: 13 additions & 0 deletions components/gfx/platform/dummy/font_context.rs
@@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[derive(Clone, HeapSizeOf, Debug)]
pub struct FontContextHandle;

impl FontContextHandle {
pub fn new() -> FontContextHandle {
FontContextHandle
}
}

24 changes: 24 additions & 0 deletions components/gfx/platform/dummy/font_list.rs
@@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

pub fn for_each_available_family<F>(mut callback: F) where F: FnMut(String)
{
}

pub fn for_each_variation<F>(family_name: &str, mut callback: F)
where F: FnMut(String)
{
}

pub fn system_default_family(generic_name: &str) -> Option<String> {
None
}

pub fn last_resort_font_families() -> Vec<String> {
vec!(
"Unknown".to_owned()
)
}

pub static SANS_SERIF_FONT_FAMILY: &'static str = "Unknown";
39 changes: 39 additions & 0 deletions components/gfx/platform/dummy/font_template.rs
@@ -0,0 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use string_cache::Atom;
use webrender_traits::NativeFontHandle;

#[derive(Deserialize, Serialize, Debug)]
pub struct FontTemplateData {
pub bytes: Vec<u8>,
pub identifier: Atom,
}

impl FontTemplateData {
pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> FontTemplateData {
let bytes = match font_data {
Some(bytes) => {
bytes
},
None => {
unimplemented!()
}
};

FontTemplateData {
bytes: bytes,
identifier: identifier,
}
}
pub fn bytes(&self) -> Vec<u8> {
self.bytes.clone()
}
pub fn bytes_if_in_memory(&self) -> Option<Vec<u8>> {
Some(self.bytes())
}
pub fn native_font(&self) -> Option<NativeFontHandle> {
None
}
}
15 changes: 13 additions & 2 deletions components/gfx/platform/mod.rs
Expand Up @@ -2,13 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
#[cfg(any(target_os = "linux", target_os = "android", all(target_os = "windows", target_env = "gnu")))]
pub use platform::freetype::{font, font_context, font_list, font_template};

#[cfg(target_os = "macos")]
pub use platform::macos::{font, font_context, font_list, font_template};

#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
#[cfg(all(target_os = "windows", target_env = "msvc"))]
pub use platform::dummy::{font, font_context, font_list, font_template};

#[cfg(any(target_os = "linux", target_os = "android", all(target_os = "windows", target_env = "gnu")))]
mod freetype {
use libc::c_char;
use std::ffi::CStr;
Expand All @@ -33,3 +36,11 @@ mod macos {
pub mod font_list;
pub mod font_template;
}

#[cfg(all(target_os = "windows", target_env = "msvc"))]
mod dummy {
pub mod font;
pub mod font_context;
pub mod font_list;
pub mod font_template;
}
102 changes: 102 additions & 0 deletions components/script/CMakeLists.txt
@@ -0,0 +1,102 @@
project(script)
cmake_minimum_required(VERSION 2.6)

set(DUMMY ${CMAKE_BUILD_TYPE})

FUNCTION(PREPEND var prefix)
SET(listVar "")
FOREACH(f ${ARGN})
LIST(APPEND listVar "${prefix}/${f}")
ENDFOREACH(f)
SET(${var} "${listVar}" PARENT_SCOPE)
ENDFUNCTION(PREPEND)

set(bindings_src ${PROJECT_SOURCE_DIR}/dom/bindings/codegen)
set(webidls_src ${PROJECT_SOURCE_DIR}/dom/webidls)

# Without Bindings/* stuff, since we install that separately below
set(globalgen_base_src
PrototypeList.rs
RegisterBindings.rs
InterfaceObjectMap.rs
InterfaceTypes.rs
InheritTypes.rs
UnionTypes.rs
)

set(globalgen_src
${globalgen_base_src}
Bindings/mod.rs
)

file(GLOB_RECURSE webidls ${webidls_src}/*.webidl)
string(REGEX REPLACE ";" "\n" webidl_filelist "${webidls}")
file(WRITE "${PROJECT_BINARY_DIR}/webidls.list" "${webidl_filelist}")
string(REGEX REPLACE "\\.webidl(;|$)" "\\1" bindings "${webidls}")
string(REGEX REPLACE "(^|;)${webidls_src}/" "\\1" bindings "${bindings}")

set(globalgen_deps
${bindings_src}/GlobalGen.py
${bindings_src}/Bindings.conf
${bindings_src}/Configuration.py
${bindings_src}/CodegenRust.py
${bindings_src}/parser/WebIDL.py
)
set(bindinggen_deps
${bindings_src}/BindingGen.py
${bindings_src}/Bindings.conf
${bindings_src}/Configuration.py
${bindings_src}/CodegenRust.py
${bindings_src}/parser/WebIDL.py
)

add_custom_command(
OUTPUT Bindings
COMMAND ${CMAKE_COMMAND} -E make_directory Bindings
)
add_custom_command(
OUTPUT _cache
COMMAND ${CMAKE_COMMAND} -E make_directory _cache
)

add_custom_command(
OUTPUT ParserResults.pkl
COMMAND python -B ${bindings_src}/pythonpath.py -I ${bindings_src}/parser -I ${bindings_src}/ply
${bindings_src}/GlobalGen.py
--cachedir=_cache
--filelist=webidls.list
${bindings_src}/Bindings.conf
.
${PROJECT_SOURCE_DIR}
DEPENDS Bindings _cache ${globalgen_deps} ${webidls}
VERBATIM
)

# We need an intermediate custom target for this, due to this misfeature:
# > If any dependency is an OUTPUT of another custom command in the same
# > directory CMake automatically brings the other custom command into the
# > target in which this command is built.
# So, depending directly on ParserResults.pkl from the add_custom_command
# below would cause GlobalGen.py to be executed each time.
add_custom_target(ParserResults ALL DEPENDS ParserResults.pkl)
add_custom_target(generate-bindings ALL)

foreach(binding IN LISTS bindings)
add_custom_command(
OUTPUT Bindings/${binding}Binding.rs
COMMAND python -B ${bindings_src}/pythonpath.py -I ${bindings_src}/parser -I ${bindings_src}/ply
${bindings_src}/BindingGen.py
${bindings_src}/Bindings.conf
.
Bindings/${binding}Binding
${webidls_src}/${binding}.webidl
DEPENDS Bindings ${bindinggen_deps} ${webidls_src}/${binding}.webidl ParserResults
VERBATIM
)
add_custom_target(${binding} DEPENDS Bindings/${binding}Binding.rs)
add_dependencies(generate-bindings ${binding})
endforeach()

PREPEND(globalgen_out ${CMAKE_BINARY_DIR}/ ${globalgen_base_src})
install(FILES ${globalgen_out} DESTINATION .)
install(DIRECTORY ${CMAKE_BINARY_DIR}/Bindings/ DESTINATION Bindings)
3 changes: 3 additions & 0 deletions components/script/Cargo.toml
Expand Up @@ -14,6 +14,9 @@ path = "lib.rs"
[features]
debugmozjs = ['js/debugmozjs']

[build-dependencies]
cmake = "0.1"

[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies]
tinyfiledialogs = {git = "https://github.com/jdm/tinyfiledialogs"}

Expand Down
33 changes: 26 additions & 7 deletions components/script/build.rs
Expand Up @@ -2,17 +2,36 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate cmake;
use std::env;
use std::process::Command;
use std::time::Instant;

fn main() {
let start = Instant::now();
let num_jobs = env::var("NUM_JOBS").unwrap();
assert!(Command::new("make")
.args(&["-f", "makefile.cargo", "-j", &num_jobs])
.status()
.unwrap()
.success());

// This must use the Ninja generator -- it's the only one that
// parallelizes cmake's output properly. (Cmake generates
// separate makefiles, each of which try to build
// ParserResults.pkl, and then stomp on eachother.)
let mut build = cmake::Config::new(".");

let target = env::var("TARGET").unwrap();
if target.contains("windows-msvc") {
// We must use Ninja on Windows for this -- msbuild is painfully slow,
// and ninja is easier to install than make.
build.generator("Ninja");
// because we're using ninja, we need to explicitly set these
// to VC++, otherwise it'll try to use cc
build.define("CMAKE_C_COMPILER", "cl.exe")
.define("CMAKE_CXX_COMPILER", "cl.exe");
// We have to explicitly specify the full path to link.exe,
// for reasons that I don't understand. If we just give
// link.exe, it tries to use script-*/out/link.exe, which of
// course does not exist.
build.define("CMAKE_LINKER", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe");
}

build.build();

println!("Binding generation completed in {}s", start.elapsed().as_secs());
}
7 changes: 6 additions & 1 deletion components/script/dom/bindings/codegen/GlobalGen.py
Expand Up @@ -34,6 +34,8 @@ def main():
help="Directory in which to cache lex/parse tables.")
o.add_option("--only-html", dest='only_html', action="store_true",
help="Only generate HTML from WebIDL inputs")
o.add_option("--filelist", dest='filelist', default=None,
help="A file containing the list (one per line) of webidl files to process.")
(options, args) = o.parse_args()

if len(args) < 2:
Expand All @@ -42,7 +44,10 @@ def main():
configFile = args[0]
outputdir = args[1]
baseDir = args[2]
fileList = args[3:]
if options.filelist is not None:
fileList = (l.strip() for l in open(options.filelist).xreadlines())
else:
fileList = args[3:]

# Parse the WebIDL.
parser = WebIDL.Parser(options.cachedir)
Expand Down

0 comments on commit 5bbec74

Please sign in to comment.