-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
Package-supplied CMake support [was: opencv issues] #77
Comments
Slightly related to #6 , as the use of a highly atypical CMake setup in https://github.com/Microsoft/vcpkg/blob/master/docs/EXAMPLES.md#example-1-2-b has hidden the problem. |
This is a serious issue, thank you for bringing it up and laying out the situation so clearly. While option 2 is the most immediate (with the assumption it doesn't prevent any other of our lint checks from working), I'd first like to make sure we completely explore the cost/benefit of option 1. For option 1, it is certainly true that we would need to alter the installation of many packages that deploy CMake scripts. I'll make a ballpark guess that this is 20% of all packages. What's the minimum needed change (to each package) to make that work? Is it required to patch the The benefits of option 1 are simplicity (for users), consistency, and reliability. It is easy to automatically determine post-installation whether a given package has provided CMake support. If there is an extremely common location that 50%+ of packages currently use (as you mentioned above, perhaps Taking a look at Debian, I see that (at least for opencv), the files are deployed to |
The typical patch would involve changing the
However if we choose this option, I strongly suggest discussing with CMake upstream to modify the examples in https://cmake.org/cmake/help/v3.3/manual/cmake-packages.7.html to have a CMake variable (such as
I am not aware of any "reliable post-processing" trick to change the relative position of the CMake configuration files in the install layout, but it may be worth to ask for the same question in the CMake mailing list.
Recently I raised a concern with the CMake devs about the fact that in Windows
|
I've massaged OpenCV a bit more, so I have some empirical findings to report. First, Option 2 (in its purest form) will not work for multi-configuration generators (like Visual Studio). This is because we install to multiple roots in order to provide both Debug and Release versions of libraries and the respectively installed cmake scripts are tied to the particular version installed. For example, if we do not manipulate the outputs at all, we'll get something like
When configuring a cmake project that uses OpenCV, it will only pull in the Debug or Release file, not both. This causes multi-configuration generators to fail in either Debug or Release mode. Fortunately, the file(READ ${CURRENT_PACKAGES_DIR}/debug/share/opencv/OpenCVModules-debug.cmake OPENCV_DEBUG_MODULE)
string(REPLACE "\${_IMPORT_PREFIX}" "\${_IMPORT_PREFIX}/debug" OPENCV_DEBUG_MODULE "${OPENCV_DEBUG_MODULE}")
file(WRITE ${CURRENT_PACKAGES_DIR}/share/opencv/OpenCVModules-debug.cmake "${OPENCV_DEBUG_MODULE}") I've confirmed that this works in an external project using the VS generator in both Debug and Release. Secondly, OpenCV's default installation behavior on Windows tries to place binaries in subfolders based on architecture. Since we are handling architecture-specific locations, we need to modify this anyway. This causes the Windows-specific cmake files to no longer point to the correct locations, but the Unix ones are actually correct! So, I had to make approximately 4 lines of modification to adjust to using the Unix paths, with one more line of modification enabling external override of the cmake config directory. I've pushed changes to the opencv port that include all the above modifications. Since OpenCV in particular is no longer an issue here, I think the right course of action is to continue requesting cmake files to be placed in Does this sound reasonable to you? It may also make sense to open a thread on the CMake Mailing List to confirm my above conclusions. |
I see. I wonder if the fix for the autogenerated On the other hand, automatically accounting for all the logic present in
Yes. The ideal situation for me would be that a project with a "state-of-the-art" CMake build system (such as the one described in https://cmake.org/cmake/help/v3.3/manual/cmake-packages.7.html#creating-relocatable-packages) could be packaged in I think it may be worth to also add some notes to the packaging documentation (see https://github.com/Microsoft/vcpkg/blob/master/docs/EXAMPLES.md#suggested-example-portfiles), mentioning that for CMake-based libraries there are problems in correctly relocating config packages, that at the moment must be solved in a package-specific way.
Yes, I think in general the CMake community has always been interested in sane ways of installing and finding C++ dependencies, so I think they could be very interested in finding the best possible solution to this issue. Thanks a lot for your effort on this. |
By the way, I just realized something (perhaps obvious): why install files that contain references to architecture-dependendent files such as |
The note about |
I am having an issue on one of my dev machines, and I am wondering if anybody has some insight. I am just following the doc (using CMAKE_TOOLCHAIN_FILE), and it works at least one machine (after setting CMAKE_PREFIX_PATH to "...vcpkg/installed/x86-windows/share/opencv"). But, on another machine, I get this error: Found package configuration file: but it set OpenCV_FOUND to FALSE so package "OpenCV" is considered to be NOT FOUND. The two machines have exactly the same setup in terms of VS 2017 update and vcpkg source snapshot, etc. And yet, it does not work on one machine. I tried everything I could think of (setting/unsetting OpenCV_DIR, etc.), but nothing helps. I have no problem using my own OpenCV builds or nuget package. It's very likely that the problem has something to do vcpkg. Any input will be greatly appreciated. |
You shouldn't need to set cmake prefix path to that -- the toolchain file should take care of everything. Just to sanity check: Vcpkg list returns the same on both machines? What opencv package version is returned by list? Can you run your project's cmake configure with debug information (or trace mode) and send any weird bits to [email protected]? |
Thanks for the quick reply, @ras0219-msft. Although I didn't do side-by-side comparison (one is a work computer and the other is a computer I use at home), things appeared correct on my work computer (which I'm having this problem with). Come to think of it, there are a few differences: My home computer has VS2015 Community and VS2017 RC2 Community, and my work computer has VS2015 Enterprise and VS2017 RC2 Community. The home computer I used has Intel i7 and my work computer has an AMD processor (cannot remember the exact processor name right now). Also, I remember setting VCPKG(?) env variable on my home computer, but I didn't do that for the work computer. (I started using VS tools for cmake + vcpkg yesterday, and I've been trying out different things. The doc is not entirely clear as to what step is optional and what step is required, etc.) I installed vcpkg at the top level (C:) on my home computer, but it was installed in a subdirectory below some levels on the other (meaning a longer path). When I get back to work next week, I'll try this again, and if I find anything notable, I'll send you the information. Thanks! |
Thanks for the very detailed information. We should insulate ourselves from all of those differences, if any of those end up being the root cause, that's a bug we need to fix! For debugging, I would recommend using cmake from the command line and completely deleting the build directory between trials. If you run cmake --help, there are a few diagnostic switches you can throw to find out exactly where the import fails. |
Just to follow up, I no longer have this problem. I cleaned up all old opencv installations and removed all related opencv env vars, and rebooted the machine. Now I can cmake, build, and run a simple opencv test app with no problems. Thanks! |
…hat vcpkg imported targets will find the expected files at the right places. This problem appears to be pretty common amongst CMake-based vcpkg ports and is discussed in depth here:microsoft#77
Updated port libdjinterop to version 0.19.2
To test
vcpkg
, I tried to compile a simple cmake-based OpenCV example:https://gist.github.com/traversaro/d8c7de12480433fc6820743f44a38d88
Following https://github.com/Microsoft/vcpkg/blob/master/docs/EXAMPLES.md#example-1-2-b ,
I successfully installed opencv with
./vcpkg install opencv
.I then tried to compile the CMake OpenCV example using:
The first problem was that
find_package(OpenCV REQUIRED)
was not working due to a wrong value ofCMAKE_PREFIX_PATH
set in the toolchain file. I fixed this little issue (see #76) but then I was faced by a more serious error:This error is caused by this line (and the following) in the
portfile.cmake
:https://github.com/Microsoft/vcpkg/blob/master/ports/opencv/portfile.cmake#L57
The problem is that relocatable CMake imported target files (the one tipically created using
install(TARGETS ...)
, see https://cmake.org/cmake/help/v3.5/manual/cmake-packages.7.html#creating-relocatable-packages) encode the relative positions in the installation layout of the include directories and of the libraries file with respect to themselves. For this reason, they cannot be moved relatively to the other installation includes and libraries.Unfortunately trying to remove this arbitrary change of location of the
OpenCVModules.cmake
file in theportfile.cmake
is impossible, because apparently there is a rule that imposes that all.cmake
files should be in theshare/<package>
location.At the moment this means that all the CMake libraries that do not install their installed targets directly in
share/<package>
cannot be found using their<package>Config.cmake
in vcpkg. Note that CMake documentation itself suggests to install the CMake config files and the installed targets inlib/cmake/<package>*/
(see https://cmake.org/cmake/help/v3.5/manual/cmake-packages.7.html#id14). So, even a new package following exactly the CMake documentation cannot be properly packaged using CMake and vcpkg.Possible solutions
Two possible solution I can think of:
Patch all projects to install their CMake config files in
share/<package>
This solution involve patching (or calling the build with an appropriate option, if the build system has an option for that) all projects' CMake files to install their exports directly in
share/<package>
.This would be undesirable as the vast majority of existing project would require a patch.
Do not constrain the port to install cmake files in
share/<package>
This solution is the one used by all the package manager that I am aware of: they permit to install the cmake configuration files whenever the upstream prefer. As long as this path is in the
find_package
search path, the library can be easily found. This would drastically simplify the writing of theportfile.cmake
s, but I do not know if this conflicts some othervcpkg
requirement.The text was updated successfully, but these errors were encountered: