forked from cyndis/qmlrs
-
Notifications
You must be signed in to change notification settings - Fork 2
/
build.rs
161 lines (136 loc) · 5.93 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
extern crate pkg_config;
use std::process::Command;
use std::fs;
use std::path::Path;
use std::env;
use std::env::consts;
use std::path::PathBuf;
use std::str::FromStr;
fn main() {
let debug = bool::from_str(&env::var("DEBUG").unwrap_or("false".to_string())).unwrap_or(false);
let wcd = env::current_dir().unwrap();
let build = PathBuf::from(&wcd.join("ext/libqmlrswrapper/build"));
let _ = fs::remove_dir_all(&build);
let _ = fs::create_dir_all(&build);
/*
* Support Qt installed via the Ports system on BSD-like systems.
*
* The native libs are in `/usr/local/lib`, which is not linked against by default.
* This means that either the user or every package has to add this if they want to link
* against something that is not part of the core distribution in `/usr/lib`.
*
* See https://wiki.freebsd.org/WarnerLosh/UsrLocal for the line of reasoning & how this will
* change in the future.
*/
if cfg!(any(target_os = "freebsd", target_os = "openbsd", target_os = "netbsd",
target_os = "dragonfly", target_os = "bitrig")) {
println!("cargo:rustc-link-search=native=/usr/local/lib");
}
/*
* Parameters for supporting QT on OS X
*
* Because QT5 conflicts with QT4 the homebrew package manager won't link
* the QT5 package into the default search paths for libraries, to deal
* with this we need to give pkg-config and cmake a nudge in the right
* direction.
*/
if cfg!(target_os = "macos") {
// We use the QTDIR or QTDIR64 env variables to find the location of
// Qt5. If these are not set, we use the default homebrew install
// location.
let qtdir_variable = match consts::ARCH {
"x86_64" => "QTDIR64",
_ => "QTDIR",
};
let mut qt5_lib_path = PathBuf::new();
qt5_lib_path.push(env::var(qtdir_variable).unwrap_or(String::from("/usr/local/opt/qt5")));
qt5_lib_path.push(Path::new("lib"));
if qt5_lib_path.exists() {
// First nudge cmake in the direction of the .cmake files added by
// homebrew. This clobbers the existing value if present, it's
// unlikely to be present though.
env::set_var("CMAKE_PREFIX_PATH", qt5_lib_path.join("cmake"));
// Nudge pkg-config in the direction of the brewed QT to ensure the
// correct compiler flags get found for the project.
env::set_var("PKG_CONFIG_PATH", qt5_lib_path.join("pkgconfig"));
} else {
panic!("QT5 was not found at the expected location ({}) please install it via homebrew, or set the {} env variable.",
qt5_lib_path.display(), qtdir_variable);
}
}
let mut myargs = vec![];
if debug {
myargs.push("-DCMAKE_BUILD_TYPE=Debug");
} else {
myargs.push("-DCMAKE_BUILD_TYPE=Release");
}
if cfg!(windows) {
let is_msys = env::var("MSYSTEM").is_ok();
if is_msys {
myargs.push("-GMSYS Makefiles");
} else {
myargs.push("-GVisual Studio 12 2013 Win64");
}
myargs.push("..");
} else {
myargs.push("..");
}
let cmake_output = Command::new("cmake").args(&myargs).current_dir(&build).output().unwrap_or_else(|e| {
panic!("Failed to run cmake: {}", e);
});
let cmake_stderr = String::from_utf8(cmake_output.stderr).unwrap();
if !cmake_stderr.is_empty() {
// Check for nvidia issue
check_qt_egl_reference_error(cmake_stderr.clone());
panic!("cmake produced stderr: {}", cmake_stderr);
}
myargs = vec!["--build",".","--config"];
if debug {
myargs.push("Debug");
} else {
myargs.push("Release");
}
Command::new("cmake")
.args(&myargs)
.current_dir(&build)
.status().and_then(|x| Ok(x.success()) ).unwrap_or_else(|e| {
panic!("Failed to run build: {}", e);
});
println!("cargo:rustc-link-lib=static=qmlrswrapper");
if cfg!(windows) {
println!("cargo:rustc-link-search=native={}\\system32",env::var("WINDIR").unwrap());
if debug {
println!("cargo:rustc-link-search=native={}\\Debug",build.display());
} else {
println!("cargo:rustc-link-search=native={}\\Release",build.display());
}
println!("cargo:rustc-link-search=native={}\\lib",env::var("QTDIR").unwrap());
println!("cargo:rustc-link-lib=dylib=Qt5Core");
println!("cargo:rustc-link-lib=dylib=Qt5Gui");
println!("cargo:rustc-link-lib=dylib=Qt5Qml");
println!("cargo:rustc-link-lib=dylib=Qt5Quick");
println!("cargo:rustc-link-lib=dylib=Qt5Svg");
} else {
println!("cargo:rustc-link-search=native={}",build.display());
println!("cargo:rustc-link-lib=dylib=stdc++");
pkg_config::find_library("Qt5Core Qt5Gui Qt5Qml Qt5Quick Qt5Svg").unwrap();
}
}
// This function checks for a special, more confusing, case of cmake failure.
// Nvidia installer creates a faulty set of symbolic links that confuse the Qt
// compilation process, we directly check the error message rather than checking
// the library paths so we can ensure we're tracking the exact issue.
fn check_qt_egl_reference_error(err_str: String) {
let error_preface = "The imported target \"Qt5::Gui\" references the file";
// Check if we have both the error preface
if err_str.contains(error_preface) &&
// .. and we include libGL in the error message
(err_str.contains("libEGL.so") || err_str.contains("libGL.so")) {
println!("It appears cmake has failed to build because of a bad symlink
to libEGL.so or libGL.so, this error typically occurs because the NVidia
installer fails to to repair the links to existing libGL bindings --
remove the bad symbolic link (typically located at /usr/lib64/libGL.so)
and ensure that you have a symbolic link to an existing copy of both
libraries .");
}
}