[compile error] FLANN not supported any more on Windows
Describe the error
Hello,
We are into some trouble compiling PCL on Windows. In particular, compiling with support of
- Eigen 3.4.0
- Boost 1.88.0
- VTK 9.5.0
- QHull 8.0.2
alone works fine. However, including FLANN seems to be broken.
To Reproduce
First, FLANN has to be compiled, but seems to be unmaintained. The latest release 1.9.2 does not compile on Windows (due to a pkg config dependency), whereas 1.9.1 does compile, but needs a few adjustments to work with the latest Visual Studio/compiler updates:
#include <functional>is missing inflann/util/heap.h, which can be fixed by adding/FI functionalto theCMAKE_CXX_FLAGS- Visual Studio tries to compile the files
lz4.c lz4hc.cas C files, however they need to be compiled as C++, which can only be fixed in the generatedvsxprojfile, as the/TPflag is not forwarded by CMake.
With these two fixes, FLANN 1.9.1 compiles. Clearly, so far this is independent of PCL, still compiling PCL has the same issues.
Thereafter, including FLANN in the PCL build by defining FLANN_INCLUDE_DIR and FLANN_LIBRARY_STATIC accordingly while running CMake works fine, however compiling PCL thereafter will fail.
We analyzed the issues and according to our tests, the following steps are necessary to fix the issues:
- Define
CMAKE_CXX_STANDARD=14asstd::random_shuffle()is used by FLANN (e.g.flann/util/random.h), but unavailable with C++17. - The
#include <functional>is missing such that adding/FI functionaltoCMAKE_CXX_FLAGSresolves this, too. - The definition
/DEIGEN_MAX_ALIGN_BYTES=32is required due to warning statingPotential runtime error due to aligned malloc mismatch!. - The two files
kiss_fft.candkiss_fftr.cneed to be compiled explicitely as C++.
Surprisingly, these issues seem not to be discussed here so far. Is FLANN not supported by PCL on Windows any more? It seems rather complicated to use, and nanoflann is not a full replacement yet, as several modules are not available with nanoflann alone.
Your Environment (please complete the following information):
- OS: Windows 11
- Compiler: Visual Studio 2022 Version 17.14.7
- PCL Version: Master
- PCL Type: Compiled from source
If PCL was compiled from source or failure in compiling PCL itself:
- GPU, Kinfu, CUDA enabled? No
- List and Version of dependencies used: see above
- Compilation flags used: Paths to the dependencies are set explicitly, everything else are default.
Possible Solution
Manually changing the build configuration flags as described.
Do you gather all sources individually? I would probably try to use VCPKG for dependencies. Most of them is up-to-date, except vtk is currently 9.3.
I have it installed (well, only on boost 1.86, but that shouldn't matter) and it works well.
I'm also struggling with this issue. :( If you find a good solution please let me know.
I'm also struggling with this issue. :( If you find a good solution please let me know.
All of it - or specific parts 😄 ?
The definition /DEIGEN_MAX_ALIGN_BYTES=32 is required due to warning stating Potential runtime error due to aligned malloc mismatch!.
Often seems to be related to whether AVX as been probably enabled for both PCL and subproject, so the same align is used. Else you'll end up with runtime errors about freeing the memory.
As he says, FLANN 1.9.2 has problems. So, I'm using FLANN 1.9.1 yet.
As he says, FLANN 1.9.2 has problems. So, I'm using FLANN 1.9.1 yet.
Ah, okay. Yeah, VCPKG has recently updated to use the latest commit from FLANN. There might have been some fixes, not yet released.
And VCPKG also apply local patches to fix things that aren't working, so they might have solved some of the issues seen here.
Correct, we are compiling the dependencies ourselves and FLANN 1.9.2 does not work. However, even FLANN 1.9.1 does not compile with latest VS releases any more. There is a missing #include <functional> and the two .c files have to be compiled explicitly as C++. Thereafter, FLANN compiles, but there are also problems with compiling PCL (cf. details described above).
In the future, maybe all the code might be migrated from FLANN to Nanoflann? However, we think a short-term solution would be to create a fork of the FLANN code, fix everything that it works with PCL or even remove the FLANN dependency at all and include the FLANN source files directly into PCL.
I can soon start working on making nanoflann a full replacement for FLANN in PCL, so that FLANN is optional and no PCL functionality is lost when FLANN is not available.
[...] include the FLANN source files directly into PCL.
This is not a good idea in my opinion. This has been done with source code from other projects in the past, and we are still cleaning that up.
we think a short-term solution would be to create a fork of the FLANN code, fix everything that it works with PCL
I am open to this idea (fork to github.com/PointCloudLibrary/flann). Only fixes for compilation failures, and maybe not indefinitely. On the other hand, this would likely be identical to the set of patches that vcpkg has https://github.com/microsoft/vcpkg/tree/master/ports/flann , as Lars mentioned).
The two files kiss_fft.c and kiss_fftr.c need to be compiled explicitely as C++.
@CSBVision Can you elaborate on this? Why?
Correct, we are compiling the dependencies ourselves and FLANN 1.9.2 does not work. However, even FLANN 1.9.1 does not compile with latest VS releases any more.
Indeed it seems you need to clone master branch, then with the patch to correctly find lz4 from VCPKG, I could build all of FLANN with VS2022 17.14.7.
The two files kiss_fft.c and kiss_fftr.c need to be compiled explicitely as C++.
@CSBVision Can you elaborate on this? Why?
The error is #error: error STL1003: Unexpected compiler, expected C++ compiler., which is thrown in file yvals_core.h. This file is provided by Visual Studio and contains:
#ifndef __cplusplus
#error error STL1003: Unexpected compiler, expected C++ compiler.
#endif // !defined(__cplusplus)
Compiling these two files in C++ mode (/TP) resolves the issue. As there are named .c, VS will default to compiling in C mode, which does not define __cplusplus and we receive that error.
Indeed it seems you need to clone master branch, then with the patch to correctly find lz4 from VCPKG, I could build all of FLANN with VS2022 17.14.7.
Just wanted to give that a try... we're not using vcpkg, thus I manually patched the files. This requires to manually provide lz4 (did that, too), then CMake configuration works, but compilation does not find the lz4.h header. Even though it is available in the lz4 installation, which is found by CMake. Personally, I think patching version 1.9.1 is the simpler alternative.
Is there maybe a patched repo of Flann available somewhere? If so, then we might stick with that, or create one as part of PCL? Or is migrating all code to Nanoflann soon a feasible alternative such that FLANN isn't required any more?
The error is
#error: error STL1003: Unexpected compiler, expected C++ compiler., which is thrown in fileyvals_core.h. This file is provided by Visual Studio and contains:#ifndef __cplusplus #error error STL1003: Unexpected compiler, expected C++ compiler. #endif // !defined(__cplusplus)Compiling these two files in C++ mode (
/TP) resolves the issue. As there are named.c, VS will default to compiling in C mode, which does not define__cplusplusand we receive that error.
@CSBVision Can you provide a file trace for the error? So via which include path does kiss_fft.c pull in yvals_core.h? To my knowledge, kiss_fft.c and kiss_fftr.c should be compilable as C-code (not C++-code).
I found this: https://stackoverflow.com/questions/72907548/expected-c-compiler-error-in-yvals-core-h but iostream or iostream.h is not included by kiss_fft.c or kiss_fftr.c. Do you use precompiled headers?
Actually it seems to be pulled in by /FI functional, which is required for FLANN. However, this definition is part of CMAKE_CXX_FLAGS and, thus, ideally should have no effect for .c files. Anyway, fixing everything inside FLANN fixes this, too, such that /FI functional is not needed any more.
In particular, we tested to build FLANN 1.9.1 with the following patch:
- add
#include <functional>inflann/util/heap.h - do not add
/FI functionalto theCMAKE_CXX_FLAGS
Here, FLANN builds fine and including in PCL works, too.
So maybe forking FLANN 1.9.1 and include this patch is all we need until everything is ported to Nanoflann? Maybe also the master version together with aforementioned vcpkg patches could be used. However compiling/using is more complicated here and might not be required at all until everything is migrated to Nanoflann.
Still, this setting ideally includes two modifications:
- Stick with C++14 (or patch FLANN to support C++17), i.e. PCL should not default to C++17.
- We propose to auto-detect whether
/DEIGEN_MAX_ALIGN_BYTES=32should be defined as well (we think it should whenever AVX is enabled).
What you think?
Correct, we are compiling the dependencies ourselves and FLANN 1.9.2 does not work. However, even FLANN 1.9.1 does not compile with latest VS releases any more.
Indeed it seems you need to clone master branch, then with the patch to correctly find lz4 from VCPKG, I could build all of FLANN with VS2022 17.14.7.
I have confirmed this. It builds successfully PCL with FLANN 1.9.2 (master). Thanks, https://gist.github.com/UnaNancyOwen/1e3fced09e4430ad0b7b#file-flann1-9-2_master-md
For your information: I started working on making nanoflann a full replacement for FLANN, but there is still a lot more work needed: https://github.com/PointCloudLibrary/pcl/compare/master...mvieth:pcl:nanoflann_default
@larshg I am thinking about adding a new function:
template<typename PointT>
Search<PointT> * autoSelectMethod(const typename pcl::PointCloud<PointT>::ConstPtr& cloud,
bool sorted_results, std::uint32_t purpose=0);
which would select the fastest search method for the given point cloud (OrganizedNeighbor if cloud is organized, otherwise nanoflann if available, or FLANN if available, and PCL's octree might also have a niche use case). Usually, it would be given to a shared_ptr, like this: searcher_.reset (pcl::search::autoSelectMethod<pcl::PointXYZ>(cloud, false));
The optional purpose parameter can be used to specify what it will be used for, perhaps pcl::search::RADIUS_SEARCH if it will be used for radius searches, pcl::search::1_KNN_SEARCH for nearestKSearch with k=1 (e.g. registration methods), or pcl::search::MANY_KNN_SEARCH if k>1. Then the autoSelectMethod function can further use that information to choose the optimal method, or tune e.g. the tree leaf size for the specific purpose.
What's your opinion on this?