opencv / opencv

Open Source Computer Vision Library
https://opencv.org
Apache License 2.0
75.95k stars 55.62k forks source link

It's not possible to use OpenCV headers unless they are installed into a system include path. #5989

Closed ioquatix closed 7 years ago

ioquatix commented 8 years ago

I'm installing OpenCV into myproject/dist and headers are being installed into paths like myproject/dist/opencv2/core.hpp.

There is a problem with the way OpenCV headers include each other. For example, in core.hpp we see

#include "opencv2/core/cvdef.h"
#include "opencv2/core/version.hpp"
#include "opencv2/core/base.hpp"
#include "opencv2/core/cvstd.hpp"
#include "opencv2/core/traits.hpp"
#include "opencv2/core/matx.hpp"
#include "opencv2/core/types.hpp"
#include "opencv2/core/mat.hpp"
#include "opencv2/core/persistence.hpp"

However, the form of #include "opencv2/..." is invalid because for #include "dir/filename" the preprocessor searches in the same directory as the file containing the directive. As core.hpp is already in opencv2/core.hpp, the relative path becomes opencv2/opencv2/core/cvdef.h for example. Finally, if the file name is not resolved, it will actually search the system include directories which may or may not have the desired effect.

The correct form of the include should therefore be:

#include "core/cvdef.h"
#include "core/version.hpp"
#include "core/base.hpp"
#include "core/cvstd.hpp"
#include "core/traits.hpp"

etc.

This applies to many other files within the project which are using a strange form of absolute paths.

ioquatix commented 8 years ago

One example of a user having problems:

http://stackoverflow.com/questions/10818437/how-to-link-and-use-opencv-headers

alalek commented 8 years ago
#include "opencv2/core/version.hpp"

is the right way and works well.

#include "core/version.hpp"

is incorrect form, which will cause many conflicts with other projects.

P.S. You may take a look on the other big projects, like Qt, VTK, etc

ioquatix commented 8 years ago

@alalek Can you explain why it's the incorrect form and what conflicts it would cause?

ioquatix commented 8 years ago

@alalek Qt use the relative form correctly, for example, in include/qt/QtXml:

#ifndef QT_QTXML_MODULE_H
#define QT_QTXML_MODULE_H
#include <QtXml/QtXmlDepends>
#include "qtxmlglobal.h"
#include "qdom.h"
#include "qxml.h"
#include "qtxmlversion.h"
#endif

All the #include "paths" are relative to the current file.

alalek commented 8 years ago

Assumption about relative path in #include "path" form is not a part of C++ standard actually. It is compiler-specific.

ioquatix commented 8 years ago

@alalek

is the right way and works well.

Clearly it isn't working well here:

clang++ -c Lab/Program.cpp -o ../teapot/platforms/lab/cache/linux-debug/Lab/Program.cpp.o -MMD -MF ../teapot/platforms/lab/cache/linux-debug/Lab/Program.cpp.o.d -MT dependencies -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_ -O0 -g -Wall -Wmissing-prototypes -fPIC -I/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include -std=c++11 -pthread -Wno-c++11-narrowing -I ../teapot/platforms/lab/linux-debug/include

with OpenCV2 headers installed into ../teapot/platforms/lab/linux-debug/include gives the following odd errors:

In file included from Lab/Program.cpp:9:
In file included from Lab/Program.hpp:15:
In file included from /home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/opencv.hpp:51:
In file included from /usr/include/opencv2/objdetect.hpp:43:
/usr/include/opencv2/objdetect/objdetect.hpp:375:58: error: out-of-line declaration of 'delete_obj' does not match any
      declaration in 'cv::Ptr<CvHaarClassifierCascade>'
template<> CV_EXPORTS void Ptr<CvHaarClassifierCascade>::delete_obj();
                                                         ^~~~~~~~~~
In file included from Lab/Program.cpp:9:
In file included from Lab/Program.hpp:15:
/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/opencv.hpp:55:10: fatal error: 
      'opencv2/highgui.hpp' file not found
#include "opencv2/highgui.hpp"
         ^
2 errors generated.

Note how the file /home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/opencv.hpp includes /usr/include/opencv2/objdetect.hpp incorrectly due to the invalid relative includes eventually trying to resolve the file in the system include directories.

ioquatix commented 8 years ago

@alalek Assumption about relative path in #include "path" form is not a part of C++ standard actually. It is compiler-specific.

This has nothing to do with a compiler, #include is resolved by the preprocessor.

The overriding logic of all popular preprocessors is that #include "path" is relative.

GCC: https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html#Include-Syntax

#include "file" This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for . You can prepend directories to the list of quote directories with the -iquote option.

Microsoft Visual C++: https://msdn.microsoft.com/en-us/library/36k2cdd4.aspx

Quoted form: The preprocessor searches for include files in this order: 1/ In the same directory as the file that contains the #include statement.

alalek commented 8 years ago

I can't reproduce this problem with system-wide OpenCV 2.4.12 installation (Fedora 23) and current upstream OpenCV 3.0 build:

$ clang++ -E -x c++ - -v -I /home/alalek/projects/opencv_build/install/include \
    <<< '#include "opencv2/opencv.hpp"' | grep  "# 1 .*opencv2.*1"
clang version 3.7.0 (tags/RELEASE_370/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/5.1.1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
 "/usr/bin/clang" -cc1 -triple x86_64-redhat-linux-gnu -E -disable-free -disable-llvm-verifier -main-file-name - -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.25 -v -dwarf-column-info -resource-dir /usr/bin/../lib/clang/3.7.0 -I /home/alalek/projects/opencv_build/install/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1/../../../../include/c++/5.1.1 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1/../../../../include/c++/5.1.1/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1/../../../../include/c++/5.1.1/backward -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.7.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /home/alalek/projects/test -ferror-limit 19 -fmessage-length 130 -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o - -x c++ -
clang -cc1 version 3.7.0 based upon LLVM 3.7.0 default target x86_64-redhat-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/alalek/projects/opencv_build/install/include
 /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1/../../../../include/c++/5.1.1
 /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1/../../../../include/c++/5.1.1/x86_64-redhat-linux
 /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1/../../../../include/c++/5.1.1/backward
 /usr/local/include
 /usr/bin/../lib/clang/3.7.0/include
 /usr/include
End of search list.
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/opencv.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/cvdef.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/hal/interface.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/version.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/base.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/cvstd.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/ptr.inl.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/neon_utils.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/traits.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/matx.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/saturate.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/fast_math.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/types.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/mat.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/bufferpool.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/mat.inl.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/persistence.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/operations.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/cvstd.inl.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/utility.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/core_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/types_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/utility.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/optim.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/imgproc.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/imgproc/imgproc_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/imgproc/types_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/photo.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/photo/photo_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/video.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/video/tracking.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/video/background_segm.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/video/tracking_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/features2d.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/flann/miniflann.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/flann/defines.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/flann/config.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/objdetect.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/objdetect/detection_based_tracker.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/objdetect/objdetect_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/calib3d.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/core/affine.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/calib3d/calib3d_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/imgcodecs.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/videoio.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/highgui.hpp" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/highgui/highgui_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/imgcodecs/imgcodecs_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/videoio/videoio_c.h" 1
# 1 "/home/alalek/projects/opencv_build/install/include/opencv2/ml.hpp" 1

$ ll /usr/include/opencv2/objdetect.hpp
-rw-r--r-- 1 root root 2200 Oct 26 10:56 /usr/include/opencv2/objdetect.hpp

You can see that there is no switching to system-wide OpenCV libraries. Something wrong is happened in your build environment.

P.S. I prefer to use relative paths myself, but this behaviour is not a part of C standard. You can check this SO answer: http://stackoverflow.com/a/77092

ioquatix commented 8 years ago

Okay, so I found out the core of the problem.

I was not building objdetect or highgui. But, when #include <opencv2/core.hpp> these headers get included. Because of the style of the include, it was including the opencv2.4 objdetect.hpp and couldn't find highgui.hpp, e.g.:

% clang++ -E -x c++ - -v -I /home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include \
    <<< '#include "opencv2/opencv.hpp"' | grep  "# 1 .*opencv2.*1"
clang version 3.7.0 (tags/RELEASE_370/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.3.0
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-unknown-linux-gnu/5.3.0
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
 "/usr/bin/clang-3.7" -cc1 -triple x86_64-unknown-linux-gnu -E -disable-free -disable-llvm-verifier -main-file-name - -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -v -dwarf-column-info -resource-dir /usr/bin/../lib/clang/3.7.0 -I /home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../include/c++/5.3.0 -internal-isystem /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../include/c++/5.3.0/x86_64-unknown-linux-gnu -internal-isystem /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../include/c++/5.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.7.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /home/samuel/Documents/Programming/cvlab/cosc428/lab1 -ferror-limit 19 -fmessage-length 210 -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o - -x c++ -
clang -cc1 version 3.7.0 based upon LLVM 3.7.0 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include
 /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../include/c++/5.3.0
 /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../include/c++/5.3.0/x86_64-unknown-linux-gnu
 /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../include/c++/5.3.0/backward
 /usr/local/include
 /usr/bin/../lib/clang/3.7.0/include
 /usr/include
End of search list.
In file included from <stdin>:1:
/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/opencv.hpp:55:10: fatal error: 'opencv2/highgui.hpp' file not found
#include "opencv2/highgui.hpp"
         ^
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/opencv.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/cvdef.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/hal/interface.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/version.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/base.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/cvstd.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/ptr.inl.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/neon_utils.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/traits.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/matx.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/saturate.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/fast_math.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/types.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/mat.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/bufferpool.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/mat.inl.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/persistence.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/operations.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/cvstd.inl.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/utility.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/core_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/types_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/utility.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/optim.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/imgproc.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/imgproc/imgproc_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/imgproc/types_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/photo.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/photo/photo_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/video.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/video/tracking.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/video/background_segm.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/video/tracking_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/features2d.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/flann/miniflann.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/flann/defines.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/flann/config.h" 1
# 1 "/usr/include/opencv2/objdetect.hpp" 1 3 4
# 1 "/usr/include/opencv2/objdetect/objdetect.hpp" 1 3 4
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/core.hpp" 1 3 4
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/calib3d.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/core/affine.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/calib3d/calib3d_c.h" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/imgcodecs.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/videoio.hpp" 1
# 1 "/home/samuel/Documents/Programming/cvlab/cosc428/lab1/teapot/platforms/lab/linux-debug/include/opencv2/ml.hpp" 1
1 error generated.

So, the odd relative path is working in a way, but causes some buggy behaviour.

My gut feeling is that the current situation is not optimal. There are a couple of points:

1/ Using relative includes ("") with relative paths would simply make more sense and possibly give better errors. 2/ Using system includes (<>) might make more sense and be more easily readable.

I'm going to submit a PR for 1 but it's up to you guys as a team to discuss what's best for OpenCV.

alalek commented 8 years ago

Thanks for update! So, these files need to be fixed to use information about enabled modules: https://github.com/Itseez/opencv/blob/2.4.12/include/opencv2/opencv.hpp https://github.com/Itseez/opencv/blob/3.1.0/include/opencv2/opencv.hpp I will take a look on this.

Anyway, includes like #include "core/base.hpp" or even #include "base.hpp" are very ambiguous: you can go into another project with same header if expected relative path doesn't found. There is still a large part of dangerous implicit behavior (system package manager "adds" system-wide OpenCV to your project implicitly - it is the one of sources for this problem). Includes like #include "../opencv2/core/core.hpp" may help somehow in some cases, but it is too verbose and requires massive renaming.

BTW, Any massive renaming is not acceptable without a serious critical reason.

ioquatix commented 8 years ago

I can't imagine any case where the correct relative path would not be found. This technique is used by Qt.

Sent from my phone.

On 20/01/2016, at 3:38 PM, Alexander Alekhin notifications@github.com wrote:

Thanks for update! So, these files need to be fixed to use information about enabled modules: https://github.com/Itseez/opencv/blob/2.4.12/include/opencv2/opencv.hpp https://github.com/Itseez/opencv/blob/3.1.0/include/opencv2/opencv.hpp I will take a look on this.

Anyway, includes like #include "core/base.hpp" or even #include "base.hpp" are very ambiguous: you can go into another project with same header if expected relative path doesn't found. There is still a large part of dangerous implicit behavior (system package manager "adds" system-wide OpenCV to your project implicitly - it is the one of sources for this problem). Includes like #include "../opencv2/core/core.hpp" may help somehow in some cases, but it is too verbose and requires massive renaming.

BTW, Any massive renaming is not acceptable without a serious critical reason.

― Reply to this email directly or view it on GitHub.

ilya-lavrenov commented 7 years ago

@alalek, can we close the issue?

ioquatix commented 7 years ago

Well, IMHO, this is still broken, and issue #6024 above is just another example of the buggy behaviour.

It's well defined how #include with relative paths work and the way it's being used here is at the very best unclear and at the very worst invalid (preprocessor may not resolve #include "..." using system include paths).

Logically, if you are in the file $include/opencv2/opencv.hpp, the path to $include/opencv2/objdetect.hpp is either ../opencv2/objdetect.hpp or objdetect.hpp, but not opencv2/objdetect.hpp. I don't think this point is debatable - it's a fact.

As shown above, the way that the include file is resolved is highly roundabout - from opencv2/opencv.hpp, #include "opencv2/objdetect.hpp" constructs the relative path $include/opencv2/opencv2/objdetect.hpp which doesn't exist within user header search path, so it ends up searching through system header paths (for opencv2/objdetect.hpp), which eventually hits the correct file, or in some cases, the incorrect one.

The case where it hits the incorrect file is as follows: If you have a custom install of opencv2 in a local -I (system include path) directory, let's say /usr/local/myproject/include/opencv2 without objdetect compiled, and a system one (e.g. older but does include objdetect) in /usr/include, when you try to include a file which wasn't compiled into your local install, but was installed into the system install, when trying to resolving opencv2/objdetect.hpp, it first tries opencv2/opencv2/objdetect.hpp which clearly doesn't exist, the it may try /usr/local/myproject/include/opencv2/objdetect.hpp which also doesn't exist, finally it ends up getting /usr/include/opencv2/objdetect.hpp. Of course, this is buggy behaviour. The correct result would be that the header wouldn't be found and an error given.

There are two options to fix this problem:

1/ Use correct relative paths, as proposed above. Relative path means a path relative to the directory the file is in, and can refer to the other file correctly. This is, IMHO, the correct fix. 2/ Don't use #include "..." but instead use #include <...>. At least this makes it clear what your intentions are (i.e. to use the file in the system include directory). This would still lead to buggy behaviour (if you try to include files which don't exist in the current install but do elsewhere) but at least it wouldn't be so confusing why it's happening.

The above options in theory should be more efficient too, since the compiler would be doing at least one less stat per #include directive.

arpita8 commented 6 years ago

I am getting this error may i know what's wrong, i am using open cv version 3.1

screen shot 2017-09-22 at 10 19 15 pm screen shot 2017-09-22 at 10 19 05 pm
Aashima-Gupta commented 5 years ago

Hi, i have downloaded opencv SDK however i am unable to find this opencv2 folder anywhere, do i need to download anything else to integrate opencv in android studio? Since android studio is giving errors like : #include <opencv2/contrib/detection_based_tracker.hpp> file cannot be found #include "opencv2/contrib/contrib.hpp" file cannot be found

Aashima-Gupta commented 5 years ago

ok . I got the opencv2 folder containing .hpp files, but as per my project contrib.hpp file is missing, then how can i download such header files externally?

glubsy commented 5 years ago

@Aashima-Gupta what system are you using? Arch Linux by any chance? Might be a problem with how opencv is installed. (having some issues myself on Arch, asking just in case)

Potomac commented 5 years ago

same problem with opencv 4.0.1-4 in archlinux, the includes files are in the path "/usr/include/opencv4/",

but inside this path there is a subfolder "opencv2" :

/usr/include/opencv4/opencv2/

which brings problem for some includes, for example :

/usr/include/opencv4/opencv2/core/core.hpp:48: error : opencv2/core.hpp: No such file or directory

include "opencv2/core.hpp"

Potomac commented 5 years ago

/usr/include/opencv4/opencv2/core/core.hpp is a perfect example of the problem, inside this file we can read this :

include "opencv2/core.hpp"

but there is no "opencv2" subdirectory in the path "/usr/include/opencv4/opencv2/core/", that's why the preprocessor will trigger this error :

error : opencv2/core.hpp: No such file or directory

include "opencv2/core.hpp"

ioquatix commented 5 years ago

I agree, this is still a bug, and the correct solution is to use relative paths for #include within the code where the target is some header relative to the current path (i.e. not from another library or system header).

Potomac commented 5 years ago

maybe someone can make a patch (bash script) in order to fix incorrect paths in include files present in /usr/include/opencv4, it could be useful for linux distro packagers like archlinux,

a script with sed command in order to edit automatically these incorrect paths in include files, and then with this patch I can rebuild the opencv archlinux package

alalek commented 5 years ago

You should fix build scripts of your apps. You must add include directory into compiler command line:

P.S. Use CMake's find_package(OpenCV) for reliable build configuration.

ioquatix commented 5 years ago

gcc -I /usr/include/opencv4 ...

It shouldn't be necessary. Should you do this for every directory in /usr/include?

or gcc -isystem /usr/include/opencv4 ...

This is really questionable advice, because warnings are ignored differently when using -isystem.

ioquatix commented 5 years ago

You should fix build scripts of your apps.

I just don't get this mentality, when there is a clear solution, you can fix OpenCV once, or we can live with the poorly specified #include in every app that depends on OpenCV? I just don't see the logic of that. ¯\_(ツ)_/¯

ioquatix commented 5 years ago

Would you be wiling to merge a PR that fixed the issue outlined here or is that a complete waste of time?

Potomac54 commented 5 years ago

You should fix build scripts of your apps. You must add include directory into compiler command line:

* `gcc -I /usr/include/opencv4 ...`

we don't have to do this on linux distros where packages are expected to use standard location for include files ( usually : /usr/include/),

by default when include files are installed in /usr/include then users expect that all includes files are coherent about paths and reachable by gcc, if it's not the case then it's a bad design,

there is a universal principle in programming : the KISS principle (Keep the things "simple", easy to understand), bad, strange, complicated designs must be avoided if there is no justification,

https://en.wikipedia.org/wiki/KISS_principle

for example I don't understand why inside the /usr/include/opencv4/opencv2/core/core.hp file there is an include file written like that : #include "opencv2/core.hpp",

it should be #include "core.hpp" (because we are already in "/usr/include/opencv4/opencv2/core/" path when the preprocessor read the file "/usr/include/opencv4/opencv2/core/core.hp" )

it can be also #include <opencv4/opencv2/core/core.php> as by default all includes files are installed in the standard system include path "/usr/include" in a lot of linux distros (when opencv is provided as package),

there is another naming path problem : why opencv team decided to append the release version number of opencv in the name of the include directory ? (/usr/include/opencv4/opencv2/)

it would be more "kiss" to use an unique path name, like "/usr/include/opencv", for example "/usr/include/opencv/core/core.hpp", this will allow programmers to keep their existing source-code intact (no need to change the version number in the include path name at each major version of opencv)

ioquatix commented 5 years ago

it can be also #include <opencv4/opencv2/core/core.php> as by default all includes files are installed in the standard system include path "/usr/include" in a lot of linux distros (when opencv is provided as package),

The main problem with this is that if you have a local install of opencv, it may try to use system headers when it is not desired. Within any coherent set of headers, I'm of the opinion that relative paths should always be used.

Potomac54 commented 5 years ago

yes you are right, I hope that opencv team will fix this design problem for include files,

otherwise we can create a script as a temporary workaround (I said in bash, but it can be a python script), which will correct automatically the paths inside include files, by detecting non reachable path, the algorithm can be simple to elaborate (detect if the path of the #include is reachable, if not then correct it by using relative path)

glubsy commented 5 years ago

In my case, I had to patch my application by tweaking the cmake scripts and some source files to work around the issue.

ansoni-san commented 5 years ago

I STILL cannot believe this is still an issue this far down the line.

Absolutely terrible. There is really no excuse for why it shouldn't be fixed.

CognitiveClouds-Prasad commented 5 years ago

I am facing a similar issue. The problem here is in compilation of Aruco and I am trying to figure out a solution for this.

wizcheu commented 5 years ago

My solution is to set header search path to "/usr/local/Cellar/opencv/4.1.0_2/include/opencv4/opencv2". My enviroment is macos, xcode.

ansoni-san commented 4 years ago

@alalek can this be re-opened?

It’s clearly still an issue. Your include style is non-standard and in some system setups with multiple opencv2 headers available (system-wide vs local or user specific) it is impossible to pull in the right headers.

I believe most of the issues are being hidden by pkg-config.

alalek commented 4 years ago

Standard says nothing about side-by-side installation of multiple versions of library.

it is impossible to pull in the right headers

Current approach make impossible to pull the incorrect headers, due implicit requirement of headers path (include/opencv4 - applied automatically by recommended CMake's find_package(OpenCV)).

Unfortunately old system packages are stuck with "explicit" legacy layout (like OpenCV 2.4.x) and they broke improperly configured builds (installing anything into /usr/local should be considered as bad idea - especially without proper uninstalling during upgrade). This can't be fixed from OpenCV side due misconfiguration of user builds.

Original issue has been resolved, so avoid off topic discussions here.

If you want help collect logs like in comments above and create question on Users OpenCV Q/A forum: http://answers.opencv.org

quimnuss commented 4 years ago

Understood, which thread should we use to keep reporting on these include issues?

I'm using Find_Package(OpenCV) and the compiler was still failing to find the headers although the header path was correctly included. I've fixed it by adding the softlink (!)

sudo ln -s /usr/include/opencv4/opencv2/ /usr/include/opencv2

on archlinux with repository's opencv (opencv4.1.1)

ioquatix commented 4 years ago

My understanding is that this issue is not resolved because relative includes are not used and therefore it can pull in the wrong headers as evidenced by many people here reporting the same problem.

fbarulli commented 4 years ago

so, any updates on this?

DunZek commented 3 years ago

Understood, which thread should we use to keep reporting on these include issues?

I'm using Find_Package(OpenCV) and the compiler was still failing to find the headers although the header path was correctly included. I've fixed it by adding the softlink (!)

sudo ln -s /usr/include/opencv4/opencv2/ /usr/include/opencv2

on archlinux with repository's opencv (opencv4.1.1)

I stopped receiving the #include errors because of your fix (using Ubuntu 20.04.1 LTS). Thank you. Also, afterwards I had encountered "linker" issues apparently (my code wasn't being compiled to create an output file to execute). It was fixed when I looked into this issue

sisrfeng commented 3 years ago

sudo ln -s /usr/include/opencv4/opencv2/ /usr/include/opencv2

on archlinux with repository's opencv (opencv4.1.1) Tried but got: Too many symbolic link

drank40 commented 2 years ago

This is somehow still a problem 5 years later. Absolutely ridiculous.

KangChou commented 1 year ago

image image