跨多个c++项目的编译时配置

Compile-time configuration across several c++ projects

本文关键字:编译 配置 项目 c++      更新时间:2023-10-16

我需要一个编译时项目配置文件,它配置了几个c++项目。我的设置是:

    我有三个c++项目,其中一个是静态库:proj1, proj2, lib1
  • proj1和proj2都使用lib1
  • proj1和proj2编译成不同Arduino板上运行的可执行文件
  • 所有三个项目都需要配置变量的值(例如,要使用的UDP端口,调试级别等)
  • proj1和proj2实际上非常相似,并且共享许多配置变量
  • proj1和proj2需要不同的配置值,lib1
  • 也是如此

我需要一个简单的解决方案来配置这三个。我需要它是低资源使用,因为我是内存受限的(部署在Arduino上)。


我的第一个解决方案是在每个项目中创建一个configuration.h文件,其中包含每个项目的#define's。

这种方法的问题:我不能为lib1和proj1/proj2定义不同的值。例如,lib1定义了UDP_PORT,那么我就不能在proj1/proj2中指定lib1实际使用的不同的UDP_PORT。


当然,我可以在运行时将所有这些配置值作为参数传递。但是,为了节省内存和运行时,我更喜欢编译时解决方案。

你可以做几件事:

  1. 编译时,从命令行传递定义,并为每个项目编译单独的库版本

    gcc -DUDP_PORT=1234 myProject.cpp

    gcc -DUDP_PORT=1234 myLib.cpp

  2. 在运行时将硬编码的UDP端口从项目传递到库。这真的不会影响你的开销

    // in project_1
    lib::set_udp_port(UDP_PORT);
    // in the lib
    static short g_udp_port;
    lib::set_udp_port(short port)
    {
        g_udp_port = port;
    }
    
  3. 2,但是在运行

    程序时在命令行上传入端口

    my_program——port 1234

您没有提到您的Arduino构建系统是托管在Windows, Linux还是"其他东西"上。

无论哪个:您应该能够轻松地使用"make"自动构建一个或多个项目:

http://www.arduino.cc/playground/Learning/CommandLine

https://github.com/queezythegreat/arduino-cmake

如果你不熟悉"make",网上有很多很好的教程,包括:

http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

您可以添加一个类ConfigurationParameterVault,它带有一个适合提供您需要的所有参数的接口。将.h文件放在所有项目都可以访问的地方(可能在lib的项目中?)

构成

class ConfigurationParameterVault{
    ConfigurationParameterVault();
    ~ConfigurationParameterVault();
public:
    int getUDPPort();
    int getOtherParameter();
    ...
    void* m_pImpl;
}

现在为每个项目添加一个.cpp文件(我们在其中实现仓库)。因此,在构建时,喜欢者选择从它正在构建的项目中的.cpp文件实现!

保险库的实现遵循PIMPL习语。因此,如果头文件是通用的,每个实现也可能在库中存储一些状态。

在第一个项目中:Vault.cpp

class Project1VaultImpl{
     Project1VaultImpl() :
          udpPort(53124),
          otherParam(28){

     };
     int udpPort;
     int otherParam;
}
ConfigurationParameterVault::ConfigurationParameterVault() :
         m_pImpl(new Project1VaultImpl()){
}
ConfigurationParameterVault::ConfigurationParameterVault() :
     delete m_pImpl;
}
int ConfigurationParameterVault::getUDPPort(){
    Project1VaultImpl* pImpl = reinterpret_cast<Project1VaultImpl*>(m_pImpl);
    return pImpl->udpPort;
}

如果所有的项目需要共享一些公共参数,所有的pimps可以扩展相同的基类。如果一个项目需要使用与普通值不同的值,则其vault的特定实现可以覆盖它