LNK1104 当尝试 link 与 boost_filesystem*.lib
LNK1104 When trying to link with boost_filesystem*.lib
我正在使用 CMake 创建一个使用一些 Boost 库的跨平台项目。我使用以下命令创建库。
.\b2.exe --prefix=C:/Boost install --with-python --with-system --with-filesystem address-model=32 toolset=msvc-12.0 link=shared threading=multi --layout=tagged --build-type=complete
项目 link 使用 python 和系统库没问题,但是当它尝试 link 使用文件系统库时,它失败了。它正在寻找 "libboost_filesystem*.lib"(不存在),然后毫无问题地使用 "boost_python*.lib" 和 "boost_system*.lib" 文件。
我的最高等级CMakeLists.txt如下:
file(GLOB SOURCES src/*.cpp)
add_subdirectory(shape)
add_subdirectory(py_shape)
#define sources and executable
set(EXECUTABLE_NAME "renderer2d")
add_executable(${EXECUTABLE_NAME} ${SOURCES})
#find python
find_package(PythonInterp)
find_package(PythonLibs 2.7 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
#detect and add SFML
#this line checks a cmake file for hints on where to find cmake
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
#find any version 2.x of SFML
#see the FindSFML.cmake file for additional details and instructions
find_package(SFML 2 REQUIRED system window graphics network audio)
include_directories(${SFML_INCLUDE_DIR})
#find and include Boost python libraries
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost COMPONENTS python system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
#link all found libraries to the executable
target_link_libraries(${EXECUTABLE_NAME} ${PYTHON_LIBRARIES} ${SFML_LIBRARIES} ${Boost_LIBRARIES} shape)
#install target
install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)
还有这个 exe 的唯一源文件:
#include <iostream>
#include <SFML/Graphics.hpp>
#include "../shape/inc/Shape.hpp"
#include <boost/python.hpp>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::python;
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
try
{
Py_Initialize();
//need to insert working directory into path
path working_directory = absolute("./").normalize();
PyObject* sys_path = PySys_GetObject("path");
PyList_Insert(sys_path, 0, PyString_FromString(working_directory.string().c_str()));
sf::RenderWindow window(sf::VideoMode(800, 600), "renderer2d");
Shape shape;
shape.Initialize();
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.type == sf::Event::KeyPressed)
{
if(event.key.code == sf::Keyboard::Q)
window.close();
else if(event.key.code == sf::Keyboard::U)
shape.Update();
else if(event.key.code == sf::Keyboard::S)
shape.SetGreen(255);
}
}
window.clear();
window.draw(*shape.GetShape());
window.display();
}
} catch(error_already_set){PyErr_Print();}
return 0;
}
那么,为什么它会尝试 link 对抗 "libboost_filesystem" 而不是 "boost_filesystem"?
这里的问题是 Boost 有 an auto-linking feature 如果您不使用 CMake,它会很有用。
要禁用此功能,您只需应用预处理器定义,如 docs for Boost.Config 中的 table 所示:
BOOST_ALL_NO_LIB
: Tells the config system not to automatically select which libraries to link against. Normally if a compiler supports #pragma lib, then the correct library build variant will be automatically selected and linked against, simply by the act of including one of that library's headers. This macro turns that feature off.
要通过 CMake 添加预处理器定义,您可以使用 target_compile_definitions
command. If you want to limit the definition to just the MSVC compiler for example, you can use a generator expression:
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE $<$<BOOL:${MSVC}>:BOOST_ALL_NO_LIB>)
我正在使用 CMake 创建一个使用一些 Boost 库的跨平台项目。我使用以下命令创建库。
.\b2.exe --prefix=C:/Boost install --with-python --with-system --with-filesystem address-model=32 toolset=msvc-12.0 link=shared threading=multi --layout=tagged --build-type=complete
项目 link 使用 python 和系统库没问题,但是当它尝试 link 使用文件系统库时,它失败了。它正在寻找 "libboost_filesystem*.lib"(不存在),然后毫无问题地使用 "boost_python*.lib" 和 "boost_system*.lib" 文件。
我的最高等级CMakeLists.txt如下:
file(GLOB SOURCES src/*.cpp)
add_subdirectory(shape)
add_subdirectory(py_shape)
#define sources and executable
set(EXECUTABLE_NAME "renderer2d")
add_executable(${EXECUTABLE_NAME} ${SOURCES})
#find python
find_package(PythonInterp)
find_package(PythonLibs 2.7 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
#detect and add SFML
#this line checks a cmake file for hints on where to find cmake
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
#find any version 2.x of SFML
#see the FindSFML.cmake file for additional details and instructions
find_package(SFML 2 REQUIRED system window graphics network audio)
include_directories(${SFML_INCLUDE_DIR})
#find and include Boost python libraries
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost COMPONENTS python system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
#link all found libraries to the executable
target_link_libraries(${EXECUTABLE_NAME} ${PYTHON_LIBRARIES} ${SFML_LIBRARIES} ${Boost_LIBRARIES} shape)
#install target
install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)
还有这个 exe 的唯一源文件:
#include <iostream>
#include <SFML/Graphics.hpp>
#include "../shape/inc/Shape.hpp"
#include <boost/python.hpp>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::python;
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
try
{
Py_Initialize();
//need to insert working directory into path
path working_directory = absolute("./").normalize();
PyObject* sys_path = PySys_GetObject("path");
PyList_Insert(sys_path, 0, PyString_FromString(working_directory.string().c_str()));
sf::RenderWindow window(sf::VideoMode(800, 600), "renderer2d");
Shape shape;
shape.Initialize();
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.type == sf::Event::KeyPressed)
{
if(event.key.code == sf::Keyboard::Q)
window.close();
else if(event.key.code == sf::Keyboard::U)
shape.Update();
else if(event.key.code == sf::Keyboard::S)
shape.SetGreen(255);
}
}
window.clear();
window.draw(*shape.GetShape());
window.display();
}
} catch(error_already_set){PyErr_Print();}
return 0;
}
那么,为什么它会尝试 link 对抗 "libboost_filesystem" 而不是 "boost_filesystem"?
这里的问题是 Boost 有 an auto-linking feature 如果您不使用 CMake,它会很有用。
要禁用此功能,您只需应用预处理器定义,如 docs for Boost.Config 中的 table 所示:
BOOST_ALL_NO_LIB
: Tells the config system not to automatically select which libraries to link against. Normally if a compiler supports #pragma lib, then the correct library build variant will be automatically selected and linked against, simply by the act of including one of that library's headers. This macro turns that feature off.
要通过 CMake 添加预处理器定义,您可以使用 target_compile_definitions
command. If you want to limit the definition to just the MSVC compiler for example, you can use a generator expression:
target_compile_definitions(${EXECUTABLE_NAME} PRIVATE $<$<BOOL:${MSVC}>:BOOST_ALL_NO_LIB>)