如何在多个项目中共享一个主要功能/文件?

时间:2018-07-02 03:15:32

标签: c++

我有多个具有相同主文件的C ++应用程序。 看起来像这样:

main() {
   superclass *a = new subclass_1();
   a.setup(); // .setup() and .run() are superclass functions that are overridden by subclasses.
   a.run();
}

我大约有10个子类(subclass_1,subclass_2,subclass_3等),它们都共享相同的接口(.setup()、. run())。

我想用完全相同的主文件创建10个单独的二进制文件,但是子类实例有所不同(而不是new subclass_1(),它将是new subclass_2(),new subclass_3()略有不同)等)。但是对.setup()和.run()的调用将始终相同。

其背后的原因是我的主要功能可能会稍作更改,并且我不想更新10个主要文件来传播此更改。我只想拥有一个主文件,然后以某种方式链接到10个不同的子类库以创建10个不同的可执行文件。

我正在使用CMake和C ++ 17,当然还有gcc / g ++。

我考虑过的策略:

a)使用一个模板引擎,该引擎采用一个主文件模板并生成10个临时的主失败并进行编译。这不是很优雅,但是我可能可以破解CMake来为我做这个过程。

b)使用C的动态类加载。使用dlopen和dlsym,我可以从子类中导出符号,并有一个通用的主文件.o文件,可以将其单独链接到每个子类lib,并创建10个不同的二进制文件,这些文件只需为每个子类加载10个不同的.so文件。此方法稍微更优雅一些,但可能会很丑陋和凌乱,不幸的是,我在设置和运行std :: strings函数的内部使用了带有args的C ++。符号导出可能会变得混乱。...

有人遇到这样的事情吗?有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以像这样使用编译器定义的MACRO

// main.cpp

int main() {
                       // macro defined by compiler command line
   superclass *a = new DEFINED_SUBCLASS();
   a.setup(); // .setup() and .run() are superclass functions that are overridden by subclasses.
   a.run();
}

编译为:

g++ -DDEFINED_SUBCLASS=subclass_1 -std=c++11 -o main-1 main.cpp
g++ -DDEFINED_SUBCLASS=subclass_2 -std=c++11 -o main-2 main.cpp
... etc ...

答案 1 :(得分:0)

您不必破解CMake。将以下内容添加到您的CMakeLists.txt:

foreach(subclass IN ITEMS 1 2 3)
    configure_file("main.cpp.in"
        "${CMAKE_CURRENT_BINARY_DIR}/main-${subclass}.cpp" @ONLY
    )
    add_executable(foo-${subclass} main-${subclass}.cpp)
    target_include_directories(foo-${subclass}
        PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
    )
endforeach()

根据需要使用正确的项目更新循环。 main.cpp.in应该看起来像这样:

#include "classes.h"

int main() {
    superclass * a = new subclass@subclass@{};
    a->setup();
    a->run();
    return 0;
}

根据需要进行调整(这是一个与您相匹配的简单示例)。这将为每个生成的文件提供一个目标:

$ make
[ 16%] Building CXX object CMakeFiles/foo-1.dir/main-1.cpp.o
[ 33%] Linking CXX executable foo-1
[ 33%] Built target foo-1
[ 50%] Building CXX object CMakeFiles/foo-3.dir/main-3.cpp.o
[ 66%] Linking CXX executable foo-3
[ 66%] Built target foo-3
[ 83%] Building CXX object CMakeFiles/foo-2.dir/main-2.cpp.o
[100%] Linking CXX executable foo-2
[100%] Built target foo-2

为了完整起见,classes.h:

struct superclass {
    virtual void setup() = 0;
    virtual void run() = 0;
};

struct subclass1 : superclass {
    void setup() override { }
    void run() override { }
};

struct subclass2 : superclass {
    void setup() override { }
    void run() override { }
};

struct subclass3 : superclass {
    void setup() override { }
    void run() override { }
};