Why does static version of the Boost Python library has a dependency to Python in Windows?
Asked Answered
O

0

1

I'm developing a Python binding for a C++ library using Boost Python. To avoid having issues distributing the Boost libraries, I'm using the static versions. It works fine in Linux and MacOSX, but in Windows, a dependency to Python is still required. My CMakeLists.txt is set as:

if((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") OR APPLE)
     target_link_libraries(my_python_module ${Boost_LIBRARIES})
elseif(WIN32 AND MSVC)
    add_definitions(/DBOOST_PYTHON_STATIC_LIB) # This is also required to force the usage of libboost_python37-vc141-mt-x64-1_70.lib instead of boost_python37-vc141-mt-x64-1_70.lib
    target_link_libraries(my_python_module ${Boost_LIBRARIES}) # This includes the Boost Python library
    # Even though Boost Python library is included statically, in Windows it has a dependency to the Python library.
    target_link_libraries(my_python_module ${Python_LIBRARIES})
endif()

Thus because in Windows, if I remove the target_link_libraries(my_python_module ${Python_LIBRARIES}) line, I get a:

LINK : fatal error LNK1104: Can't open file 'python37.lib'

My resulting DLL has indeed Python as a dependency:

C:\PythonModule\bin\Release\Release>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\dumpbin.exe" /DEPENDENTS my_python_module.dll
Microsoft (R) COFF/PE Dumper Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file my_python_module.dll

File Type: DLL

  Image has the following dependencies:

    python37.dll <------- HERE
    MSVCP140.dll
    VCRUNTIME140.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll
    KERNEL32.dll

  Summary

        B000 .data
        3000 .pdata
       18000 .rdata
        1000 .reloc
        1000 .rsrc
       27000 .text

Since I'm using Boost static libraries, the process is linking against libboost_python37-vc141-mt-x64-1_70.lib, not boost_python37-vc141-mt-x64-1_70.lib (which is the library module associated to the dynamic library, boost_python37-vc141-mt-x64-1_70.dll). I can check this on the command line passed to Visual Studio (thanks to -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON):

Link:
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe /ERRORREPORT:QUEUE /OUT:"C:\PythonModule\bin\Release\Release\my_python_module.dll" /INCREMENTAL:NO /NOLOGO "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_filesystem-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_program_options-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_python37-vc141-mt-x64-1_70.lib"  <------- HERE
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_thread-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_system-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_stacktrace_windbg-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_chrono-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_date_time-vc141-mt-x64-1_70.lib"
  "C:\local\boost_1_70_0\lib64-msvc-14.1\libboost_atomic-vc141-mt-x64-1_70.lib"
  "C:\Program Files\Python37\libs\python37.lib"
  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /PDB:"C:/PythonModule/lib/Release/Release/my_python_module.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/PythonModule/lib/Release/Release/my_python_module.lib" /MACHINE:X64  /machine:x64 /IGNORE:4049,4217 /DLL my_python_module.dir\Release\my_python_module.obj
     Creating library C:/PythonModule/lib/Release/Release/my_python_module.lib and object C:/PythonModule/lib/Release/Release/my_python_module.exp
  my_python_module.vcxproj -> C:\PythonModule\bin\Release\Release\my_python_module.dll

BTW, these are the Boost officially provided binaries, by the way, obtained from https://dl.bintray.com/boostorg/release/1.70.0/binaries/boost_1_70_0-msvc-14.1-64.exe

The static Boost Python library DOESN'T have a dependency to Python, as far as I can check:

C:\local\boost_1_70_0\lib64-msvc-14.1>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\dumpbin.exe" /DEPENDENTS libboost_python37-vc141-mt-x64-1_70.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file libboost_python37-vc141-mt-x64-1_70.lib

File Type: LIBRARY

  Summary

         100 .CRT$XCU
         35A .bss
       17EF8 .chks64
         DD0 .data
         CFE .data$r
        1804 .debug$S
        23B5 .drectve
        5B20 .pdata
        9FD3 .rdata
         EF8 .rdata$r
         4DB .text$di
       32D89 .text$mn
        3F59 .text$x
         608 .text$yd
       11C10 .xdata
         4C0 .xdata$x

While the shared one does:

C:\local\boost_1_70_0\lib64-msvc-14.1>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\dumpbin.exe" /DEPENDENTS boost_python37-vc141-mt-x64-1_70.dll
Microsoft (R) COFF/PE Dumper Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file boost_python37-vc141-mt-x64-1_70.dll

File Type: DLL

  Image has the following dependencies:

    python37.dll <------- HERE
    MSVCP140.dll
    KERNEL32.dll
    VCRUNTIME140.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll

  Summary

        3000 .data
        3000 .pdata
       18000 .rdata
        1000 .reloc
        1000 .rsrc
       1D000 .text

So, my main question is:

Why, if I'm using the static version of the Boost Python library, I still have that Python dependency?

I'm not using Python directly in the module in any other way, and in Linux, such dependency doesn't exist.

Thanks a lot for your help.

Oman answered 27/6, 2019 at 19:35 Comment(3)
"The static Boost Python library DOESN'T have a dependency to Python, as far as I can check" - Not sure what have you checked, but linking isn't used when create a static library, so static libraries by definition has no automatic dependency on the other libraries. However, when link dynamic object with a static library, you need to link with libraries which define symbols for static one. Otherwise you will get "undefined reference" error. BTW, the error LINK : fatal error LNK1104: Can't open file 'python37.lib' looks strange when NOT linking with the library.Parrot
You're right, I (incorrectly) thought I could list the dependencies of a static library using dumpbin. After looking this I realized that can't be done (or maybe it can be done, but I couldn't figure out how). However, I'm certain the libboost_python37.lib static library has a dependency on python37.lib, since the compilation works once I add target_link_libraries(my_python_module ${Python_LIBRARIES}) to my CMake configuration.Oman
I was previously under the (again, incorrect) impression that, by using the static Boost Python library, it would take care of such dependencies to Python (as it does in Linux). It looks that's not true, that Windows precompiled version of the Boost libraries are built using the external dependencies as dynamic.Oman

© 2022 - 2024 — McMap. All rights reserved.