2016-02-12 5 views
2

В настоящее время я пытаюсь построить на Windows (с компилятором Intel) большой проект, который очень хорошо компилируется в UNIX с CMake. Ниже приведен простой пример моей проблемы.Синтаксис CMake/VisualStudio для использования статических библиотек Boost.Python

Запуск следующий простой пример кода с помощью Boost.Python:

#include <iostream> 
#include <Python.h> 
#include <boost/python.hpp> 

int main() 
{ 
    std::string python_home = "C:\\softs\\python\\2.7.9\\64"; 
    char* python_home_char = new char[python_home.length() + 1]; 
    strcpy(python_home_char, python_home.c_str()); 
    Py_SetPythonHome(python_home_char); 
    Py_Initialize(); 

    boost::python::object pyobj_main = boost::python::import("__main__"); 
    boost::python::object glob = pyobj_main.attr("__dict__"); 
    boost::python::exec("print \"Hello from Python\"", glob, glob); 

    Py_Finalize(); 

    return 0; 
} 

Я получаю следующее сообщение об ошибке при выполнении кода:

Программа не может начать работу из-за boost_python-IW -mt-1_57.dll отсутствует на вашем компьютере. Попробуйте переустановить программу, чтобы исправить эту проблему.

Обратите внимание, что у меня нет ошибки, если в конце кода удалить 3 строки boost::python::***. Кроме того, у меня нет какой-либо ошибки, если я скомпилировать следующий пример, используя Boost.Thread (На мой взгляд, он также использовать библиотеки (не только заголовок), правильно ли это?):

#include <iostream> 
#include <boost/thread.hpp> 

boost::mutex mutex_hello; 
void hello(unsigned long int thread_number) 
{ 
    boost::mutex::scoped_lock lock_hello(mutex_hello); 
    std::cout << "Hello from thread " << thread_number << std::endl; 
} 

int main() 
{ 
    boost::thread_group group; 
    for(unsigned long int i = 0; i < 9; ++i) 
     group.create_thread(boost::bind(hello, i + 1)); 
    group.join_all(); 

    return 0; 
} 

Собственно, Я не хочу использовать общие библиотеки, я хочу, чтобы мой исполняемый файл был более статическим, насколько это возможно.

Я строй этого кода со следующим файлом CMake:

cmake_minimum_required(VERSION 2.8.9) 

# Project 
project(TestBoost) 
enable_language(C) 
enable_language(CXX) 
enable_language(Fortran) 

# Compiler info 
if(CMAKE_SYSTEM_NAME STREQUAL "Windows") 
    set(CompilerName "${CMAKE_CXX_COMPILER_ID}") 
    set(CompilerVersion "${CMAKE_CXX_COMPILER_VERSION}") 
    if(CMAKE_CL_64) 
     set(CompilerArch "64") 
    else() 
     set(CompilerArch "32") 
    endif() 
endif() 
string(TOLOWER "${CompilerName}" CompilerName) 
if("${CompilerVersion}" MATCHES "([0-9]+\\.[0-9]+\\.[0-9]+)\\..*") 
    string(REGEX REPLACE "([0-9]+\\.[0-9]+\\.[0-9]+)\\..*" "\\1" CompilerVersion "${CompilerVersion}") 
endif() 

# Libs 
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 

# Intel 
if(CompilerName STREQUAL "intel") 
    string(REGEX REPLACE "(.*)/bin/.*" "\\1" IntelPath "${CMAKE_C_COMPILER}") 
    if(CompilerArch STREQUAL "32") 
     set(IntelArchStr "ia32") 
    elseif(CompilerArch STREQUAL "64") 
     set(IntelArchStr "intel64") 
    endif() 
    set(Compiler_LIBRARY_DIRS "${IntelPath}/compiler/lib/${IntelArchStr}") 
endif() 

