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

Ubuntu 18.04 - app compilation fails #339

Closed
neilyoung opened this issue May 9, 2022 · 38 comments
Closed

Ubuntu 18.04 - app compilation fails #339

neilyoung opened this issue May 9, 2022 · 38 comments

Comments

@neilyoung
Copy link

Is there anything to consider on Ubuntu 18.04?

My rust application uses the latest opencv crate, but fails to compile on 18.04. No issue on 20.04

20.04 has OpenCV 4.2.0, while 18.04 comes with 3.2. This seems to be a problem.

Collection of problems:

imgproc::FONT_HERSHEY_PLAIN,
imgproc::LINE_AA,
     
highgui::set_window_property(window_title, highgui::WND_PROP_TOPMOST, 1.0)?;
     |                                                             ^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `WND_PROP_OPENGL`
     |
     
cam = videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?;
     |                                      ^^^ function or associated item not found in `VideoCapture`
     
@neilyoung
Copy link
Author

All errors:

error[E0425]: cannot find value `FONT_HERSHEY_PLAIN` in module `imgproc`
   --> src/main.rs:321:22
    |
321 |             imgproc::FONT_HERSHEY_PLAIN,
    |                      ^^^^^^^^^^^^^^^^^^
    |
   ::: /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/opencv-0.63.1/src/opencv/hub/imgproc.rs:580:1
    |
580 | pub const CV_FONT_HERSHEY_PLAIN: i32 = 1;
    | ----------------------------------------- similarly named constant `CV_FONT_HERSHEY_PLAIN` defined here
    |
help: a constant with a similar name exists
    |
321 |             imgproc::CV_FONT_HERSHEY_PLAIN,
    |                      ~~~~~~~~~~~~~~~~~~~~~
help: consider importing one of these items
    |
1   | use crate::core::FONT_HERSHEY_PLAIN;
    |
1   | use crate::core::HersheyFonts::FONT_HERSHEY_PLAIN;
    |
1   | use opencv::core::FONT_HERSHEY_PLAIN;
    |
1   | use opencv::core::HersheyFonts::FONT_HERSHEY_PLAIN;
    |

error[E0425]: cannot find value `LINE_AA` in module `imgproc`
   --> src/main.rs:325:22
    |
325 |             imgproc::LINE_AA,
    |                      ^^^^^^^ not found in `imgproc`
    |
help: consider importing one of these items
    |
1   | use crate::core::LINE_AA;
    |
1   | use crate::core::LineTypes::LINE_AA;
    |
1   | use opencv::core::LINE_AA;
    |
1   | use opencv::core::LineTypes::LINE_AA;
    |

error[E0425]: cannot find value `FONT_HERSHEY_PLAIN` in module `imgproc`
   --> src/main.rs:334:26
    |
334 |                 imgproc::FONT_HERSHEY_PLAIN,
    |                          ^^^^^^^^^^^^^^^^^^
    |
   ::: /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/opencv-0.63.1/src/opencv/hub/imgproc.rs:580:1
    |
580 | pub const CV_FONT_HERSHEY_PLAIN: i32 = 1;
    | ----------------------------------------- similarly named constant `CV_FONT_HERSHEY_PLAIN` defined here
    |
help: a constant with a similar name exists
    |
334 |                 imgproc::CV_FONT_HERSHEY_PLAIN,
    |                          ~~~~~~~~~~~~~~~~~~~~~
help: consider importing one of these items
    |
1   | use crate::core::FONT_HERSHEY_PLAIN;
    |
1   | use crate::core::HersheyFonts::FONT_HERSHEY_PLAIN;
    |
1   | use opencv::core::FONT_HERSHEY_PLAIN;
    |
1   | use opencv::core::HersheyFonts::FONT_HERSHEY_PLAIN;
    |

error[E0425]: cannot find value `LINE_AA` in module `imgproc`
   --> src/main.rs:338:26
    |
338 |                 imgproc::LINE_AA,
    |                          ^^^^^^^ not found in `imgproc`
    |
help: consider importing one of these items
    |
1   | use crate::core::LINE_AA;
    |
1   | use crate::core::LineTypes::LINE_AA;
    |
1   | use opencv::core::LINE_AA;
    |
1   | use opencv::core::LineTypes::LINE_AA;
    |

error[E0425]: cannot find value `FONT_HERSHEY_PLAIN` in module `imgproc`
   --> src/main.rs:347:30
    |
347 |                     imgproc::FONT_HERSHEY_PLAIN,
    |                              ^^^^^^^^^^^^^^^^^^
    |
   ::: /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/opencv-0.63.1/src/opencv/hub/imgproc.rs:580:1
    |
