每个项目的 Boost.Build 条件库编译

发布于 2024-07-30 00:13:50 字数 1335 浏览 9 评论 0原文

我有使用 Boost.Build 构建的 C++ 项目。 该项目由3个子项目组成。

    . [root]
    \-- source
        \-- common
            \-- config
                \-- config.cpp
        \-- project_1
            \-- Jamfile.jam
        \-- project_2
            \-- Jamfile.jam
        \-- project_3
            \-- Jamfile.jam
    \-- Jamroot.jam

Jamroot.jam:

    project my_project 
        : requirements 
          multi 
          debug:DEBUG
        : default-build
          static
        : build-dir bin
        ;

    alias project_1 : source/project_1 ;
    alias project_2 : source/project_2 ;
    alias project_3 : source/project_3 ;

    install dist : project_1 project_2 project_3
        : on EXE
        ;

每个项目都有Jamfile.jam,按照这个模板:

    project project_N
      : requirements 
          CONFIG_DEFINE_1=
          CONFIG_DEFINE_2=
      ; 

    lib config : [ glob ../common/config/*.cpp ] ;

    exe project_N 
        : [ glob *.cpp ]  config
        :  
        ;

config.cpp使用定义CONFIG_DEFINE_1CONFIG_DEFINE_2进行条件编译(实际上它们只是常量),因此每个项目都有一个单独版本的 config 库。

问题是,这种方法会导致每次构建整个项目时都会重新构建 config 库,无论文件是否更改。 即,第一次构建所有内容都已编译和链接,第二次构建时不进行任何修改 - 仅为每个 project_N 构建 config 库。 我应该如何正确设置建筑物以免发生冗余编译?

I have C++ project that are built using Boost.Build. The project consists of 3 subprojects.

    . [root]
    \-- source
        \-- common
            \-- config
                \-- config.cpp
        \-- project_1
            \-- Jamfile.jam
        \-- project_2
            \-- Jamfile.jam
        \-- project_3
            \-- Jamfile.jam
    \-- Jamroot.jam

Jamroot.jam:

    project my_project 
        : requirements 
          multi 
          debug:DEBUG
        : default-build
          static
        : build-dir bin
        ;

    alias project_1 : source/project_1 ;
    alias project_2 : source/project_2 ;
    alias project_3 : source/project_3 ;

    install dist : project_1 project_2 project_3
        : on EXE
        ;

Each project has Jamfile.jam according to this template:

    project project_N
      : requirements 
          CONFIG_DEFINE_1=
          CONFIG_DEFINE_2=
      ; 

    lib config : [ glob ../common/config/*.cpp ] ;

    exe project_N 
        : [ glob *.cpp ]  config
        :  
        ;

config.cpp uses defines CONFIG_DEFINE_1 and CONFIG_DEFINE_2 for conditional compilation (actually they are simply constants), so there's a separate version of config library per project.

The problem is that such approach causes the config library to be rebuilt each time the whole project is built regardless of were the files changed or not. I.e. building the first time everything is compiled and linked, building the second time without doing any modifications - only the config library is built for each project_N. How should I properly setup the building so no redundand compilation occur?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

荒路情人 2024-08-06 00:13:50

据我了解,您的配置库在不同的项目中共享,并为每个项目使用不同的定义。

在这种情况下,无论 boost build. 或任何其他构建系统如何,都不可能克服重新编译的问题。 在 cpp 文件的编译之间,预处理文件发生了变化。

如果您想避免重新编译,一种选择是将配置库拆分为每个项目的不同库,但根据 config 的外观,也很少需要有大量代码重复......

我能想到的唯一其他选择是减少每次需要重新编译的代码量。

例如,您有一个源文件 LargeFunction.cpp 并将

 #if CONFIG_DEFINE_1
     void VeryLargeFunction() {
        ...
     }
 #elif CONFIG_DEFINE_2
     void VeryLargeFunction() {
        ...
     }
 #endif

其拆分为三个文件,一个包含为 DEFINE_1 定义的 VeryLargeFunction,一个包含为 DEFINE_2 定义的,另一个仅包含基于 DEFINE_1 的值的这两个文件定义。

 #if CONFIG_DEFINE_1
    #include "definitionFileFor1"
 #elif CONFIG_DEFINE_2
    #include "definitionFileFor2"
 #endif

该文件仍然需要每次重新编译,但包含“真实”代码的目标文件则不需要。

您将有效地仅在每次编译时重新链接现有目标文件,iso 重新编译所有内容。

缺点是需要更多的维护,并且不同的函数定义驻留在不同的文件中,因此代码变得有点难以阅读。

As I understand it, your config library is shared over different projects and uses different defines for each project.

It's not possible to overcome recompilation in that case, irrespective of boost build.or any other build system. In between compiles of the cpp files the preprocessed files have changed.

If you want to avoid recompilation one option is to split of the config library into different libraries for each project, but depending on what config looks like, having a lot of code duplication is rarely desireable either...

The only other option I can think of is reducing the amount of code that needs to be recompiled every time.

e.g. you have a sourcefile LargeFunction.cpp with

 #if CONFIG_DEFINE_1
     void VeryLargeFunction() {
        ...
     }
 #elif CONFIG_DEFINE_2
     void VeryLargeFunction() {
        ...
     }
 #endif

Split it into three files, one containing the VeryLargeFunction as defined for DEFINE_1, one as defined for DEFINE_2, and one which simply includes these two based on the values of the defines.

 #if CONFIG_DEFINE_1
    #include "definitionFileFor1"
 #elif CONFIG_DEFINE_2
    #include "definitionFileFor2"
 #endif

This file still needs to be recompiled every time, but the object files which contain the 'real' code, will not.

You'll effectively only relink existing object files on every compile, i.s.o. recompiling everything.

The disadvantage is more maintenance though, and the different function definitions reside in different files, so the code becomes a bit harder to read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文