Algomorph/pyboostcvconverter

CMake error message related to Boost - Building in Anaconda3 (64 bit) in Windows 10

Closed this issue · 22 comments

I am trying to build the code in Anaconda3 (64 bit) in Windows 10 using CMake. This is the error message that I get when I run CMake:

Could not find a package configuration file provided by "boost_python-py38"
  (requested version 1.76.0) with any of the following names:

    boost_python-py38Config.cmake
    boost_python-py38-config.cmake

  Add the installation prefix of "boost_python-py38" to CMAKE_PREFIX_PATH or
  set "boost_python-py38_DIR" to a directory containing one of the above
  files.  If "boost_python-py38" provides a separate development package or
  SDK, be sure it has been installed.

The problem seems to be Boost. For the building of Boost , I use the command that you have recommended:
bootstrap.bat
b2 toolset=msvc-14.1 release debug runtime-link=shared link=static --build-type=complete --abbreviate-paths architecture=x86 address-model=64 install -j4

I haven't tested with Anaconda3, but I suppose it shouldn't be too different from stock Python3.

  1. Which version of VisualStudio are you using to build Boost?
  2. Do you have BOOST_ROOT, BOOST_DIR, or Boost_DIR environment variables set, and, if so, to which values?
  3. Which version of Boost do you have deployed?

I have Visual Studio 14 2015.

Regarding the Boost variables, I have set only BOOST_ROOT when I call cmake:
cmake -DCMAKE_GENERATOR="Visual Studio 14 2015" -DBOOST_ROOT=C:/Boost/ ../

I have downloaded the last version of Boost: 1_76_0

My Boost/ folder contains the folders include/ and lib/. In the include/ folder there is boost-1_76/boost/

I'm surprised the build worked. You'd need "toolset=msvc-12.0" instead of "toolset=msvc-14.1" for VS 14 / 2015. I believe BOOST_ROOT only works for the 1.69 version of Boost. For the one you're using, try setting Boost_DIR instead like I describe here. If that doesn't work, let me know which Boost python libraries you have inside your /lib folder there.

Also, from my description in the README:

the include directory should have a "boost" subdirectory with all the headers, not boost-1_68/boost as is done by the build automatically

I have tried to compile Boost with msvc-12.0 and to run CMake with -DBoost_DIR instead of -DBOOST_ROOT:

bootstrap.bat
b2 toolset=msvc-12.0 --prefix=C:/Boost4/ release debug runtime-link=shared link=static --build-type=complete --abbreviate-paths architecture=x86 address-model=64 install -j4
cmake -DCMAKE_GENERATOR="Visual Studio 14 2015" -DBoost_DIR=C:/Boost4/ ../

I have tried to run CMake with the Boost folder configurations C:/Boost4/include/bost-1_76/boost and C:/Boost4/include/boost/

Now, I get the following error message:

CMake Warning at C:/Users/crocis/anaconda3/Lib/site-packages/cmake/data/share/cmake-3.21/Modules/FindBoost.cmake:2186 (message):
No header defined for python-py38; skipping header check (note: header-only
libraries have no designated component)
Call Stack (most recent call first):
CMakeLists.txt:59 (find_package)

CMake Error at C:/Users/crocis/anaconda3/Lib/site-packages/cmake/data/share/cmake-3.21/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find Boost (missing: python-py38) (found version "1.76.0")
Call Stack (most recent call first):
C:/Users/crocis/anaconda3/Lib/site-packages/cmake/data/share/cmake-3.21/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
C:/Users/crocis/anaconda3/Lib/site-packages/cmake/data/share/cmake-3.21/Modules/FindBoost.cmake:2345 (find_package_handle_standard_args)
CMakeLists.txt:59 (find_package)

The lib folder contains a CMake folder and a list of lib files: libboost_-vc120-mt-x64-1_76.lib

In the past, I probably install boost with pip install boost. There could be a conflict between the different Boost versions.

By the way, I am still using Boost 1_76_0

Which Boost python libraries you have inside your /lib folder? Should be something like libboost_python3.8-vc120-mt-x64-1_76.lib

If Boost couldn't detect your python installation during the build, it may have skipped building the boost python libraries altogether.

In lib I have found:
libboost_python38-vc120-mt-gd-x64-1_76.lib
libboost_python38-vc120-mt-x64-1_76.lib

Ah, I see. This may be due to a recent CMake upgrade of some kind.
I'm suspecting this line isn't working correctly anymore:

find_package(Boost COMPONENTS python${PYTHON3_VERSION_MAJOR}${PYTHON3_VERSION_MINOR} QUIET)

I'll try to investigate the issue shortly.

Which Cmake version are you using?

I have just upgrated CMake to version 3.21.0. Before upgrading CMake, I had had different error messages but all related to the Python component of Boost.

I was unable to replicate your issue with CMake 3.15 or CMake 3.21.0. What I also encountered was that the Boost_DIR environment variable should be set to the location of BoostConfig.cmake, e.g. C:\Boost4\lib\cmake\Boost-1.76.0, not C:\Boost4 like for the older versions of Boost.

