微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 _GLIBCXX_USE_CXX11_ABI=0 编译 OR 工具?

如何解决如何使用 _GLIBCXX_USE_CXX11_ABI=0 编译 OR 工具?

我正在尝试使用 cmake 在与 libtorch 相同的项目中编译 OR 工具。

CMake 与 OR-Tools 的链接成功:

cmake_minimum_required(VERSION 3.14)
project(my_proj VERSION 1.0 LANGUAGES CXX)

# Function linking or-tools to the target whose name is passed as parameters
function(link_or_tools_to_target)
    set(options)
    set(args TARGET BINARY)
    set(list_args)
    cmake_parse_arguments(
        PARSE_ARGV 0
        "ARG"
        "${options}"
        "${args}"
        "${list_args}"
    )

    foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
        message(WARNING "Unparsed argument: ${arg}")
    endforeach()

    # Build OR-tools dependencies.
    set(BUILD_DEPS ON)

    # disable SCIP solver.
    set(USE_SCIP OFF)

    # Add or-tools as a subdirectory and create the alias ortools::ortools.
    add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/or-tools")

    # Link or-tools to the target.
    target_link_libraries(${ARG_TARGET} PRIVATE ortools::ortools)

endfunction()

# Create main executable
add_executable(myapp-success main.cpp)
add_library(basic-success STATIC
        BasicExample.cpp BasicExample.h)
target_link_libraries(myapp-success PUBLIC basic-success)
include_directories(${CMAKE_CURRENT_LIST_DIR})

# Link or-tools library to basic library.
link_or_tools_to_target(TARGET basic-success BINARY basic_success)

尝试链接 libtorch:

cmake_minimum_required(VERSION 3.14)
project(my_proj VERSION 1.0 LANGUAGES CXX)

# Function linking pytorch to the target whose name is passed as parameters
function(link_pytorch_to_target)
    set(options)
    set(args TARGET)
    set(list_args)
    cmake_parse_arguments(
        PARSE_ARGV 0
        "ARG"
        "${options}"
        "${args}"
        "${list_args}"
    )

    foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
        message(WARNING "Unparsed argument: ${arg}")
    endforeach()

    # Link boost
    find_package(Boost 1.40.0 COMPONENTS filesystem system iostreams required)
    target_link_libraries(${ARG_TARGET} PUBLIC "${Boost_LIBRARIES}")

    # Link pytorch
    set(Torch_DIR "${CMAKE_CURRENT_LIST_DIR}/torch/share/cmake/Torch")
    set(Caffe2_DIR "${CMAKE_CURRENT_LIST_DIR}/torch/share/cmake/Caffe2")

    find_package(Torch required)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
    target_link_libraries(${ARG_TARGET} PUBLIC "${TORCH_LIBRARIES}")

    if (MSVC)
        file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
        add_custom_command(TARGET ${ARG_TARGET}
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            ${TORCH_DLLS}
            $<TARGET_FILE_DIR:${ARG_TARGET}>)
    endif (MSVC)

endfunction()

# Function linking or-tools to the target whose name is passed as parameters
function(link_or_tools_to_target)
    set(options)
    set(args TARGET BINARY)
    set(list_args)
    cmake_parse_arguments(
        PARSE_ARGV 0
        "ARG"
        "${options}"
        "${args}"
        "${list_args}"
    )

    foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
        message(WARNING "Unparsed argument: ${arg}")
    endforeach()

    # Build OR-tools dependencies.
    set(BUILD_DEPS ON)

    # disable SCIP solver.
    set(USE_SCIP OFF)

    # Add or-tools as a subdirectory and create the alias ortools::ortools.
    add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/or-tools")

    # Link or-tools to the target.
    target_link_libraries(${ARG_TARGET} PRIVATE ortools::ortools)

endfunction()

# For compatibility with PyTorch
add_compile_deFinitions(_GLIBCXX_USE_CXX11_ABI=0)

# Create main executable
add_executable(myapp-fail mainCFE.cpp)

# Create basic library and link it to main executable
add_library(basic-fail STATIC
    api/API.cpp api/API.h
    api/Aliases.h
    math/Ops.cpp math/Ops.h
    environments/Environment.h
    environments/MazeEnv.cpp environments/MazeEnv.h
    common/ExperimentConfig.cpp common/ExperimentConfig.h
    common/Experiments.cpp common/Experiments.h
    common/MazePerformanceTracker.cpp common/MazePerformanceTracker.h
    common/TimeTracker.cpp common/TimeTracker.h
    zoo/CFE.cpp zoo/CFE.h)
target_link_libraries(myapp-fail PUBLIC basic-fail)
include_directories(${CMAKE_CURRENT_LIST_DIR})

# Link libtorch to target
link_pytorch_to_target(TARGET basic-fail)

# Link or-tools to the target.
link_or_tools_to_target(TARGET basic-fail BINARY basic_fail)

在上面的 CMakeLists.txt 中,我使用 add_compile_deFinitions(_GLIBCXX_USE_CXX11_ABI=0) 将 _GLIBCXX_USE_CXX11_ABI 设置为零,因为 libtorch 也使用 _GLIBCXX_USE_CXX11_ABI=0。如果删除此行,则会出现以下链接错误

