cython - distutils vs cmake:链接libpython?

时间:2013-03-23 06:46:30

标签: python cmake cython distutils

我曾经问过另一个问题,这个问题对于一个直接的答案来说有点过于复杂,所以我把它归结为这个基本问题......

当我使用标准的cython distutils构建我的aModule.so时,它似乎与libpython无关:

$ otool -L aModule.so
aModule.so:
    /usr/local/lib/libboost_thread-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/opt/thrift/lib/libthrift-0.9.0.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)

但是当我使用cmake设置构建时,它会继续生成一个链接命令,将libpython链接到.so:

$ otool -L aModule.so 
aModule.so:
    /System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.1)
    /usr/local/opt/thrift/lib/libthrift-0.9.0.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_thread-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

distutils生成的模块似乎可以与我的任何python2.7安装(系统或我的项目的virtualenv)一起使用。当我尝试使用除链接系统python之外的任何东西导入时,cmake崩溃时版本不匹配。

为什么distutils模块在没有链接的情况下工作正常?如果是这样的话,为什么我需要让cmake构建链接libpython,如果是这样的话我怎么能阻止它以便它可以与我的任何python2.7解释器一起工作而不会崩溃?

目前我可以使用:CXX=g++ cmake -DPYTHON_LIBRARY=/path/to/another/Python

指示右侧python的cmake

1 个答案:

答案 0 :(得分:5)

我意识到问题的根源与cython-cmake-example及其UseCython.cmake cython_add_module()函数如何将库与libpython明确链接有关。

我最终为自己的用途做了什么,因为我不知道这是否是一个完全可移植的解决方案,就是在该函数中添加一个标志来说DYNAMIC_LOOKUP

function( cython_add_module _name _dynamic_lookup )
  set( pyx_module_sources "" )
  set( other_module_sources "" )
  foreach( _file ${ARGN} )
    if( ${_file} MATCHES ".*\\.py[x]?$" )
      list( APPEND pyx_module_sources ${_file} )
    else()
      list( APPEND other_module_sources ${_file} )
    endif()
  endforeach()
  compile_pyx( ${_name} generated_file ${pyx_module_sources} )
  include_directories( ${PYTHON_INCLUDE_DIRS} )
  python_add_module( ${_name} ${generated_file} ${other_module_sources} )
  ### Added here ##
  if( ${_dynamic_lookup} )
    message( STATUS "Not linking target ${_name} against libpython" )
    set_target_properties( ${_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
  else()
    target_link_libraries( ${_name} ${PYTHON_LIBRARIES} )
  endif()
endfunction()

现在我可以调用cython_add_module,它不会链接到libpython。