Also, I found that there is no need to restructure the include folder, e.g. I have C:\boost_1_76\include\boost-1_76\boost

Thank you for your help. What do you recommend me to try next?

Revert to the directory structure after the original boost install and set the Boost_DIR to the location of the BoostConfig.cmake file within the lib folder.

I built again Boost 1.76.0 with the following commands:

bootstrap.bat
b2 toolset=msvc-14.0 --prefix=C:/Boost8/ release debug runtime-link=shared link=static --build-type=complete --abbreviate-paths architecture=x86 address-model=64 install -j4

I used msvc=14.0 for Visual Studio 14 2015.

Then, I successfully generated a Visual Studio solution with CMake by simply specifying the architecture -A x64. Without -A x64, CMake had problems finding the Boost libraries. This is the CMadke command:

cmake -G "Visual Studio 14 2015" -A x64 -DBoost_DIR=C:/Boost8/lib/cmake/Boost-1.76.0 ../

Next, I built the Visual Studio solution in Release mode, but I got a lot of linker errors. Here some of them:

LNK2038 mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in pyboost_cv2_converter.obj
LNK2038 mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in pyboost_cv2_converter.obj
LNK2019 unresolved external symbol __imp__invalid_parameter referenced in function "public: bool __cdecl std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct _typeobject const *> > >::operator==(class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct _typeobject const *> > > const &)const " (??8?$_Tree_const_iterator@V?$_Tree_val@U?$_Tree_simple_types@PEBU_typeobject@@@std@@@std@@@std@@QEBA_NAEBV01@@z)
LNK2019 unresolved external symbol __imp__CrtDbgReportW referenced in function "public: bool __cdecl std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct _typeobject const *> > >::operator==(class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct _typeobject const *> > > const &)const " (??8?$_Tree_const_iterator@V?$_Tree_val@U?$_Tree_simple_types@PEBU_typeobject@@@std@@@std@@@std@@QEBA_NAEBV01@@z)

You can find the full list of the linker errors here Errors

When building in release mode in Visual Studio, I have replaced libboost_python38-vc140-mt-gd-x64-1_76.lib with libboost_python38-vc140-mt-x64-1_76.lib in the linker configuration. Now, I get only one linker error:

LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl boost::python::objects::py_function_impl_base::py_function_impl_base(void)" (_imp??0py_function_impl_base@objects@python@boost@@qeaa@XZ) referenced in function "class boost::python::api::object __cdecl boost::python::detail::make_function_aux<class cv::Mat (__cdecl*)(class cv::Mat,class cv::Mat),struct boost::python::default_call_policies,struct boost::mpl::vector3<class cv::Mat,class cv::Mat,class cv::Mat> >(class cv::Mat (__cdecl*)(class cv::Mat,class cv::Mat),struct boost::python::default_call_policies const &,struct boost::mpl::vector3<class cv::Mat,class cv::Mat,class cv::Mat> const &)" (??$make_function_aux@P6A?AVMat@cv@@v12@0@ZUdefault_call_policies@python@boost@@U?$vector3@VMat@cv@@v12@V12@@mpl@5@@detail@python@boost@@ya?AVobject@api@12@P6A?AVMat@cv@@v56@0@ZAEBUdefault_call_policies@12@AEBU?$vector3@VMat@cv@@v12@V12@@mpl@2@@z)

I have solved this error by adding

#define BOOST_PYTHON_STATIC_LIB

at the beginning of python_module.cpp

I have tested the Python module from the C++ code and it runs successfully.

Is it correct to replace libboost_python38-vc140-mt-gd-x64-1_76.lib with libboost_python38-vc140-mt-x64-1_76.lib in the linker configuration when building in release mode?

Sorry, I have just seen an error in my previous post. I have replaced libboost_python38-vc140-mt-gd-x64-1_76.lib with libboost_python38-vc140-mt-x64-1_76.lib (no -gd- in the name) in the linker configuration when building in release mode. Is it correct?

-gd- in the name simply specifies that there are debugging symbols in the compiled library. It is correct that to build the release configuration of your app / library, you want to link to the release version of Boost as well. I didn't have to change any flags, add any defines, or rename library when I tested yesterday. However, I was using VS2019 (MSVC 14.2), perhaps there are some subtle differences from VS2015. I'm glad you found a solution!

I've just added another AppVeyor (CI) configuration that demonstrates how to compile Boost 1.73 and pbcvt with Visual Studio 2019.

The relevant cmake command is on this line:

- cmd: if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" ( cmake .. -G %CMAKE_GENERATOR% %VC2019ARCH% -DCMAKE_BUILD_TYPE=%Configuration% -DBUILD_TEST_PROJECT=ON -DPYTHON_DESIRED_VERSION=%REQUESTED_PYTHON_VERSION% -DBoost_DIR=C:\projects\boost_1_73\lib\cmake\Boost-1.73.0 )

If you check around the yaml file, I haven't really changed any of the code / directory structures / filenames. The same goes for the Boost 1.69 / VS 2017 setup.

Hopefully, this will help future generations avoid these issues :-)
Please, reopen if you're still having trouble.