# Boost 
set(BOOST_ROOT "C:/softs/boost/1.57.0/${CompilerArch}/${CompilerName}/${CompilerVersion}") 
set(Boost_USE_MULTITHREAD ON) 
set(Boost_USE_STATIC_LIBS ON) 
set(Boost_NO_SYSTEM_PATHS ON) 
set(Boost_ADDITIONAL_VERSIONS "1.57.0" "1.57") 
find_package(Boost 1.57.0 REQUIRED COMPONENTS thread system filesystem python) 

# Python 
set(PythonPath C:/softs/python/2.7.9/${CompilerArch}) 
set(Python_INCLUDE_DIRS ${PythonPath}/include) 
set(Python_LIBRARY_DIRS ${PythonPath}/libs) 
set(Python_LIBRARIES python27) 

# Executable 
include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${Python_INCLUDE_DIRS}) 
link_directories(${Boost_LIBRARY_DIRS} ${Python_LIBRARY_DIRS} ${Compiler_LIBRARY_DIRS}) 
add_executable(test_boost test_boost.cpp) 
target_link_libraries(test_boost ${Boost_LIBRARIES} ${Python_LIBRARIES}) 

Я запустить этот сценарий CMake с начальной записью CMAKE_GENERATOR_TOOLSET набором для Intel C++ Compiler XE 14.0 и задания Intel компилятор, как родной компилятор. У меня нет ошибки или предупреждения при запуске CMake (см. Журнал ниже). Это создает файл TestBoost.sln. При загрузке в Visual Studio Professional 2013 я меняю тип компиляции на Release и изменяю параметры компоновщика цели test_boost, чтобы добавить /NODEFAULTLIB:LIBCMT (обходной путь из-за ошибки в CMake). Затем я компилирую без ошибок.

Вход с CMake:

