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

Use environment variables in build script instead of cfg directives #54

Merged
merged 1 commit into from
Mar 8, 2024
Merged
Changes from all commits
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
240 changes: 120 additions & 120 deletions pq-src/build.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::path::PathBuf;
use std::{env, fs};

const LIBPORTS: &'static [&'static str] = &[
#[cfg(any(target_os = "linux", target_os = "windows"))]
"getpeereid.c",
const LIBPORTS_BASE: &[&str] = &[
"strlcat.c",
"strlcpy.c",
"snprintf.c",
Expand All @@ -23,47 +22,35 @@ const LIBPORTS: &'static [&'static str] = &[
"quotes.c",
"strerror.c",
"tar.c",
#[cfg(not(target_os = "windows"))]
"thread.c",
#[cfg(any(target_os = "macos", target_os = "windows"))]
];

const LIBPORTS_LINUX: &[&str] = &["getpeereid.c", "thread.c"];

const LIBPORTS_MACOS: &[&str] = &["explicit_bzero.c", "thread.c"];

const LIBPORTS_WINDOWS: &[&str] = &[
"getpeereid.c",
"explicit_bzero.c",
#[cfg(target_os = "windows")]
"win32common.c",
#[cfg(target_os = "windows")]
"win32dlopen.c",
#[cfg(target_os = "windows")]
"win32env.c",
#[cfg(target_os = "windows")]
"win32error.c",
#[cfg(target_os = "windows")]
"win32fdatasync.c",
#[cfg(target_os = "windows")]
"win32fseek.c",
#[cfg(target_os = "windows")]
"win32getrusage.c",
#[cfg(target_os = "windows")]
"win32gettimeofday.c",
#[cfg(target_os = "windows")]
"win32link.c",
#[cfg(target_os = "windows")]
"win32ntdll.c",
#[cfg(target_os = "windows")]
"win32pread.c",
#[cfg(target_os = "windows")]
"win32pwrite.c",
#[cfg(target_os = "windows")]
"win32security.c",
#[cfg(target_os = "windows")]
"win32setlocale.c",
#[cfg(target_os = "windows")]
"win32stat.c",
#[cfg(target_os = "windows")]
"open.c",
#[cfg(target_os = "windows")]
"dirmod.c",
];

const LIBCOMMON: &'static [&'static str] = &[
const LIBCOMMON_BASE: &[&str] = &[
"file_perm.c",
"encnames.c",
"base64.c",
Expand All @@ -87,31 +74,28 @@ const LIBCOMMON: &'static [&'static str] = &[
"username.c",
"wait_error.c",
"wchar.c",
#[cfg(not(target_os = "windows"))]
"cryptohash_openssl.c",
#[cfg(target_os = "windows")]
"cryptohash.c",
#[cfg(not(target_os = "windows"))]
"hmac_openssl.c",
#[cfg(target_os = "windows")]
"hmac.c",
#[cfg(not(target_os = "windows"))]
"protocol_openssl.c",
"fe_memutils.c",
"restricted_token.c",
"sprompt.c",
"logging.c",
#[cfg(target_os = "windows")]
];

const LIBCOMMON_NOT_WINDOWS: &[&str] = &[
"cryptohash_openssl.c",
"hmac_openssl.c",
"protocol_openssl.c",
];

const LIBCOMMON_WINDOWS: &[&str] = &[
"cryptohash.c",
"hmac.c",
"md5.c",
#[cfg(target_os = "windows")]
"sha1.c",
#[cfg(target_os = "windows")]
"sha2.c",
#[cfg(target_os = "windows")]
"wchar.c",
];

const LIBPQ: &'static [&'static str] = &[
const LIBPQ_BASE: &[&str] = &[
"fe-auth-scram.c",
"fe-auth.c",
"fe-connect.c",
Expand All @@ -125,144 +109,160 @@ const LIBPQ: &'static [&'static str] = &[
"legacy-pqsignal.c",
"libpq-events.c",
"pqexpbuffer.c",
#[cfg(not(target_os = "windows"))]
"fe-secure-common.c",
#[cfg(not(target_os = "windows"))]
"fe-secure-openssl.c",
#[cfg(target_os = "windows")]
"fe-secure.c",
#[cfg(target_os = "windows")]
"pthread-win32.c",
#[cfg(target_os = "windows")]
"win32.c",
];

const LIBPQ_NOT_WINDOWS: &[&str] = &["fe-secure-common.c", "fe-secure-openssl.c"];

const LIBPQ_WINDOWS: &[&str] = &["fe-secure.c", "pthread-win32.c", "win32.c"];

fn unimplemented() -> ! {
unimplemented!(
"Building a bundled version of libpq is currently not supported for this OS\n\
If you are interested in support for using a bundled libpq we are happy to accept patches \
at https://github.com/sgrif/pq-sys/"
);
}

fn main() {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();

println!("cargo:rerun-if-changed=additional_include");
let crate_dir = env!("CARGO_MANIFEST_DIR");
let temp_include = format!("{}/more_include/", std::env::var("OUT_DIR").unwrap());
let temp_include = format!("{}/more_include/", env::var("OUT_DIR").unwrap());
let path = format!("{crate_dir}/source/");
let port_path = "src/port/";
let common_path = "src/common/";
let pq_path = "src/interfaces/libpq/";

if !PathBuf::from(&temp_include).exists() {
std::fs::create_dir(&temp_include).unwrap();
fs::create_dir(&temp_include).unwrap();
}
if !PathBuf::from(format!("{temp_include}pg_config_os.h")).exists() {
if cfg!(target_os = "linux") {
std::fs::copy(
format!("{path}src/include/port/linux.h"),
format!("{temp_include}pg_config_os.h"),
)
.unwrap();
} else if cfg!(target_os = "macos") {
std::fs::copy(
format!("{path}src/include/port/darwin.h"),
format!("{temp_include}pg_config_os.h"),
)
.unwrap();
} else if cfg!(target_os = "windows") {
std::fs::copy(
format!("{path}src/include/port/win32.h"),
format!("{temp_include}pg_config_os.h"),
)
.unwrap();
println!("cargo:rustc-link-lib=Secur32");
println!("cargo:rustc-link-lib=Shell32");
} else {
unimplemented!(
"Building a bundled version of libpq is currently not supported for this OS\n\
If you are interested in support for using a bundled libpq we are happy to accept patches \n
at https://github.com/sgrif/pq-sys/"
);
match target_os.as_str() {
"linux" => {
fs::copy(
format!("{path}src/include/port/linux.h"),
format!("{temp_include}pg_config_os.h"),
)
.unwrap();
}
"macos" => {
fs::copy(
format!("{path}src/include/port/darwin.h"),
format!("{temp_include}pg_config_os.h"),
)
.unwrap();
}
"windows" => {
fs::copy(
format!("{path}src/include/port/win32.h"),
format!("{temp_include}pg_config_os.h"),
)
.unwrap();
println!("cargo:rustc-link-lib=Secur32");
println!("cargo:rustc-link-lib=Shell32");
}
_ => unimplemented(),
}
}
#[cfg(not(target_os = "windows"))]
let openssl = std::env::var("DEP_OPENSSL_INCLUDE").unwrap();

let mut basic_build = cc::Build::new();

let base_includes = &[
format!("{path}{port_path}"),
format!("{path}src/include"),
format!("{crate_dir}/additional_include"),
temp_include.clone(),
][..];

let includes = if target_os == "windows" {
let includes_windows = &[
format!("{path}/src/include/port/win32/"),
format!("{path}/src/include/port/win32_msvc/"),
];
[base_includes, includes_windows].concat()
} else {
let includes_not_windows = &[env::var("DEP_OPENSSL_INCLUDE").unwrap().clone()];
[base_includes, includes_not_windows].concat()
};

basic_build
.define("FRONTEND", None)
.warnings(false)
.includes([
format!("{path}{port_path}"),
format!("{path}src/include"),
format!("{crate_dir}/additional_include"),
temp_include.clone(),
#[cfg(not(target_os = "windows"))]
openssl.clone(),
#[cfg(target_os = "windows")]
format!("{path}/src/include/port/win32/"),
#[cfg(target_os = "windows")]
format!("{path}/src/include/port/win32_msvc/"),
]);
.includes(includes);

if cfg!(feature = "with-asan") {
if env::var("CARGO_FEATURE_WITH_ASAN").is_ok() {
basic_build.flag("-fsanitize=address");
}

if cfg!(target_os = "linux") {
basic_build.define("_GNU_SOURCE", None);
}
if cfg!(target_os = "macos") {
// something is broken in homebrew
// https://github.com/Homebrew/legacy-homebrew/pull/23620
basic_build.define("_FORTIFY_SOURCE", Some("0"));
}
if cfg!(target_os = "windows") {
basic_build.define("WIN32", None);
basic_build.define("_WINDOWS", None);
basic_build.define("__WIN32__", None);
basic_build.define("__WINDOWS__", None);
}
let (libports_os, libcommon_os, libpq_os) = match target_os.as_str() {
"linux" => {
basic_build.define("_GNU_SOURCE", None);
(LIBPORTS_LINUX, LIBCOMMON_NOT_WINDOWS, LIBPQ_NOT_WINDOWS)
}
"macos" => {
// something is broken in homebrew
// https://github.com/Homebrew/legacy-homebrew/pull/23620
basic_build.define("_FORTIFY_SOURCE", Some("0"));
(LIBPORTS_MACOS, LIBCOMMON_NOT_WINDOWS, LIBPQ_NOT_WINDOWS)
}
"windows" => {
basic_build.define("WIN32", None);
basic_build.define("_WINDOWS", None);
basic_build.define("__WIN32__", None);
basic_build.define("__WINDOWS__", None);
basic_build.define("HAVE_SOCKLEN_T", Some("1"));
(LIBPORTS_WINDOWS, LIBCOMMON_WINDOWS, LIBPQ_WINDOWS)
}
_ => unimplemented(),
};

let libports = LIBPORTS_BASE.iter().chain(libports_os);
let libcommon = LIBCOMMON_BASE.iter().chain(libcommon_os);
let libpq = LIBPQ_BASE.iter().chain(libpq_os);

basic_build
.clone()
.files(
LIBPORTS
.iter()
.map(|p| format!("{path}{port_path}{p}"))
.chain(LIBCOMMON.iter().map(|p| format!("{path}{common_path}{p}")))
.chain(LIBPQ.iter().map(|p| format!("{path}{pq_path}{p}"))),
(libports.map(|p| format!("{path}{port_path}{p}")))
.chain(libcommon.map(|p| format!("{path}{common_path}{p}")))
.chain(libpq.map(|p| format!("{path}{pq_path}{p}"))),
)
.compile("pq");

let out = std::env::var("OUT_DIR").expect("Set by cargo");
let out = env::var("OUT_DIR").expect("Set by cargo");
let include_path = PathBuf::from(&out).join("include");
let lib_pq_path = PathBuf::from(format!("{path}/{pq_path}"));
std::fs::create_dir_all(&include_path).expect("Failed to create include directory");
std::fs::create_dir_all(include_path.join("postgres").join("internal"))
fs::create_dir_all(&include_path).expect("Failed to create include directory");
fs::create_dir_all(include_path.join("postgres").join("internal"))
.expect("Failed to create include directory");
std::fs::copy(
fs::copy(
lib_pq_path.join("libpq-fe.h"),
include_path.join("libpq-fe.h"),
)
.expect("Copying headers failed");
std::fs::copy(
fs::copy(
lib_pq_path.join("libpq-events.h"),
include_path.join("libpq-events.h"),
)
.expect("Copying headers failed");

std::fs::copy(
fs::copy(
lib_pq_path.join("libpq-int.h"),
include_path
.join("postgres")
.join("internal")
.join("libpq-int.h"),
)
.expect("Copying headers failed");
std::fs::copy(
fs::copy(
lib_pq_path.join("fe-auth-sasl.h"),
include_path
.join("postgres")
.join("internal")
.join("fe-auth-sasl.h"),
)
.expect("Copying headers failed");
std::fs::copy(
fs::copy(
lib_pq_path.join("pqexpbuffer.h"),
include_path
.join("postgres")
Expand Down
Loading