C ++模块化项目链接问题和未定义的参考错误

时间:2018-07-08 04:09:17

标签: c++ cmake linker-errors

我在弄清楚如何构建模块化的c ++应用程序并使所有内容正确链接方面遇到困难。具体来说,我无法构建一些测试,因为最终我会基于类方法得到未定义的引用错误。 (我是C ++和CMake的新手,所以我可能做错了很多,但我正在学习!)我浏览了其他文章,我所能收集到的只是我可能没有正确链接。

OrderBook和Strategy都很好。但是,当我构建StrategyTests和OrderBookTests时,出现错误:

[ 83%] Linking CXX executable StrategyTests.exe
../../OrderBook/libOrderBook.a(OrderBook.cpp.o): In function `orderbook::OrderBook::notify_strategies(std::shared_ptr<orderbook::Order> const&, bool)':
/cygdrive/d/Dropbox/My Documents/Programming/CLionProjects/TradingSystem/OrderBook/OrderBook.cpp:220: undefined reference to `HYSTRAT::Strategy::onBookUpdate(std::shared_ptr<Events::TOB> const&, std::shared_ptr<Events::OrderBookEvent> const&, bool)'
/cygdrive/d/Dropbox/My Documents/Programming/CLionProjects/TradingSystem/OrderBook/OrderBook.cpp:220:(.text+0x11c4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `HYSTRAT::Strategy::onBookUpdate(std::shared_ptr<Events::TOB> const&, std::shared_ptr<Events::OrderBookEvent> const&, bool)'
collect2: error: ld returned 1 exit status

我尝试了许多不同的方法,包括摆弄CMakeLists和标头,但似乎都没有用。很明显,我不知道“未定义引用”的真正含义。我怀疑这是一个简单的修复程序,但是如果不是这样,我会在下面发布项目设置。

这是我的设置:

Windows 10上的Clion和Cygwin

项目树

TradingSystem
|-CMakeLists.txt
|\OrderBook
|-|-CMakeLists.txt
|-|-OrderBook.h
|-|-OrderBook.cpp
|\Strategy
|-|-CMakeLists.txt
|-|-Strategy.h
|-|-Strategy.cpp
|\Tests
|-|-CMakeLists.txt
|-|\OrderBookTests
|-|-|-CMakeLists.txt
|-|-|\BoostTests
|-|-|-|-CMakeLists.txt
|-|-|-|-OrderBookBoostTests.cpp
|-|\StrategyTests
|-|-|-CMakeLists.txt
|-|-|-StrategyBoostTests.cpp

CMakes

#TradingSystem/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(TradingSystem)

set(CMAKE_CXX_STANDARD 11)

set(SOURCE_FILES main.cpp)

add_executable(TradingSystem ${SOURCE_FILES} ${HEADER_FILES})

include_directories(OrderBook Strategy Events)

add_subdirectory(OrderBook)
add_subdirectory(Strategy)
add_subdirectory(Events)
add_subdirectory(Tests/OrderBookTests)
add_subdirectory(Tests/StrategyTests)

target_link_libraries(TradingSystem OrderBook Strategy)

-

#TradingSystem/OrderBook/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(OrderBook)

include_directories(/cygdrive/c/Program Files/boost/boost_1_66_0)

set(CMAKE_CXX_STANDARD 11)
set(HEADER_FILES OrderBook.h)
set(SOURCE_FILES OrderBook.cpp)

add_library(OrderBook STATIC ${SOURCE_FILES} ${HEADER_FILES})

-

#TradingSystem/Strategy/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(Strategy)

include_directories(/cygdrive/c/Program Files/boost/boost_1_66_0)

set(CMAKE_CXX_STANDARD 11)
set(HEADER_FILES Strategy.h)
set(SOURCE_FILES Strategy.cpp)

add_library(Strategy STATIC ${SOURCE_FILES} ${HEADER_FILES})

-

#TradingSystem/Tests/CMakeLists.txt
project(Tests)
add_subdirectory(OrderBookTests)
add_subdirectory(StrategyTests)

-

#TradingSystem/Tests/OrderBookTests/CMakeLists.txt
project(OrderBookTests)
add_subdirectory(BoostTests)

[编辑]

#TradingSystem/Tests/OrderBookTests/BoostTests/CMakeLists.txt
add_executable(BoostTests OrderBookBoostTests.cpp)

enable_testing()
include_directories(/cygdrive/c/Program Files/boost_1_66_0)

set(BOOST_ROOT "C:/Program Files/boost_1_66_0/")
set(BOOST_LIBRARYDIR "C:/Program Files/boost_1_66_0/")

find_package(Boost 1.66.0)

find_package(Boost COMPONENTS unit_test_framework REQUIRED)

include_directories(${BOOSTROOT})
link_directories("${BOOSTROOT}")
target_include_directories(OrderBook PRIVATE ${BOOST_INCLUDE_DIRS})

# Original:
# target_link_libraries(BoostTests OrderBook)
# Changed to: 
target_link_libraries(BoostTests Orderbook Strategy)

if(NOT Boost_FOUND)
    message(FATAL_ERROR "Could not find boost!")
endif()

[编辑]

#TradingSystem/Tests/StrategyTests/CMakeLists.txt
project(StrategyTests)

add_executable(StrategyTests StrategyBoostTests.cpp)

enable_testing()
include_directories(/cygdrive/c/Program Files/boost_1_66_0)

set(BOOST_ROOT "C:/Program Files/boost_1_66_0/")
set(BOOST_LIBRARYDIR "C:/Program Files/boost_1_66_0/")

find_package(Boost 1.66.0)

find_package(Boost COMPONENTS unit_test_framework REQUIRED)

include_directories(${BOOSTROOT})
link_directories("${BOOSTROOT}")
target_include_directories(Strategy PRIVATE ${BOOST_INCLUDE_DIRS})

# Original:
# target_link_libraries(StrategyTests Strategy OrderBook)
# Change to:
target_link_libraries(StrategyTests Orderbook Strategy)

if(NOT Boost_FOUND)
    message(FATAL_ERROR "Could not find boost!")
endif()

Src文件

#TradingSystem/OrderBook/OrderBook.h
#fndef TRADINGSYSTEM_ORDERBOOK_H
#define TRADINGSYSTEM_ORDERBOOK_H

#include <vector>
using std::vector;

#include "Strategy.h"
#include "Events.h"

namespace orderbook {
    /////////////////////
    // HIDDEN CODE
    /////////////////////

    class OrderBook {
    private:
        vector<HYSTRAT::Strategy> strategies_;

        bool notify_strategies(const order_ptr& o, bool add_flag);;
        Events::order_book_event_ptr create_order_book_event(const order_ptr& order);;

    public:
        /////////////////////////////
        // CONSTRUTORS; DESTRUCTORS
        /////////////////////////////

        inline bool subscribe(HYSTRAT::Strategy& s) {
            strategies_.push_back(s);
        }

#endif //TRADINGSYSTEM_ORDERBOOK_H

-

#TradingSystem/OrderBook/OrderBook.cpp
#include "OrderBook.h"
#include "Events.h"
#include "Strategy.h"

using orderbook::OrderBook;
using HYSTRAT::Strategy;

bool orderbook::OrderBook::notify_strategies(const order_ptr& o, bool add_flag) {
    try {
        Events::order_book_event_ptr event = create_order_book_event(o);
        Events::topOfBook_ptr tob = get_top_of_book();
        for (HYSTRAT::Strategy& strategy : strategies_) {
            strategy.onBookUpdate(tob, event, add_flag);
        }
        return true;
    } catch (const std::exception& e) {
        return false;
    }
}

-

#TradingSystem/Strategy/Strategy.h
#ifndef TRADINGSYSTEM_STRATEGY_H
#define TRADINGSYSTEM_STRATEGY_H

#include "Events.h"

namespace HYSTRAT {
    class Strategy {
    public:
        void onBookUpdate(const Events::topOfBook_ptr& tob, const Events::order_book_event_ptr& e, bool event_flag);;
    };
}

#endif //TRADINGSYSTEM_STRATEGY_H

-

#TradingSystem/Strategy/Strategy.cpp
#include "OrderBook.h"
#include "Strategy.h"
#include "Events.h"

using namespace HYSTRAT;

void Strategy::onBookUpdate(const Events::topOfBook_ptr &tob, const Events::order_book_event_ptr &e, bool event_flag) {
    if (tob->bidP >= tob->offerP) {
        quantity_t order_size = std::min(tob->offerQ, tob->bidQ);
        order_ptr buy_order(new Order(tob->offerP, order_size, BUY));
        order_ptr sell_order(new Order(tob->bidP, order_size, SELL));
        send_order(buy_order);
        send_order(sell_order);
    }
}

1 个答案:

答案 0 :(得分:0)

我认为您在CMakeLists.txt文件中缺少对“ add_dependencies”的一些调用。我认为可以通过添加

解决此特定问题
add_dependencies(OrderBook Strategy)

到您的订单CMakelists.txt