xd009642 / tarpaulin

A code coverage tool for Rust projects
https://crates.io/crates/cargo-tarpaulin
Apache License 2.0
2.5k stars 180 forks source link

Issue with opencv #1354

Closed protortyp closed 5 months ago

protortyp commented 1 year ago

I am copying this issue over from the opencv library because I think it is primarily an issue with tarpaulin.


I am using cargo tarpaulin to generate code coverage. While everything compiles smoothly in tests and release mode, using tarpaulin results in a lot of errors.

I have replicated this in a fresh Ubuntu:22.04 docker container. With

This is the error output from cargo tarpaulin:

error.log

You can use this Dockerfile to recreate the error with a minimal example that only includes the opencv dependency, and does nothing else besides that.

# Use Ubuntu 22.04 as the base image
FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive
ENV OPENCV_VERSION=4.8.0

# Install necessary dependencies, OpenCV, and its development packages
RUN apt-get update && apt-get install -y \
    clang \
    libclang-dev \
    pkg-config \
    curl \
    build-essential \
    openssl \
    libssl-dev \
    cmake g++ wget unzip

# install opencv from scratch
WORKDIR /tmp

# Download opencv and opencv_contrib
RUN wget -O opencv.zip https://github.com/opencv/opencv/archive/refs/tags/${OPENCV_VERSION}.zip && \
    wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/refs/tags/${OPENCV_VERSION}.zip

# Unzip
RUN unzip opencv.zip && \
    unzip opencv_contrib.zip

WORKDIR /tmp/opencv-${OPENCV_VERSION}/build

# Configure the build
#RUN cmake -D CMAKE_BUILD_TYPE=RELEASE \
RUN cmake -D CMAKE_BUILD_TYPE=DEBUG \
          -D CMAKE_INSTALL_PREFIX=/usr/local \
          -D INSTALL_C_EXAMPLES=OFF \
          -D INSTALL_PYTHON_EXAMPLES=OFF \
          -D OPENCV_EXTRA_MODULES_PATH=/tmp/opencv_contrib-${OPENCV_VERSION}/modules \
          -D BUILD_EXAMPLES=OFF ..

# Build and install
RUN make -j$(nproc) && \
    make install && \
    ldconfig

# Set environment variables for dynamic linking and pkg-config path
ENV LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/local/lib
ENV PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig

# Install Rust using rustup
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable -y
ENV PATH="/root/.cargo/bin:${PATH}"

# Create a new Rust project
WORKDIR /app
RUN cargo new rust_opencv_project

# Change working directory to the new Rust project
WORKDIR /app/rust_opencv_project

# Add OpenCV dependency to the Cargo.toml
RUN echo 'opencv = "0.83"' >> Cargo.toml

# Patch the Cargo.toml file
RUN echo "\n[patch.crates-io]" >> Cargo.toml && \
    echo "cc = { git = \"https://github.com/rust-lang/cc-rs.git\", version = \"1.0\", tag = \"1.0.79\" }" >> Cargo.toml

# Add use statement in src/main.rs
RUN sed -i '1i\use opencv::prelude::*;\n' src/main.rs

# Build the project to ensure it compiles successfully
RUN cargo build

# Install cargo-tarpaulin for code coverage
RUN cargo install cargo-tarpaulin

# Run cargo tarpaulin to generate code coverage
# I simply run the container and attach with bash, and run cargo tarpaulin myself, since
# this command will fail
#RUN cargo tarpaulin

For now, I am using cargo-llvm-cov, but it does not offer branch coverage and I generally like the html output of tarpaulin much more.

Any hints would be highly appreciated.

xd009642 commented 1 year ago

"--engine llvm" in the tarpaulin args may work, but tarpaulin doesn't offer branch coverage as well fwiw, it's just on our roadmap

I'll try to look over the weekend in more detail

protortyp commented 1 year ago

Thanks! I tried -engine llvm but that also fails.

xd009642 commented 5 months ago

Sorry for the delay, had a brief hiatus while prepping for rustnation!

So this is something that completely slipped my mind but I'm doing some tests now and it looks like it's working (just doing one final tarpaulin run). When there are native dependencies -Clink-dead-code will fail to compile with Rust (there is an open issue in the compiler for this). So with tarpaulin you should add --no-dead-code.

This does have the side-effect of making the results less accurate unfortunately. But you can mitigate that with --engine llvm which does attempt to add in the counters for the dead code in the results still

xd009642 commented 5 months ago

Okay I've now fully confirmed, it's due to dead code inclusion.

I have started writing a troubleshooting guide which will hopefully provide more comprehensive and quicker help for future similar issues since the readme is a bit dense and some stuff hard to find