介子创建不会编译的构建文件

Posted

技术标签:

【中文标题】介子创建不会编译的构建文件【英文标题】:Meson creates build files which will not compile 【发布时间】:2021-09-22 02:31:36 【问题描述】:

我正在尝试将现有代码树移植到 centos 7 机器上的介子构建系统。介子配置工作正常,但是当我尝试编译时,它失败了。代码是专有的,所以我创建了一个示例来说明问题(我希望足够准确。)我不能随意重构目录树。

这是树:

mesonex/
    alpha/
        beta/
            alpha/
                inc/
                    funcs.h
                    numbers.h
                src/
                    numbers.cpp
                    funcs.cpp
        src/
            example.cpp
            meson.build

我的 meson.build:

project('example', 'cpp')

srcs=['example.cpp']

srcs+='../beta/alpha/src/funcs.cpp'

srcs+='../beta/alpha/src/funcs.cpp'

incdirs=include_directories('../beta/alpha/inc')

executable('example', srcs, include_directories: incdirs)

这里是主要的 example.cpp 文件:

#include <iostream>
#include "../beta/alpha/inc/numbers.h"
#include "../beta/alpha/inc/funcs.h"

int main()

    std::cout << "Hello" << std::endl;
    std::cout << interestingNumber() << std::endl;
    std::cout << interestingFunc() << std::endl;


这些是支持的 cpp 文件:

// funcs.cpp
#include "../inc/numbers.h"

float interestingFunc()

    return (interestingNumber()+1)/2;


// numbers.cpp

float interestingNumber()

    return 11.3355;


这些是头文件:

// funcs.h

float interestingFunc();

// numbers.h

float interestingNumber();

请注意,目录名称的重复是故意的。也许这让介子在弄清楚如何处理#includes 时感到困惑?

这只是我尝试过的许多不同构建策略的一个示例。

【问题讨论】:

以什么方式失败?什么是编译器错误消息? 【参考方案1】:

我立即看到一个问题,可能只是您的示例的问题,而不是您的实际代码:Meson 认为带有 project() 调用的 meson.build 文件是源的“根”目录结构。您不能要求它包含根目录之外的文件。在类 Unix 操作系统上,它类似于 cp /../foo .。这可能只是您的示例中的一个错误,因为这当然不是真正的代码。

所以,如果我们将其重写为 (mesonex/alpha/meson.build):

# no project(), that would be in mesonex/meson.build)

sources = files(
  'example.cpp',
  '../beta/alpha/src/funcs.cpp',
  '../beta/alpha/src/numbers.cpp',  # you have a typo in your example, funcs.cpp is listed twice.
)

executable(
  'example',
  sources,
  include_directories : include_directories('../beta/alpha/inc'),
)

应该可以。

请注意,您可能需要考虑使用方便的静态库而不是返回代码,因为这是最佳实践,您可以编写类似 (mesonex/alpha/beta/meson.build) 的内容:

lib_beta = static_library(
  'beta',
  ['src/funcs.cpp', 'src/numbers.cpp']
)

idep_beta = declare_dependency(
  link_with : lib_beta,
  include_directories : include_directories('.'),
)

然后在(src/meson.build)中:

executable(
  'example',
  'source.cpp',
  dependencies : idep_beta
)

这就是你所需要的,因为idep_beta 带有链接和包含信息。

【讨论】:

谢谢!这确实适用于我的例子。我以为我在实际代码上尝试过类似的东西,但也许我搞砸了实现。【参考方案2】:

这是一个后续 - 该解决方案适用于我的示例,但不适用于实际代码。我的模型一定是不完整的(在某种程度上我还没有确定。)配置阶段有效,但在编译阶段,cpp源中的#includes被标记为“文件或目录不存在”。介子如何协调指定的包含目录与源中的#include 语句? #include 路径可能与实际 cpp 源的实际目录相关。这是否意味着我必须编辑所有来源中的所有#includes - 这将是一个真正的负面因素。我们使用一些非常大的代码库。

【讨论】:

Meson 使用 include_directories() 执行此操作,传递给该函数的每个路径都将成为一个 -I 参数,指向树中的源目录和构建目录。因此,如果您在同一个文件中有#include "a/b/c.h"#include "b/d.h",则需要include_directories('.', 'a') 之类的内容。所有采用 include_directories 的函数都采用其中的数组。

以上是关于介子创建不会编译的构建文件的主要内容,如果未能解决你的问题,请参考以下文章

介子构建系统 - 将编译器更改为 g++

介子构建:手动添加可执行文件的依赖路径

Autotools 交叉编译和生成源

介子找不到静态库

makefile不会在windows中编译:系统找不到指定的文件

使用介子和忍者安装 DPDK