/usr/bin/ld: libbasic-fail.a(CFE.cpp.o): in function `hopi::zoo::CFE::updatePosteriorOverActions(int)':
/home/tmac3/Desktop/Experiments_AI_TS/or_tools_test/zoo/CFE.cpp:137: undefined reference to `operations_research::MPSolver::CreateSolver(std::string const&)'
/usr/bin/ld: /home/tmac3/Desktop/Experiments_AI_TS/or_tools_test/zoo/CFE.cpp:142: undefined reference to `operations_research::MPSolver::MakeNumVar(double,double,std::string const&)'
/usr/bin/ld: /home/tmac3/Desktop/Experiments_AI_TS/or_tools_test/zoo/CFE.cpp:146: undefined reference to `operations_research::MPSolver::MakeRowConstraint(double,std::string const&)'
collect2: error: ld returned 1 exit status

如果我将 _GLIBCXX_USE_CXX11_ABI 行设置为零,则编译成功但执行崩溃并显示以下输出

$> valgrind ./myapp-fail
==55900== Memcheck,a memory error detector
==55900== copyright (C) 2002-2017,and GNU GPL'd,by Julian Seward et al.
==55900== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==55900== Command: ./myapp-fail
==55900== 
==55900== Warning: set address range perms: large range [0x484a000,0x17e22000) (defined)
==55900== Invalid read of size 8
==55900==    at 0x1A8C8F24: absl::lts_20210324::flags_internal::FlagRegistry::RegisterFlag(absl::lts_20210324::CommandLineFlag&,char const*) (reflection.cc:115)
==55900==    by 0x1A8C9D67: absl::lts_20210324::flags_internal::RegisterCommandLineFlag(absl::lts_20210324::CommandLineFlag&,char const*) (reflection.cc:192)
==55900==    by 0x199E280F: absl::lts_20210324::flags_internal::FlagRegistrar<bool,true>::FlagRegistrar(absl::lts_20210324::flags_internal::Flag<bool>&,char const*) (flag.h:726)
==55900==    by 0x19A1C6DD: __static_initialization_and_destruction_0(int,int) (logging.cc:105)
==55900==    by 0x19A1CAA0: _GLOBAL__sub_I_logging.cc (logging.cc:1884)
==55900==    by 0x4011B89: call_init.part.0 (dl-init.c:72)
==55900==    by 0x4011C90: call_init (dl-init.c:30)
==55900==    by 0x4011C90: _dl_init (dl-init.c:119)
==55900==    by 0x4001139: ??? (in /usr/lib/x86_64-linux-gnu/ld-2.31.so)
==55900==  Address 0x8 is not stack'd,malloc'd or (recently) free'd
==55900== 
==55900== 
==55900== Process terminating with default action of signal 11 (SIGSEGV)
==55900==  Access not within mapped region at address 0x8
==55900==    at 0x1A8C8F24: absl::lts_20210324::flags_internal::FlagRegistry::RegisterFlag(absl::lts_20210324::CommandLineFlag&,int) (logging.cc:105)
==55900==    by 0x19A1CAA0: _GLOBAL__sub_I_logging.cc (logging.cc:1884)
==55900==    by 0x4011B89: call_init.part.0 (dl-init.c:72)
==55900==    by 0x4011C90: call_init (dl-init.c:30)
==55900==    by 0x4011C90: _dl_init (dl-init.c:119)
==55900==    by 0x4001139: ??? (in /usr/lib/x86_64-linux-gnu/ld-2.31.so)
==55900==  If you believe this happened as a result of a stack
==55900==  overflow in your program's main thread (unlikely but
==55900==  possible),you can try to increase the size of the
==55900==  main thread stack using the --main-stacksize= flag.
==55900==  The main thread stack size used in this run was 8388608.
==55900== 
==55900== HEAP SUMMARY:
==55900==     in use at exit: 23,051 bytes in 389 blocks
==55900==   total heap usage: 6,779 allocs,6,390 frees,442,746 bytes allocated
==55900== 
==55900== LEAK SUMMARY:
==55900==    definitely lost: 0 bytes in 0 blocks
==55900==    indirectly lost: 0 bytes in 0 blocks
==55900==      possibly lost: 0 bytes in 0 blocks
==55900==    still reachable: 23,051 bytes in 389 blocks
==55900==                       of which reachable via heuristic:
==55900==                         stdstring          : 8,395 bytes in 188 blocks
==55900==         suppressed: 0 bytes in 0 blocks
==55900== Rerun with --leak-check=full to see details of leaked memory
==55900== 
==55900== For lists of detected and suppressed errors,rerun with: -s
==55900== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

问题:如何在同一个项目中编译 libtorch 和 or-tools?

解决方法

仅供参考 OR-Tools 依赖于 C++17 并在其公共头文件中使用 abseil-cpp。
Abseil-cpp 在其头文件中依赖于 C++ 方言,
即,您必须所有可能包含或工具标头(即 abseil-cpp 标头)的项目也使用 C++17 方言构建...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。