580 | pub const CV_FONT_HERSHEY_PLAIN: i32 = 1;
    | ----------------------------------------- similarly named constant `CV_FONT_HERSHEY_PLAIN` defined here
    |
help: a constant with a similar name exists
    |
347 |                     imgproc::CV_FONT_HERSHEY_PLAIN,
    |                              ~~~~~~~~~~~~~~~~~~~~~
help: consider importing one of these items
    |
1   | use crate::core::FONT_HERSHEY_PLAIN;
    |
1   | use crate::core::HersheyFonts::FONT_HERSHEY_PLAIN;
    |
1   | use opencv::core::FONT_HERSHEY_PLAIN;
    |
1   | use opencv::core::HersheyFonts::FONT_HERSHEY_PLAIN;
    |

error[E0425]: cannot find value `LINE_AA` in module `imgproc`
   --> src/main.rs:351:30
    |
351 |                     imgproc::LINE_AA,
    |                              ^^^^^^^ not found in `imgproc`
    |
help: consider importing one of these items
    |
1   | use crate::core::LINE_AA;
    |
1   | use crate::core::LineTypes::LINE_AA;
    |
1   | use opencv::core::LINE_AA;
    |
1   | use opencv::core::LineTypes::LINE_AA;
    |

error[E0425]: cannot find value `WND_PROP_TOPMOST` in module `highgui`
   --> src/main.rs:358:61
    |
358 |         highgui::set_window_property(window_title, highgui::WND_PROP_TOPMOST, 1.0)?;
    |                                                             ^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `WND_PROP_OPENGL`
    |
   ::: /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/opencv-0.63.1/src/opencv/hub/highgui.rs:214:1
    |
214 | pub const WND_PROP_OPENGL: i32 = 3;
    | ----------------------------------- similarly named constant `WND_PROP_OPENGL` defined here

error[E0599]: no function or associated item named `new` found for struct `VideoCapture` in the current scope
   --> src/main.rs:214:38
    |
214 |         cam = videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?;
    |                                      ^^^ function or associated item not found in `VideoCapture`

Some errors have detailed explanations: E0425, E0599.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `calibration` due to 8 previous errors

Caused by:
  process didn't exit successfully: `rustc --crate-name calibration --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no -C metadata=3d7943da16be8fd4 -C extra-filename=-3d7943da16be8fd4 --out-dir /home/runner/work/calibration/calibration/target/release/deps -L dependency=/home/runner/work/calibration/calibration/target/release/deps --extern anyhow=/home/runner/work/calibration/calibration/target/release/deps/libanyhow-77e73e2acd49b3b7.rlib --extern chrono=/home/runner/work/calibration/calibration/target/release/deps/libchrono-0bc40a43050d735c.rlib --extern opencv=/home/runner/work/calibration/calibration/target/release/deps/libopencv-5bcb5f19e26c3343.rlib --extern soloud=/home/runner/work/calibration/calibration/target/release/deps/libsoloud-f465fae[239](https://github.com/neilyoung/calibration/runs/6357698001?check_suite_focus=true#step:5:239)b1c6f0.rlib --extern structopt=/home/runner/work/calibration/calibration/target/release/deps/libstructopt-53a203cdd29f6e0c.rlib --extern url=/home/runner/work/calibration/calibration/target/release/deps/liburl-36b124c28dc08a4a.rlib -L native=/home/runner/work/calibration/calibration/target/release/build/opencv-346ce717f722e034/out -L /usr/lib/x86_64-linux-gnu -L native=/home/runner/work/calibration/calibration/target/release/build/soloud-sys-a844bb1917039dc3/out/build -L native=/home/runner/work/calibration/calibration/target/release/build/soloud-sys-a844bb1917039dc3/out/lib -L native=/home/runner/work/calibration/calibration/target/release/build/soloud-sys-a844bb1917039dc3/out/lib/Release` (exit status: 1)
Error: Process completed with exit code 101.

@twistedfall
Copy link
Owner

twistedfall commented May 9, 2022

The older OpenCV version doesn’t support everything that you’re using in your application. You’ll need to adjust the code for it to compile successfully.

@neilyoung
Copy link
Author

I see. Thanks. Another small issue (maybe you have a hint): I was compiling OpenCV 4.2.0 from source on 18.04, also with the contrib repo. While running my app it was missing "libopencv_viz.so:4.2". Any idea how to get this?

@twistedfall
Copy link
Owner

I would need some more context for that. Some build logs for example

@neilyoung
Copy link
Author

