Skip to content

Commit

Permalink
clamav-sys: tweaks for split build personalities
Browse files Browse the repository at this point in the history
  • Loading branch information
shutton committed Jan 12, 2024
1 parent fd2a218 commit dba749a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 22 deletions.
10 changes: 10 additions & 0 deletions clamav-sys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,13 @@ with newer ClamAV versions.

No attempt at preserving downward compatibility (using a `libclamav-sys` with
a version number greater than ClamAV's) is made.

## Packaging

In order to execute `cargo package` or `cargo publish`, there must be an
installed copy of the ClamAV include headers and libraries available. For
Unix-like environments, this means that the `pkg-config` utility must be able
to locate the `libclamav` package. As such, ensure that `PKG_CONFIG_PATH` is
set correctly when packaging. It is not critical that the installed copy
exactly match the version in the source tree, as compilation during packaging
is done only as a verification step.
56 changes: 41 additions & 15 deletions clamav-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ fn generate_bindings(
bindings = bindings.allowlist_var(constant);
}

// TODO: this wrapper probably isn't necessary. clamav.h could simply be located
bindings = bindings
.header("wrapper.h")
// Tell cargo to invalidate the built crate whenever any of the
Expand Down Expand Up @@ -166,25 +167,32 @@ fn cargo_common() {
}

fn main() -> anyhow::Result<()> {
cargo_common();

let mut include_paths = vec![];

// Test whether being built as part of ClamAV source
let local_include_path = local_clamav_include_path();
if let Some(path) = &local_include_path {
eprintln!("Local ClamAV include path: {path:?}",);
}
eprintln!(
"Building as part of ClamAV: {:?}",
building_under_clamav_cmake()
);
eprintln!("Maintainer mode: {:?}", in_maintainer_mode());

// Generate temporary path for the generated "internal" module
let mut output_path_intmod = PathBuf::from(env::var("OUT_DIR")?);
output_path_intmod.push("sys.rs");

if let Some(include_path) = &local_include_path {
// It seems we're being compiled from within the ClamAV source tree.
// Confirm that clamav.h is there, too

include_paths.push(include_path.clone());

build_internal::bindgen_internal(&output_path_intmod)?;
// Find headers
if let Some(path) = &local_include_path {
include_paths.push(path.clone());
} else {
// This crate is being referenced from an external project. Utilize the
// system-installed copy of libclamav (as located using pkg-config).
// This crate is being referenced from an external project that doesn't
// have access to the ClamAV source tree. Utilize the system-installed
// copy of libclamav (as located using pkg-config).

#[cfg(not(windows))]
{
Expand Down Expand Up @@ -226,7 +234,11 @@ fn main() -> anyhow::Result<()> {
include_paths.push(openssl_include);
}
};
}

if building_under_clamav_cmake() {
build_internal::bindgen_internal(&output_path_intmod)?;
} else {
// Build a vestigial `sys` module, as there will be no access to
// internal APIs.
let mut fh = std::fs::File::create(&output_path_intmod)?;
Expand All @@ -236,8 +248,7 @@ fn main() -> anyhow::Result<()> {
// Write the bindings to the $OUT_DIR/bindings.rs file.
let mut output_path = PathBuf::from(env::var("OUT_DIR").unwrap());
output_path.push("bindings.rs");
if local_include_path.is_none() || (local_include_path.is_some() && in_maintainer_mode()) {
cargo_common();
if !building_under_clamav_cmake() || (local_include_path.is_some() && in_maintainer_mode()) {
generate_bindings(
&output_path,
&|builder: bindgen::Builder| -> bindgen::Builder {
Expand All @@ -250,14 +261,19 @@ fn main() -> anyhow::Result<()> {
builder
},
);
// And place a copy in the source tree (for potential check-in)
std::fs::copy(&output_path, BINDGEN_OUTPUT_FILE)?;
} else {
// Otherwise, just copy the pre-generated file to the specified
// location.
// If building within ClamAV and not in maintainer mode, just copy the
// "cached" version, as libclang may not be available.
std::fs::copy(BINDGEN_OUTPUT_FILE, &output_path)?;
}

if in_maintainer_mode() {
// Copy the pre-generated file to the specified location. This should
// *not* be done when packaging `clamav-sys`, as it will touch the
// source tree, and `cargo package` will report an error.
std::fs::copy(&output_path, BINDGEN_OUTPUT_FILE)?;
}

Ok(())
}

Expand All @@ -282,6 +298,16 @@ fn local_clamav_include_path() -> Option<PathBuf> {
None
}

/// Return whether "maintiner mode" has been enabled in a ClamAV build.
pub(crate) fn in_maintainer_mode() -> bool {
env::var("MAINTAINER_MODE").unwrap_or_default() == "ON"
}

/// Return whether or not this crate's build is being performed as part of a ClamAV build
pub(crate) fn building_under_clamav_cmake() -> bool {
// Note, PROJECT_NAME is examined rather than CMAKE_PROJECT_NAME, as it's
// *possible* for a ClamAV build to be embedded within another CMake-based
// build, which would have a global CMAKE_PROJECT_NAME that is *not*
// "ClamAV"
env::var("PROJECT_NAME").unwrap_or_default() == "ClamAV"
}
14 changes: 7 additions & 7 deletions cmake/FindRust.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ function(add_rust_library)
if("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^(arm64;x86_64|x86_64;arm64)$")
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E make_directory "${ARGS_BINARY_DIRECTORY}/${RUST_COMPILER_TARGET}/${CARGO_BUILD_TYPE}"
COMMAND lipo -create ${ARGS_BINARY_DIRECTORY}/x86_64-apple-darwin/${CARGO_BUILD_TYPE}/lib${ARGS_TARGET}.a ${ARGS_BINARY_DIRECTORY}/aarch64-apple-darwin/${CARGO_BUILD_TYPE}/lib${ARGS_TARGET}.a -output "${OUTPUT}"
WORKING_DIRECTORY "${ARGS_SOURCE_DIRECTORY}"
Expand All @@ -297,22 +297,22 @@ function(add_rust_library)
elseif("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^(arm64)$")
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
WORKING_DIRECTORY "${ARGS_SOURCE_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_BINARY_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
elseif("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^(x86_64)$")
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E make_directory "${ARGS_BINARY_DIRECTORY}/${RUST_COMPILER_TARGET}/${CARGO_BUILD_TYPE}"
WORKING_DIRECTORY "${ARGS_SOURCE_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_BINARY_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
else()
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS}
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=build" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "MAINTAINER_MODE=${MAINTAINER_MODE}" "CARGO_INCLUDE_DIRECTORIES=\"${ARGS_INCLUDE_DIRECTORIES}\"" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS}
WORKING_DIRECTORY "${ARGS_SOURCE_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_BINARY_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
Expand Down Expand Up @@ -362,7 +362,7 @@ function(add_rust_test)
list(JOIN MY_CARGO_ARGS " " MY_CARGO_ARGS_STRING)

if(ARGS_PRECOMPILE_TESTS)
list(APPEND ARGS_PRECOMPILE_ENVIRONMENT "CARGO_CMD=test" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}")
list(APPEND ARGS_PRECOMPILE_ENVIRONMENT "CARGO_CMD=test" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}")
add_custom_target(${ARGS_NAME}_tests ALL
COMMAND ${CMAKE_COMMAND} -E env ${ARGS_PRECOMPILE_ENVIRONMENT} ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --color always --no-run
DEPENDS ${ARGS_PRECOMPILE_DEPENDS}
Expand All @@ -372,7 +372,7 @@ function(add_rust_test)

add_test(
NAME ${ARGS_NAME}
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=test" "PROJECT_NAME='${PROJECT_NAME}'" "CMAKE_PROJECT_NAME='${CMAKE_PROJECT_NAME}'" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --color always
COMMAND ${CMAKE_COMMAND} -E env "CARGO_CMD=test" "PROJECT_NAME=${PROJECT_NAME}" "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}" "CARGO_TARGET_DIR=${ARGS_BINARY_DIRECTORY}" "RUSTFLAGS=${RUSTFLAGS}" ${cargo_EXECUTABLE} ${MY_CARGO_ARGS} --color always
WORKING_DIRECTORY ${ARGS_SOURCE_DIRECTORY}
)
endfunction()
Expand Down

0 comments on commit dba749a

Please sign in to comment.