The C compiler identification is Intel 14.0.4.20140805 
The CXX compiler identification is Intel 14.0.4.20140805 
Check for working C compiler using: Visual Studio 12 2013 Win64 
Check for working C compiler using: Visual Studio 12 2013 Win64 -- works 
Detecting C compiler ABI info 
Detecting C compiler ABI info - done 
Check for working CXX compiler using: Visual Studio 12 2013 Win64 
Check for working CXX compiler using: Visual Studio 12 2013 Win64 -- works 
Detecting CXX compiler ABI info 
Detecting CXX compiler ABI info - done 
The Fortran compiler identification is Intel 
Check for working Fortran compiler using: Visual Studio 12 2013 Win64 
Check for working Fortran compiler using: Visual Studio 12 2013 Win64 -- works 
Detecting Fortran compiler ABI info 
Detecting Fortran compiler ABI info - done 
Determine Intel Fortran Compiler Implicit Link Path 
Determine Intel Fortran Compiler Implicit Link Path -- done 
Checking whether C:/Program Files (x86)/Intel/Composer XE 2013 SP1/bin/intel64/icl.exe supports Fortran 90 
Checking whether C:/Program Files (x86)/Intel/Composer XE 2013 SP1/bin/intel64/icl.exe supports Fortran 90 -- yes 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:515 ] _boost_TEST_VERSIONS = 1.57.0;1.57 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:517 ] Boost_USE_MULTITHREADED = TRUE 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:519 ] Boost_USE_STATIC_LIBS = ON 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:521 ] Boost_USE_STATIC_RUNTIME = 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:523 ] Boost_ADDITIONAL_VERSIONS = 1.57.0;1.57 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:525 ] Boost_NO_SYSTEM_PATHS = ON 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:577 ] Declared as CMake or Environmental Variables: 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:579 ] BOOST_ROOT = C:/softs/boost/1.57.0/64/intel/14.0.4 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:581 ] BOOST_INCLUDEDIR = 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:583 ] BOOST_LIBRARYDIR = 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:585 ] _boost_TEST_VERSIONS = 1.57.0;1.57 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:654 ] Include debugging info: 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:656 ] _boost_INCLUDE_SEARCH_DIRS = C:/softs/boost/1.57.0/64/intel/14.0.4/include;C:/softs/boost/1.57.0/64/intel/14.0.4;NO_CMAKE_SYSTEM_PATH 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:658 ] _boost_PATH_SUFFIXES = boost-1_57_0;boost_1_57_0;boost/boost-1_57_0;boost/boost_1_57_0;boost-1_57;boost_1_57;boost/boost-1_57;boost/boost_1_57 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:678 ] location of version.hpp: C:/softs/boost/1.57.0/64/intel/14.0.4/include/boost-1_57/boost/version.hpp 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:702 ] version.hpp reveals boost 1.57.0 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:787 ] guessed _boost_COMPILER = -iw 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:797 ] _boost_MULTITHREADED = -mt 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:840 ] _boost_RELEASE_ABI_TAG = - 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:842 ] _boost_DEBUG_ABI_TAG = -gd 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:890 ] _boost_LIBRARY_SEARCH_DIRS = C:/softs/boost/1.57.0/64/intel/14.0.4/lib;C:/softs/boost/1.57.0/64/intel/14.0.4/stage/lib;C:/softs/boost/1.57.0/64/intel/14.0.4/include/boost-1_57/lib;C:/softs/boost/1.57.0/64/intel/14.0.4/include/boost-1_57/../lib;C:/softs/boost/1.57.0/64/intel/14.0.4/include/boost-1_57/stage/lib;NO_CMAKE_SYSTEM_PATH 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1001 ] Searching for THREAD_LIBRARY_RELEASE: libboost_thread-iw-mt-1_57;libboost_thread-iw-mt;libboost_thread-mt-1_57;libboost_thread-mt;libboost_thread;libboost_thread-iw-mt-s-1_57;libboost_thread-iw-mt-s;libboost_thread-mt-s-1_57;libboost_thread-mt-s 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1037 ] Searching for THREAD_LIBRARY_DEBUG: libboost_thread-iw-mt-gd-1_57;libboost_thread-iw-mt-gd;libboost_thread-mt-gd-1_57;libboost_thread-mt-gd;libboost_thread-mt;libboost_thread;libboost_thread-iw-mt-s-gd-1_57;libboost_thread-iw-mt-s-gd;libboost_thread-mt-s-gd-1_57;libboost_thread-mt-s-gd 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1001 ] Searching for SYSTEM_LIBRARY_RELEASE: libboost_system-iw-mt-1_57;libboost_system-iw-mt;libboost_system-mt-1_57;libboost_system-mt;libboost_system;libboost_system-iw-mt-s-1_57;libboost_system-iw-mt-s;libboost_system-mt-s-1_57;libboost_system-mt-s 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1037 ] Searching for SYSTEM_LIBRARY_DEBUG: libboost_system-iw-mt-gd-1_57;libboost_system-iw-mt-gd;libboost_system-mt-gd-1_57;libboost_system-mt-gd;libboost_system-mt;libboost_system;libboost_system-iw-mt-s-gd-1_57;libboost_system-iw-mt-s-gd;libboost_system-mt-s-gd-1_57;libboost_system-mt-s-gd 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1001 ] Searching for FILESYSTEM_LIBRARY_RELEASE: libboost_filesystem-iw-mt-1_57;libboost_filesystem-iw-mt;libboost_filesystem-mt-1_57;libboost_filesystem-mt;libboost_filesystem;libboost_filesystem-iw-mt-s-1_57;libboost_filesystem-iw-mt-s;libboost_filesystem-mt-s-1_57;libboost_filesystem-mt-s 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1037 ] Searching for FILESYSTEM_LIBRARY_DEBUG: libboost_filesystem-iw-mt-gd-1_57;libboost_filesystem-iw-mt-gd;libboost_filesystem-mt-gd-1_57;libboost_filesystem-mt-gd;libboost_filesystem-mt;libboost_filesystem;libboost_filesystem-iw-mt-s-gd-1_57;libboost_filesystem-iw-mt-s-gd;libboost_filesystem-mt-s-gd-1_57;libboost_filesystem-mt-s-gd 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1001 ] Searching for PYTHON_LIBRARY_RELEASE: libboost_python-iw-mt-1_57;libboost_python-iw-mt;libboost_python-mt-1_57;libboost_python-mt;libboost_python;libboost_python-iw-mt-s-1_57;libboost_python-iw-mt-s;libboost_python-mt-s-1_57;libboost_python-mt-s 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1037 ] Searching for PYTHON_LIBRARY_DEBUG: libboost_python-iw-mt-gd-1_57;libboost_python-iw-mt-gd;libboost_python-mt-gd-1_57;libboost_python-mt-gd;libboost_python-mt;libboost_python;libboost_python-iw-mt-s-gd-1_57;libboost_python-iw-mt-s-gd;libboost_python-mt-s-gd-1_57;libboost_python-mt-s-gd 
[ C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/FindBoost.cmake:1088 ] Boost_FOUND = 1 
Boost version: 1.57.0 
Found the following Boost libraries: 
    thread 
    system 
    filesystem 
    python 