Sure. I was compiling 4.2 on 18.04 following this (buggy) gist: https://dev.to/swervin/how-to-install-opencv-4-2-0-on-ubuntu-18-04-3i7l

After sudo make install I was still forced to sudo ldconfig in order to overcome the initially missing `libopencv_aruco.so:4.2. But then there is still the "libopencv_viz.so:4.2" missing.

@neilyoung
Copy link
Author

I think the viz module has not been build... Checking

@twistedfall
Copy link
Owner

If you're compiling OpenCV from the source anyway, why not take the latest version (4.5.5 at the moment)?

@neilyoung
Copy link
Author

I was just trying to align to 20.04... But possible, yes.

The reason is definitely the missing VTK. Couldn't overcome this. Even with a source installation of VTK.

I don't need that viz module, I could live w/o it

@neilyoung
Copy link
Author

Oh no... 4.5.5 cmake generates tons of errors and a missing VTK is one of it... Not worth the efforts.

@twistedfall
Copy link
Owner

Just in case it's useful to you I used to build OpenCV on 18.04 for CI, you can find the build script here:

# runtime deps
at the moment it was OpenCV-4.5.4. These instructions might not be enough though because it's build inside the github actions container and it comes preinstalled with some software already, so if you install on a minimal Ubuntu image then you might need some more dependencies.

@neilyoung
Copy link
Author

Cool. Thanks for sharing. I will give it a try on my messed up 18.04 Linux box :)

@neilyoung
Copy link
Author

The problem remains in the end:

./calibration: error while loading shared libraries: libopencv_viz.so.4.2: cannot open shared object file: No such file or directory

I'm not sure where this dependency comes from. I have compiled calibration using Github Actions with ubuntu-latest (which is 20.04 I think). The build was successful. I copied the result to my 18.04 with a hand-made 4.5.5. There is a libopencv_viz.so:4.5.5, but my Rust app wants to see libopencv_viz.so:4.2 for some reasons.

I ran the build from your script, there was no dependency missing, VTK was installed (from 7.1) and detected. All fine. Just not for the app :(

Attached the complete build log.

build.log

@neilyoung
Copy link
Author

ldd calibration reveals, that calibration is full of dependencies to opencv 4.2.

Re-building OpenCV from source with version 4.2.0 now.

Let's see

@neilyoung
Copy link
Author

neilyoung commented May 10, 2022

Hopping from error to error... With OpenCV 4.2 on 18.04 this is the new runtime error:

decades@ubuntu:~/Downloads$ ./calibration 
./calibration: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by ./calibration)
./calibration: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by ./calibration)
decades@ubuntu:~/Downloads$ 

@neilyoung
Copy link
Author

neilyoung commented May 10, 2022

I think the opencv-rs approach is nice, but the dependency hell is a PITA. And we are not even talking about cross-platform...

The bionic GLIBC version is 2.27...

@neilyoung
Copy link
Author

Let's go back a step. Say, I would try to align my app to be compatible with OpenCV 3.2 and 4.2 (for 18.04 and 20.04). How could I achieve that? If I look at the errors above, then it seems to be doable.

I'm a bit concerned about this

         cam = videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?;
    |                                      ^^^ function or associated item not found in `VideoCapture`

How is opencv-rs supposed to be compatible with 3.2 if this does not work?

@twistedfall
Copy link
Owner

twistedfall commented May 10, 2022

When you build your project the opencv crate will generate bindings for the OpenCV that it was able to find. But it's not always possible for your code to be portable between different OpenCV versions (same is also true for C++ code). In Rust case you can use conditional compilation like it's done in this example: https://github.com/twistedfall/opencv-rust/blob/master/examples/video_capture.rs#L11

So you have 3 options: #[cfg(ocvrs_opencv_branch_32)], #[cfg(ocvrs_opencv_branch_34)] and #[cfg(ocvrs_opencv_branch_4)]. These are set by the build script when it determines the version of your installed OpenCV.

At the moment I wouldn't really target OpenCV 3.2, this version is very old and unmaintained upstream. The crate will drop the support for it at some point.

@neilyoung
Copy link
Author

Cool. Thanks. Will try that. Better to stick with the default OpenCV background of a particular Ubuntu version

@neilyoung
Copy link
Author

The determination seems to not work on my 18.04, even though all 4.x stuff is removed. I'm sure I only have 3.2 installed, but it still tries to resolve 4.x references.

@neilyoung
Copy link
Author

Disregard please. I'm giving up here. Thanks for your help so far

@neilyoung
Copy link
Author

There is definitely something wrong with OpenCV 3.2 and 18.04. I'm having a default installation of 3.2 on 18.04

sudo apt install libopencv-dev

Not even a minimalistic app links correctly:

use opencv;

 fn main() -> Result<()> {
    println!("Hello, world!");
    dbg!(opencv::core::get_build_information())?;
    Ok(())
}

cargo build ends with:

 = note: /usr/bin/ld: warning: libopencv_videoio.so.3.2, needed by /usr/lib/x86_64-linux-gnu/libopencv_videostab.so, not found (try using -rpath or -rpath-link)
          /usr/bin/ld: warning: libopencv_imgproc.so.3.2, needed by /usr/lib/x86_64-linux-gnu/libopencv_videostab.so, not found (try using -rpath or -rpath-link)
          /usr/bin/ld: warning: libopencv_core.so.3.2, needed by /usr/lib/x86_64-linux-gnu/libopencv_videostab.so, not found (try using -rpath or -rpath-link)
          /usr/bin/ld: warning: libopencv_highgui.so.3.2, needed by /usr/lib/x86_64-linux-gnu/libopencv_ccalib.so, not found (try using -rpath or -rpath-link)
          /usr/bin/ld: warning: libopencv_imgcodecs.so.3.2, needed by /usr/lib/x86_64-linux-gnu/libopencv_ccalib.so, not found (try using -rpath or -rpath-link)
          /usr/bin/ld: warning: libopencv_ml.so.3.2, needed by /usr/lib/x86_64-linux-gnu/libopencv_text.so, not found (try using -rpath or -rpath-link)
          /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libopencv_core.a(parallel.cpp.o): undefined reference to symbol '_ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv'
          //usr/lib/x86_64-linux-gnu/libtbb.so.2: error adding symbols: DSO missing from command line
          collect2: error: ld returned 1 exit status

The problem is: The linker is right! The /usr/lib/x86_64_linux-gnu dir contains a lot of opencv-related libs, such as

/usr/lib/x86_64-linux-gnu/libopencv_calib3d.so.3.2.0
./usr/lib/x86_64-linux-gnu/libopencv_saliency.so
./usr/lib/x86_64-linux-gnu/libopencv_viz.a
./usr/lib/x86_64-linux-gnu/libopencv_face.so.3.2
./usr/lib/x86_64-linux-gnu/libopencv_bgsegm.so.3.2
./usr/lib/x86_64-linux-gnu/libopencv_video.so
./usr/lib/x86_64-linux-gnu/libopencv_phase_unwrapping.so.3.2.0
./usr/lib/x86_64-linux-gnu/libopencv_calib3d.so
./usr/lib/x86_64-linux-gnu/libopencv_structured_light.so
./usr/lib/x86_64-linux-gnu/libopencv_superres.a
./usr/lib/x86_64-linux-gnu/libopencv_xphoto.so.3.2
./usr/lib/x86_64-linux-gnu/libopencv_objdetect.a
.

But not the a.m. missing. But they are all there, just w/o "3.2"

@twistedfall
Copy link
Owner

Something seems not right with your system install. I'm running the crate tests on 18.04 exactly for the reason for testing against OpenCV 3.2 from the repository and everything runs fine, the install script is trivial: https://github.com/twistedfall/opencv-rust/blob/master/ci/install-bionic.sh

@neilyoung
Copy link
Author

Yeah, I think so. But what shall I do? I have now several times installed and removed, even manually, EVERYTHING what did sound like "opencv" from the system. It doesn't help.

I tend to believe you, but I can't overcome this. I'm regularly getting dpkg warnings regarding missing file lists for exactly these packages...

An installation on a VM was successful

@neilyoung
Copy link
Author

Strange. I was always running the setup like so sudo apt-get install libopencv-dev. Now for the first time I was using `sudo apt-get install "libopencv-dev-3.2*" and the files are there...

