I created a recipe for a cpp application using opencv to stream an image. But The build fails with following error :
Log data follows:
| DEBUG: Executing shell function do_compile
| shot.cpp:1:10: fatal error: core.hpp: No such file or directory
| 1 | #include "core.hpp"
| | ^~~~~~~~~~
| compilation terminated.
| WARNING: exit code 1 from a shell command.
Although, I added the meta-openembedded/meta-oe that includes opencv folder in which I found core.hpp to bblayers.
Here is the recipe:
DESCRIPTION = " this is an application display an image"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://shot.cpp"
DEPENDS = "opencv"
S = "${WORKDIR}"
do_compile () {
${CXX} shot.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_videoio
}
do_install () {
install -d 0755 ${D}/${bindir}
install -m 0755 ${D}/${bindir}
}
When I ran the application using the opencv I installed on my ubuntu 18.04. it works fine (using cmake).
I tried adding manually the core folder next to the recipe and it didn't work of course, I also added the path of the core.hpp to the recipe in the SRC_URI variable but no luck whatsoever I don't know what to do specially that I'm new to both yocto and opencv; help please
Here is the source code of the application:
#include "core.hpp"
#include "highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( )
{
Mat image;
// LOAD image
image = imread("image1.jpg"); // Read the file "image.jpg".
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
//DISPLAY image
namedWindow( "window"); // Create a window for display.
imshow( "window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
I think you need some modifications on your recipe:
[...]
inherit pkgconfig
DEPENDS = "opencv"
[...]
And you will need to add a RDEPENDS and FILES variable:
[...]
DEPENDS = "opencv"
# Add the runtime dependencies
RDEPENDS_${PN} = "libopencv-core libopencv-imgproc libopencv-highgui libopencv-videoio libopencv-imgcodecs"
[...]
# At the end, ship the files
FILES_${PN} = "${bindir}"
RDEPENDS_${PN}
will tell Yocto that your recipe package ${PN}
needs a list a runtime dependencies. These dependencies are requiered to run your application on your board (typically libraries).
FILES_${PN}
will tell Yocto that your recipe package ${PN}
will contains files. Without this line, Yocto will tell you that
${PN}
is by default your recipe file name (without the version and .bb
)
There is also some errors.
The compilation had some issues, lopencv_imgcodecs was not added, and there was no output name of your binary (I have named it shot
):
do_compile () {
${CXX} ${WORKDIR}/shot.cpp -o ${WORKDIR}/shot -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs ${LDFLAGS}
}
The second install command is not right:
install -m 0755 ${WORKDIR}/shot ${D}/${bindir}
Your application does not have the correct headers:
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
At the end, the recipe looks like:
DESCRIPTION = " this is an application display an image"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://shot.cpp"
inherit pkgconfig
DEPENDS = "opencv"
RDEPENDS_${PN} = "libopencv-core libopencv-imgproc libopencv-highgui libopencv-videoio libopencv-imgcodecs"
S = "${WORKDIR}"
do_compile () {
${CXX} ${WORKDIR}/shot.cpp -o ${WORKDIR}/shot -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs ${LDFLAGS}
}
do_install () {
install -d 0755 ${D}/${bindir}
install -m 0755 ${WORKDIR}/shot ${D}/${bindir}
}
FILES_${PN} = "${bindir}"
And the application:
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( )
{
Mat image;
// LOAD image
image = imread("image1.jpg"); // Read the file "image.jpg".
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
//DISPLAY image
namedWindow( "window"); // Create a window for display.
imshow( "window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
The recipe was working on my Yocto warrior meta.