Configuring done 

Как я могу заставить компиляцию использовать только статические библиотеки? Я думал, что это было в случае с вариантами в файле CMake. Более того, он работает с примером, используя потоки ... Возможно, что-то не так в установке Boost.Python?

+0

В визуальной студии, если вы посмотрите на C++/Code Generation, установлена ​​ли она в многопоточную или многопоточную DLL? Проблема в том, что если вы измените это, вы можете получить что-то несовместимое с библиотеками python, если у вас нет источника библиотек python, и вы также можете изменить его. – cup

+1

Во-первых, очевидный вопрос: действительно ли у вас статическая версия boost на C: /softs/boost/1.57.0/? Вы можете использовать Boost_DEBUG = ON для «отладки» во время CMake, что находит find_package (Boost) .... –

+0

@Andre: Да, у меня есть. Я добавил журнал из CMake в свой вопрос. Но, может быть, они плохо составлены? Как это знать? – Caduchon

ответ

6

При использовании Boost.Python настройка по умолчанию - это динамическое связывание. Чтобы заставить статическое связывание, определите BOOST_PYTHON_STATIC_LIB в компиляции. Рассмотрим как:

  • Добавить add_definitions(-DBOOST_PYTHON_STATIC_LIB) в CMake
  • Добавить #define BOOST_PYTHON_STATIC_LIBперед тем включая boost/python.hpp
  • Добавить #define BOOST_PYTHON_STATIC_LIB в boost/config/user.hpp

Boost.Python является исключением из переменной CMake Boost_USE_STATIC_LIBS. FindBoost documentation примечания:

В компиляторах Visual Studio и Borland Boost headers запрашивают автоматическое связывание с соответствующими библиотеками. [...] Boost automatic linking обычно запрашивает статические библиотеки за несколькими исключениями (например, Boost.Python).

К сожалению, опция BOOST_PYTHON_STATIC_LIB не является ни перечислены в документации Boost user settable options, Choosing a Boost.Python Library Binary, ни Boost.Python Configuration Information.


Несколько других рекомендаций, учитывая ваш пример кода:

  • Per Boost.Python-х embedding documentation, не вызывать Py_Finalize(). Некоторые внутренние объекты Boost.Python будут оставаться в живых в течение Py_Finalize() и будут пытаться удалить их только при выгрузке Boost.Python, в результате чего объекты будут пытаться удалить с несуществующим интерпретатором.
  • Не включайте напрямую, python.h. Если вам нужно, подумайте, включите в него boost/python/detail/wrap_python.hpp.
  • Не указывайте никаких системных заголовков до python.h (или файлов Boost.Python). Это ограничение наложено Python (см. here).

Последние две рекомендации, задокументированные в разделе #include issues.

-2

У вас возникли проблемы с finding dll's на вашей машине. Как temporary fix, вы можете попробовать переименовать ваш DLL-файл в .pyd.

+0

Как я уже сказал, я не хочу использовать общие библиотеки, но только статические. Название моего вопроса было неправильным. Я исправил это. – Caduchon

Смежные вопросы