@neilyoung
Copy link
Author

But can you tell me, what #[cfg(ocvrs_opencv_branch_32)] makes to become true? I see it in VS Code and at build time, that it is NOT true.

@neilyoung
Copy link
Author

I'm sure, it is due to my limited Rust knowledge, but this also does not compile:

Besides the fact, that rust-analyzer shows #[cfg(ocvrs_opencv_branch_32)] as inactive, the error is:

attributes on expressions are experimental
see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more informationrustcE0658
   let mut cam;
    // // Open the web-camera (assuming you have one)
    if rtsp_url.is_some() {
       cam = videoio::VideoCapture::from_file(rtsp_url.unwrap().as_str(), videoio::CAP_FFMPEG)?;
    } else {
        #[cfg(ocvrs_opencv_branch_32)]
        cam = videoio::VideoCapture::new_default(device_index)?; // 0 is the default camera
        #[cfg(not(ocvrs_opencv_branch_32))]
        cam = videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?; // 0 is the default camera

        cam.set(opencv::videoio::CAP_PROP_FRAME_WIDTH, 1280.0)?;
        cam.set(opencv::videoio::CAP_PROP_FRAME_HEIGHT, 720.0)?;
    }
    

@neilyoung
Copy link
Author

Not sure why all the world is so keen to do Rust. This language is brain-fuck. This works:

    // Open the web-camera (assuming you have one)
    let mut cam;
    if rtsp_url.is_some() {
        cam = videoio::VideoCapture::from_file(rtsp_url.unwrap().as_str(), videoio::CAP_FFMPEG)?;
    } else {
        #[cfg(ocvrs_opencv_branch_32)]
        let camera = videoio::VideoCapture::new_default(device_index)?;
        #[cfg(not(ocvrs_opencv_branch_32))]
        let camera = videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?;

        cam = camera;
        cam.set(opencv::videoio::CAP_PROP_FRAME_WIDTH, 1280.0)?;
        cam.set(opencv::videoio::CAP_PROP_FRAME_HEIGHT, 720.0)?;
    }


