]> git.proxmox.com Git - cargo.git/blob - vendor/libssh2-sys/build.rs
New upstream version 0.52.0
[cargo.git] / vendor / libssh2-sys / build.rs
1 extern crate cc;
2 extern crate pkg_config;
3
4 #[cfg(target_env = "msvc")]
5 extern crate vcpkg;
6
7 use std::env;
8 use std::fs;
9 use std::path::{Path, PathBuf};
10 use std::process::Command;
11
12 fn main() {
13 let zlib_ng_compat = env::var("CARGO_FEATURE_ZLIB_NG_COMPAT").is_ok();
14
15 if !zlib_ng_compat && try_vcpkg() {
16 return;
17 }
18
19 // The system copy of libssh2 is not used by default because it
20 // can lead to having two copies of libssl loaded at once.
21 // See https://github.com/alexcrichton/ssh2-rs/pull/88
22 println!("cargo:rerun-if-env-changed=LIBSSH2_SYS_USE_PKG_CONFIG");
23 if true {
24 if zlib_ng_compat {
25 panic!("LIBSSH2_SYS_USE_PKG_CONFIG set, but cannot use zlib-ng-compat with system libssh2");
26 }
27 if let Ok(lib) = pkg_config::find_library("libssh2") {
28 for path in &lib.include_paths {
29 println!("cargo:include={}", path.display());
30 }
31 return;
32 }
33 }
34
35 if false {
36 let _ = Command::new("git")
37 .args(&["submodule", "update", "--init"])
38 .status();
39 }
40
41 let target = env::var("TARGET").unwrap();
42 let profile = env::var("PROFILE").unwrap();
43 let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
44 let mut cfg = cc::Build::new();
45
46 let include = dst.join("include");
47 println!("cargo:include={}", include.display());
48 println!("cargo:root={}", dst.display());
49 let build = dst.join("build");
50 cfg.out_dir(&build);
51 fs::create_dir_all(&build).unwrap();
52 fs::create_dir_all(&include).unwrap();
53
54 fs::copy("libssh2/include/libssh2.h", include.join("libssh2.h")).unwrap();
55 fs::copy(
56 "libssh2/include/libssh2_publickey.h",
57 include.join("libssh2_publickey.h"),
58 )
59 .unwrap();
60 fs::copy(
61 "libssh2/include/libssh2_sftp.h",
62 include.join("libssh2_sftp.h"),
63 )
64 .unwrap();
65
66 cfg.file("libssh2/src/agent.c")
67 .file("libssh2/src/bcrypt_pbkdf.c")
68 .file("libssh2/src/blowfish.c")
69 .file("libssh2/src/channel.c")
70 .file("libssh2/src/comp.c")
71 .file("libssh2/src/crypt.c")
72 .file("libssh2/src/global.c")
73 .file("libssh2/src/hostkey.c")
74 .file("libssh2/src/keepalive.c")
75 .file("libssh2/src/kex.c")
76 .file("libssh2/src/knownhost.c")
77 .file("libssh2/src/mac.c")
78 .file("libssh2/src/misc.c")
79 .file("libssh2/src/packet.c")
80 .file("libssh2/src/pem.c")
81 .file("libssh2/src/publickey.c")
82 .file("libssh2/src/scp.c")
83 .file("libssh2/src/session.c")
84 .file("libssh2/src/sftp.c")
85 .file("libssh2/src/transport.c")
86 .file("libssh2/src/userauth.c")
87 .include(&include)
88 .include("libssh2/src");
89
90 cfg.define("HAVE_LONGLONG", None);
91
92 if target.contains("windows") {
93 cfg.include("libssh2/win32");
94 cfg.define("LIBSSH2_WINCNG", None);
95 cfg.define("LIBSSH2_WIN32", None);
96 cfg.file("libssh2/src/wincng.c");
97 } else {
98 cfg.flag("-fvisibility=hidden");
99 cfg.define("HAVE_SNPRINTF", None);
100 cfg.define("HAVE_UNISTD_H", None);
101 cfg.define("HAVE_INTTYPES_H", None);
102 cfg.define("HAVE_STDLIB_H", None);
103 cfg.define("HAVE_SYS_SELECT_H", None);
104 cfg.define("HAVE_SYS_SOCKET_H", None);
105 cfg.define("HAVE_SYS_IOCTL_H", None);
106 cfg.define("HAVE_SYS_TIME_H", None);
107 cfg.define("HAVE_SYS_UN_H", None);
108 cfg.define("HAVE_O_NONBLOCK", None);
109 cfg.define("LIBSSH2_OPENSSL", None);
110 cfg.define("HAVE_LIBCRYPT32", None);
111 cfg.define("HAVE_EVP_AES_128_CTR", None);
112 cfg.define("HAVE_POLL", None);
113 cfg.define("HAVE_GETTIMEOFDAY", None);
114
115 cfg.file("libssh2/src/openssl.c");
116
117 // Create `libssh2_config.h`
118 let config = fs::read_to_string("libssh2/src/libssh2_config_cmake.h.in").unwrap();
119 let config = config
120 .lines()
121 .filter(|l| !l.contains("#cmakedefine"))
122 .collect::<Vec<_>>()
123 .join("\n");
124 fs::write(build.join("libssh2_config.h"), &config).unwrap();
125 cfg.include(&build);
126 }
127
128 /* Enable newer diffie-hellman-group-exchange-sha1 syntax */
129 cfg.define("LIBSSH2_DH_GEX_NEW", None);
130
131 cfg.define("LIBSSH2_HAVE_ZLIB", None);
132
133 if profile.contains("debug") {
134 cfg.define("LIBSSH2DEBUG", None);
135 }
136
137 println!("cargo:rerun-if-env-changed=DEP_Z_INCLUDE");
138 if let Some(path) = env::var_os("DEP_Z_INCLUDE") {
139 cfg.include(path);
140 }
141
142 println!("cargo:rerun-if-env-changed=DEP_OPENSSL_INCLUDE");
143 if let Some(path) = env::var_os("DEP_OPENSSL_INCLUDE") {
144 if let Some(path) = env::split_paths(&path).next() {
145 if let Some(path) = path.to_str() {
146 if path.len() > 0 {
147 cfg.include(path);
148 }
149 }
150 }
151 }
152
153 let libssh2h = fs::read_to_string("libssh2/include/libssh2.h").unwrap();
154 let version_line = libssh2h
155 .lines()
156 .find(|l| l.contains("LIBSSH2_VERSION"))
157 .unwrap();
158 let version = &version_line[version_line.find('"').unwrap() + 1..version_line.len() - 1];
159
160 let pkgconfig = dst.join("lib/pkgconfig");
161 fs::create_dir_all(&pkgconfig).unwrap();
162 fs::write(
163 pkgconfig.join("libssh2.pc"),
164 fs::read_to_string("libssh2/libssh2.pc.in")
165 .unwrap()
166 .replace("@prefix@", dst.to_str().unwrap())
167 .replace("@exec_prefix@", "")
168 .replace("@libdir@", dst.join("lib").to_str().unwrap())
169 .replace("@includedir@", include.to_str().unwrap())
170 .replace("@LIBS@", "")
171 .replace("@LIBSREQUIRED@", "")
172 .replace("@LIBSSH2VER@", version),
173 )
174 .unwrap();
175
176 cfg.warnings(false);
177 cfg.compile("ssh2");
178
179 if target.contains("windows") {
180 println!("cargo:rustc-link-lib=bcrypt");
181 println!("cargo:rustc-link-lib=crypt32");
182 println!("cargo:rustc-link-lib=user32");
183 println!("cargo:rustc-link-lib=ntdll");
184 }
185 }
186
187 #[cfg(not(target_env = "msvc"))]
188 fn try_vcpkg() -> bool {
189 false
190 }
191
192 #[cfg(target_env = "msvc")]
193 fn try_vcpkg() -> bool {
194 vcpkg::Config::new()
195 .emit_includes(true)
196 .probe("libssh2")
197 .map(|_| {
198 // found libssh2 which depends on openssl and zlib
199 vcpkg::Config::new()
200 .lib_name("libssl")
201 .lib_name("libcrypto")
202 .probe("openssl")
203 .or_else(|_| {
204 // openssl 1.1 was not found, try openssl 1.0
205 vcpkg::Config::new()
206 .lib_name("libeay32")
207 .lib_name("ssleay32")
208 .probe("openssl")
209 })
210 .expect(
211 "configured libssh2 from vcpkg but could not \
212 find openssl libraries that it depends on",
213 );
214
215 vcpkg::Config::new()
216 .lib_names("zlib", "zlib1")
217 .probe("zlib")
218 .expect(
219 "configured libssh2 from vcpkg but could not \
220 find the zlib library that it depends on",
221 );
222
223 println!("cargo:rustc-link-lib=crypt32");
224 println!("cargo:rustc-link-lib=gdi32");
225 println!("cargo:rustc-link-lib=user32");
226 })
227 .is_ok()
228 }