clamav/libclamav_rust/build.rs

192 lines
6.4 KiB
Rust
Raw Normal View History

Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
use std::env;
use std::path::{Path, PathBuf};
// Note to maintainers: this is currently a hybrid of examination of the
// CMake environment, and leaning on Rust `cfg` elements. Ideally, it
// should be possible to work in this space (e.g., execute tests from an
// IDE) without having to rely on CMake elements to properly link the
// unit tests). Hence the bizarre mix of CMake inspection and Cargo-based
// elements.
//
// It's handy to know that all the `cfg` goodies are defined here:
//
// https://doc.rust-lang.org/reference/conditional-compilation.html
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
// A list of environment variables to query to determine additional libraries
// that need to be linked to resolve dependencies.
const LIB_ENV_LINK: [&str; 12] = [
"LIBSSL",
"LIBCRYPTO",
"LIBZ",
"LIBBZ2",
"LIBPCRE2",
"LIBXML2",
"LIBCURL",
"LIBJSONC",
"LIBCLAMMSPACK",
"LIBCLAMUNRARIFACE",
"LIBCLAMUNRAR",
"LIBICONV",
];
// The same, but additional values to check on Windows platforms
const LIB_ENV_LINK_WINDOWS: [&str; 2] = ["LIBPTHREADW32", "LIBWIN32COMPAT"];
// Additional [verbatim] libraries to link on Windows platforms
const LIB_LINK_WINDOWS: [&str; 4] = ["wsock32", "ws2_32", "Shell32", "User32"];
// Windows library names that must have the leading `lib` trimmed (if encountered)
const WINDOWS_TRIM_LOCAL_LIB: [&str; 2] = ["libclamav", "libclammspack"];
2021-11-29 17:24:39 -08:00
const C_HEADER_OUTPUT: &str = "clamav_rust.h";
// Environment variable name prefixes worth including for diags
const ENV_PATTERNS: &[&str] = &["CARGO_", "RUST", "LIB"];
2021-11-29 17:24:39 -08:00
fn main() -> Result<(), &'static str> {
// Dump the command line and interesting environment variables for diagnostic
// purposes. These will end up in a 'stderr' file under the target directory,
// in a ".../clamav_rust-<hex>" subdirectory
eprintln!("build.rs command line: {:?}", std::env::args());
eprintln!("Environment:");
std::env::vars()
.filter(|(k, _)| ENV_PATTERNS.iter().any(|prefix| k.starts_with(prefix)))
.for_each(|(k, v)| eprintln!(" {}={:?}", k, v));
2021-11-29 17:24:39 -08:00
detect_clamav_build()?;
// We only want to execute cbindgen for `cargo build`, not `cargo test`.
// FindRust.cmake defines $CARGO_CMD so we can differentiate.
if "build" == env::var("CARGO_CMD").or(Ok("".to_string()))? {
execute_cbindgen()?;
} else {
eprintln!("NOTE: Not performing cbindgen as CARGO_CMD != build");
}
2021-11-29 17:24:39 -08:00
Ok(())
}
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
2021-11-29 17:24:39 -08:00
fn execute_cbindgen() -> Result<(), &'static str> {
let crate_dir = env::var("CARGO_MANIFEST_DIR").or(Err("CARGO_MANIFEST_DIR not specified"))?;
let build_dir = PathBuf::from(env::var("CARGO_TARGET_DIR").unwrap_or(".".into()));
2021-11-29 17:24:39 -08:00
let outfile_path = build_dir.join(C_HEADER_OUTPUT);
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
2021-11-29 17:24:39 -08:00
// Useful for build diagnostics
eprintln!("cbindgen outputting {:?}", &outfile_path);
cbindgen::generate(crate_dir)
.expect("Unable to generate bindings")
.write_to_file(&outfile_path);
Ok(())
}
fn detect_clamav_build() -> Result<(), &'static str> {
println!("cargo:rerun-if-env-changed=LIBCLAMAV");
if search_and_link_lib("LIBCLAMAV")? {
eprintln!("NOTE: LIBCLAMAV defined. Examining LIB* environment variables");
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
// Need to link with libclamav dependencies
for var in &LIB_ENV_LINK {
let _ = search_and_link_lib(var);
}
if cfg!(windows) {
for var in &LIB_ENV_LINK_WINDOWS {
let _ = search_and_link_lib(var);
}
for lib in &LIB_LINK_WINDOWS {
println!("cargo:rustc-link-lib={}", lib);
}
} else {
// Link the test executable with libstdc++ on unix systems,
// This is needed for fully-static build where clamav & 3rd party
// dependencies excluding the std libs are static.
if cfg!(target_os = "linux") {
eprintln!("NOTE: linking libstdc++ (linux target)");
println!("cargo:rustc-link-lib=stdc++");
} else {
eprintln!("NOTE: NOT linking libstdc++ (non-linux target)");
}
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
}
} else {
println!("NOTE: LIBCLAMAV not defined");
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
}
2021-11-29 17:24:39 -08:00
Ok(())
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
}
//
// Return whether the specified environment variable has been set, and output
// linking directives as a side-effect
//
fn search_and_link_lib(environment_variable: &str) -> Result<bool, &'static str> {
eprintln!(" - checking for {:?} in environment", environment_variable);
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
let filepath_str = match env::var(environment_variable) {
Err(env::VarError::NotPresent) => return Ok(false),
Err(env::VarError::NotUnicode(_)) => return Err("environment value not unicode"),
Ok(s) => {
if s.is_empty() {
return Ok(false);
} else {
s
}
}
};
let parsed_path = parse_lib_path(&filepath_str)?;
eprintln!(
" - adding {:?} to rustc library search path",
&parsed_path.dir
);
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
println!("cargo:rustc-link-search={}", parsed_path.dir);
eprintln!(" - requesting that rustc link {:?}", &parsed_path.libname);
Add Rust logging module unit test & integrate with CMake / CTest Add a basic unit test for the new libclamav_rust `logging.rs` module. This test simply initializes logging and then prints out a message with each of the `log` macros. Also set the Rust edition to 2018 because the default is the 2015 edition in which using external crates is very clunky. For the Rust test support in CMake this commit adds support for cross-compiling the Rust tests. Rust tests must be built for the same LLVM triple (target platform) as the rest of the project. In particular this is needed to build both x64 and x86 packages on a 64bit Windows host. For Alpine, we observed that the LLVM triple for the host platform tools may be either: - x86_64-unknown-linux-musl, or - x86_64-alpine-linux-musl To support it either way, we look up the host triple with `rustc -vV` and use that if the musl libc exists. This is a big hacky and unfortunately means that we probably can't cross-compile to other platforms when running on a musl libc host. There are probably improvements to be made to improve cross compiling support. The Rust test programs must link with libclamav, libclammspack, and possibly libclamunrar_iface and libclamunrar plus all of the library dependencies for those libraries. To do this, we pass the path of each library in environment variables when building the libclamav_rust unit test program. Within `libclamav_rust/build.rs`, we read those environment variables. If set, we parse each into library path and name components to use as directives for how to build the unit test program. See: https://doc.rust-lang.org/cargo/reference/build-scripts.html Our `build.rs` file ignores the library path environment variables if thye're not set, which is necessary when building the libclamav_rust library and when libclamunrar isn't static and for when not linking with a libiconv external to libc. Rust test programs are built and executed in subdirectory under: <target>/<llvm triple>/<config>/deps where "target" for libclamav_rust tests is set to <build>/unit_tests For example: clamav/build/unit_tests/x86_64-pc-windows-msvc/debug/deps/clamav_rust-7e1343f8a2bff1cc.exe Since this program isn't co-located with the rest of the libraries we also have to set environment variables so the test program can find and load the shared libraries: - Windows: PATH - macOS: DYLD_LIBRARY_PATH We already set LD_LIBRARY_PATH when not Windows for similar reasons. Note: In build.rs, we iterate references to LIB_ENV_LINK & Co because older Rust versions do implement Iterator for [&str].
2021-11-18 10:24:00 -08:00
println!("cargo:rustc-link-lib={}", parsed_path.libname);
return Ok(true);
}
struct ParsedLibraryPath {
dir: String,
libname: String,
}
// Parse a library path, returning the portion expected after the `-l`, and the
// directory containing the library
fn parse_lib_path<'a>(path: &'a str) -> Result<ParsedLibraryPath, &'static str> {
let path = PathBuf::from(path);
let file_name = path
.file_name()
.ok_or("file name not found")?
.to_str()
.ok_or("file name not unicode")?;
// This can't fail because it came from a &str
let dir = path
.parent()
.unwrap_or(Path::new("."))
.to_str()
.unwrap()
.to_owned();
// Grab the portion up to the first '.'
let full_libname = file_name
.split('.')
.next()
.ok_or("no '.' found in file name")?;
// Windows typically requires the full filename when linking system libraries,
// but not when it's one of the locally-generated libraries.
let should_trim_leading_lib =
!cfg!(windows) || WINDOWS_TRIM_LOCAL_LIB.iter().any(|s| *s == full_libname);
let libname = if should_trim_leading_lib {
full_libname
.strip_prefix("lib")
.ok_or(r#"file name doesn't begin with "lib""#)?
} else {
full_libname
}
.to_owned();
Ok(ParsedLibraryPath { dir, libname })
}