@neilyoung
Copy link
Author

However, #[cfg(ocvrs_opencv_branch_32)] is still false on my 3.2 system. Just why?

@twistedfall
Copy link
Owner

Can you post the full build log cargo build -vv after doing cargo clean? It will provide the necessary info to help debug this.

@neilyoung
Copy link
Author

Thank you very much for your help. Will provide the info soon.

@neilyoung
Copy link
Author

Here we go.

I can see the "branch_32" somehow in the log. It works on devices, where the "not" case is true, but not on 18.04 with 3.2.

My code parts, which are decorated with the conditional:

    // Align to the used OpenCV version
    #[cfg(ocvrs_opencv_branch_32)] 
    let font_face = CV_FONT_HERSHEY_PLAIN; 
    #[cfg(ocvrs_opencv_branch_32)] 
    let line_type = opencv::core::LINE_AA;
    #[cfg(not(ocvrs_opencv_branch_32))]
    let font_face = imgproc::FONT_HERSHEY_PLAIN;
    #[cfg(not(ocvrs_opencv_branch_32))]
    let line_type = imgproc::LINE_AA;

    let mut cam;
    if rtsp_url.is_some() {
        cam = videoio::VideoCapture::from_file(rtsp_url.unwrap().as_str(), videoio::CAP_FFMPEG)?;
    } else {
        #[cfg(ocvrs_opencv_branch_32)]
        let camera = videoio::VideoCapture::new_default(device_index)?;
        #[cfg(not(ocvrs_opencv_branch_32))]
        let camera = videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?;

        cam = camera;
        cam.set(opencv::videoio::CAP_PROP_FRAME_WIDTH, 1280.0)?;
        cam.set(opencv::videoio::CAP_PROP_FRAME_HEIGHT, 720.0)?;
    }

        #[cfg(not(ocvrs_opencv_branch_32))]
        highgui::set_window_property(window_title, highgui::WND_PROP_TOPMOST, 1.0)?;

But for some reason the #[cfg(not(ocvrs_opencv_branch_32))] is always found false.

build.log

@twistedfall
Copy link
Owner

I see and I can confirm that it's indeed the issue. ocvrs_opencv_branch_* config directives don't seem to be propagating to the dependent crates. Let me investigate it.

@neilyoung
Copy link
Author

Thanks for taking care

@twistedfall
Copy link
Owner

It turns out that it's not really possible to propagate configuration directives to the outside crates. In version 0.63.2 I've implemented the new way of doing conditional compilation:

opencv::opencv_branch_32! {
    let mut cam = videoio::VideoCapture::new_default(0)?; // 0 is the default camera
}
opencv::not_opencv_branch_32! {
    let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?; // 0 is the default camera
}

and for imports:

opencv::opencv_branch_4! {
    use opencv::core::AccessFlag::ACCESS_READ;
}
opencv::not_opencv_branch_4! {
    use opencv::core::ACCESS_READ;
}

There are 6 macros: opencv_branch_32, not_opencv_branch_32, opencv_branch_34, not_opencv_branch_34, opencv_branch_4 and not_opencv_branch_4. Please check them out to see if they work for you.

@neilyoung
Copy link
Author

Thanks for your efforts. I will give it a try and report.

@neilyoung
Copy link
Author

Seems, I need to wait until it is published, right?

image

@neilyoung
Copy link
Author

No, disregard. All fine. VSCode wasn't fast enough

@neilyoung
Copy link
Author

Well done. Works perfectly. Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants