03.meson和ninja

meson和ninja

需求

基于DPDK的转发平台需求

  1. 转发平台库根据不同功能放到不同目录下,依赖DPDK库,每个目录都编译成一个动态库.so,一个静态库.a;
  2. 转发平台install到特定目录,像DPDK一样,生产pkg-config文件,提供给DPDK APP调用;

基于DPDK+转发平台的APP需求

  1. DPDK APP的main函数和一些库都编译成.so和.a,依赖dpdk转发平台库、DPDK库,静态编译成可执行文件;
  2. 一些工具在不同的目录下,也分别编译成可执行文件;

基于DPDK的转发平台

加载dpdk库

编译时使用:
export PKG_CONFIG_PATH=/home/dpdkinstall/lib64/pkgconfig/;ldconfig

运行是使用:
LD_LIBRARY_PATH=/home/dpdkinstall/lib64;ldconfig

目录结构

.
├── ABI_VERSION
├── buildtools
│   └── pkg-config
│       ├── meson.build
│       └── set-static-linker-flags.py
├── meson.build
├── src
│   ├── ma
│   │   ├── ma.c
│   │   ├── ma.h
│   │   └── meson.build
│   ├── mb
│   │   ├── mb.c
│   │   ├── mb.h
│   │   └── meson.build
│   ├── mc
│   │   ├── mc.c
│   │   ├── mc.h
│   │   └── meson.build
│   ├── md
│   │   ├── md.c
│   │   ├── md.h
│   │   └── meson.build
│   └── meson.build
└── VERSION

文件内容

VERSION

说明:存放版本信息。当前为:23.11.0;会在.pc文件中体现;

[root@dpdk-dev projx]# cat VERSION 
23.11.0
ABI_VERSION

说明:application binary interface (ABI);两个二进制程序模块之间的接口;当前为:24.0;会在so库文件上体现;

[root@dpdk-dev projx]# cat ABI_VERSION 
24.0
./meson.build

说明:主meson.build。

  1. 通过project申明产品名称,使用语言,版本信息,license,meson版本和默认options,当前指定了编译器使用c11,静态编译,并且安装目录在/home/fwdpinstall。
  2. 读取dpdk的pc文件,获取库、头文件、编译参数等信息。提前执行exportPKG_CONFIG_PATH=/home/dpdkinstall/lib64/pkgconfig/;ldconfig
  3. 读取文件获取abi_version和so_version
  4. 设置default_cflags、default_shared_deps、default_static_deps
  5. subdir递归src目录
  6. 生产pkg-config的pc文件
[root@dpdk-dev projx]# cat meson.build 
project('FWDP', 'c',
      version: run_command(find_program('cat', 'more'),
            files('VERSION'), check: true).stdout().strip(),
      license: 'BSD',
      default_options: [
        'buildtype=release',
        'c_std=c11',
        'default_library=static',
        'prefix=/home/fwdpinstall',
      ],
      meson_version: '>= 0.53.2'
)

shared_dpdk = dependency('libdpdk')
static_dpdk = dependency('libdpdk', static: true)

abi_version = run_command(find_program('cat', 'more'), files('ABI_VERSION'), check: true).stdout().strip()
so_version = abi_version.split('.')[0]

default_cflags = []
default_shared_deps = [shared_dpdk]
default_static_deps = [static_dpdk]

fwdp_libraries = []
fwdp_static_libraries = []
fwdp_extra_ldflags = []

subdir('src')

subdir('buildtools/pkg-config')
buildtoos/pkg-config/meson.build

生成pkg-config识别的pc文件

[root@dpdk-dev pkg-config]# pwd
/home/projx/buildtools/pkg-config
[root@dpdk-dev pkg-config]# cat meson.build 

python3 = import('python').find_installation(required: false)
if python3.found()
    py3 = [python3]
else
    py3 = ['meson', 'runpython']
endif

pkg_extra_cflags = []
pkg = import('pkgconfig')
pkg.generate(name: 'fwdp-libs',
             filebase: 'libfwdp-libs',
             description: 'fwdp-libs is fast forward platform.........',
             version: meson.project_version(),
             subdirs:['.'],
             extra_cflags: pkg_extra_cflags,
             libraries: ['-Wl,--as-needed'] + fwdp_libraries,
             libraries_private: fwdp_extra_ldflags)


platform_flags = []
platform_flags += ['-Wl,--export-dynamic']

pkg.generate(name: 'fwdp',
             filebase: 'libfwdp',
             version: meson.project_version(),
             description: 'fwdp is fast forward platform.........',
             requires: ['libfwdp-libs'],
             libraries_private: ['-Wl,--whole-archive'] + fwdp_static_libraries + ['-Wl,--no-whole-archive'] + platform_flags
             )


run_command(py3, files('set-static-linker-flags.py'), check: true)
buildtools/pkg-config/set-static-linker-flags.py

将动态链接名称通过脚本改成静态库的名称

#!/usr/bin/env python3

import os
import sys

def fix_ldflag(f):
    if not f.startswith('-lfwdp_'):
        return f
    return '-l:lib' + f[2:] + '.a'


def fix_libs_private(line):
    if not line.startswith('Libs.private'):
        return line
    ldflags = [fix_ldflag(flag) for flag in line.split()]
    return ' '.join(ldflags) + '\n'


def process_pc_file(filepath):
    print('Processing', filepath)
    with open(filepath) as src:
        lines = src.readlines()
    with open(filepath, 'w') as dst:
        dst.writelines([fix_libs_private(line) for line in lines])


if 'MESON_BUILD_ROOT' not in os.environ:
    print('This script must be called from a meson build environment')
    sys.exit(1)
for root, dirs, files in os.walk(os.environ['MESON_BUILD_ROOT']):
    pc_files = [f for f in files if f.endswith('.pc')]
    for f in pc_files:
        process_pc_file(os.path.join(root, f))
src/meson.build

说明:被依赖的模块必须放在使用他的模块的前面;例子中:md依赖ma/mb/mc,ma依赖mc;那么mc要放在ma前面,mb随便放,md放最后;
并将库存到fwdp_libraries、fwdp_static_libraries两个变量中;

libraries = [
    'mc',
    'ma',
    'mb',
    'md'
]

foreach l:libraries
  dirname = l
  libname = l

  cflags = default_cflags
  shared_deps = default_shared_deps
  static_deps = default_static_deps
  includes = []
  deps = []
  headers = []

  subdir(dirname)

  foreach d:deps
    if not is_variable('shared_fwdp_' + d)
      error('Cannot build explicitly requested lib "@0@".\n'.format(libname)
        + '\tPlease add missing dependency "@0@" to "enable_libs" option'.format(d))
    else
      shared_deps += [get_variable('shared_fwdp_' + d)]
      static_deps += [get_variable('static_fwdp_' + d)]
    endif
  endforeach

  install_headers(headers)
  includes = include_directories(dirname)

  static_lib = static_library('fwdp_' + libname,
                              sources,
                              dependencies: static_deps,
                              c_args: cflags,
                              include_directories: includes,
                              install: true)
  static_dep = declare_dependency(link_with: static_lib,
                                  include_directories: includes,
                                  dependencies: static_deps)
  set_variable('static_fwdp_' + libname, static_dep)


  shared_lib = shared_library('fwdp_' + libname,
                              sources,
                              dependencies: shared_deps,
                              c_args: cflags,
                              include_directories: includes,
                              version: abi_version,
                              soversion: so_version,
                              install: true)

  shared_dep = declare_dependency(link_with: shared_lib,
                                  include_directories: includes,
                                  dependencies: shared_deps)
  set_variable('shared_fwdp_' + libname, shared_dep)

  fwdp_libraries = [shared_lib] + fwdp_libraries
  fwdp_static_libraries = [static_lib] + fwdp_static_libraries
endforeach
src/ma/meson.build
sources = files('ma.c')
headers = files('ma.h')

deps += ['mc']
src/mb/meson.build
sources = files('mb.c')
headers = files('mb.h')
src/mc/meson.build
sources = files('mc.c')
headers = files('mc.h')
src/md/meson.build
sources = files('md.c')
headers = files('md.h')

deps += ['mb', 'mc', 'ma']

编译执行命令

  1. 在projx目录下执行:meson setup build
  2. 到build目录下:build
  3. 编译项目:ninja
  4. install项目:ninja install;会被安装到/home/fwdpinstall目录下;
[root@dpdk-dev build]# ninja install
[0/1] Installing files.
Installing src/libfwdp_mc.a to /home/fwdpinstall/lib64
Installing src/libfwdp_mc.so.24.0 to /home/fwdpinstall/lib64
Installing src/libfwdp_ma.a to /home/fwdpinstall/lib64
Installing src/libfwdp_ma.so.24.0 to /home/fwdpinstall/lib64
Installing src/libfwdp_mb.a to /home/fwdpinstall/lib64
Installing src/libfwdp_mb.so.24.0 to /home/fwdpinstall/lib64
Installing src/libfwdp_md.a to /home/fwdpinstall/lib64
Installing src/libfwdp_md.so.24.0 to /home/fwdpinstall/lib64
Installing /home/projx/src/mc/mc.h to /home/fwdpinstall/include
Installing /home/projx/src/ma/ma.h to /home/fwdpinstall/include
Installing /home/projx/src/mb/mb.h to /home/fwdpinstall/include
Installing /home/projx/src/md/md.h to /home/fwdpinstall/include
Installing /home/projx/build/meson-private/libfwdp-libs.pc to /home/fwdpinstall/lib64/pkgconfig
Installing /home/projx/build/meson-private/libfwdp.pc to /home/fwdpinstall/lib64/pkgconfig

基于DPDK+转发平台的APP需求

加载dpdk库和转发平台库

编译时使用:
PKG_CONFIG_PATH=/home/dpdkinstall/lib64/pkgconfig/:/home/fwdpinstall/lib64/pkgconfig;ldconfig

运行是使用:
LD_LIBRARY_PATH=/home/fwdpinstall/lib64/:/home/dpdkinstall/lib64;ldconfig

目录结构

[root@dpdk-dev projapp]# tree
.
├── ABI_VERSION
├── meson.build
├── src
│   ├── appa
│   │   ├── appa.c
│   │   ├── appa.h
│   │   └── meson.build
│   ├── appb
│   │   ├── appb.c
│   │   ├── appb.h
│   │   └── meson.build
│   ├── main
│   │   ├── main.c
│   │   ├── main.h
│   │   └── meson.build
│   └── meson.build
└── VERSION

文件内容

VERSION
[root@dpdk-dev projapp]# cat VERSION 
0.1.0
ABI_VERSION
[root@dpdk-dev projapp]# cat ABI_VERSION 
24.0
meson.build

link_whole 和 dependencies都是用static的库,编译出来的可执行文件就会很大,dpdk和转发平台的库都会打包在一起。

project('myapp', 'c',
      version: run_command(find_program('cat', 'more'),
            files('VERSION'), check: true).stdout().strip(),
      license: 'BSD',
      default_options: [
        'buildtype=release',
        'c_std=c11',
        'default_library=static',
        'prefix=/home/myapp',
      ],
      meson_version: '>= 0.53.2'
)

objs = 'myapp'
abi_version = run_command(find_program('cat', 'more'), files('ABI_VERSION'), check: true).stdout().strip()
so_version = abi_version.split('.')[0]

ext_shared_deps = [dependency('libdpdk'), dependency('libfwdp')]
ext_static_deps = [dependency('libdpdk', static: true), dependency('libfwdp', static: true)]

default_cflags = []
ldflags = []
default_shared_deps = [ext_shared_deps]
default_static_deps = [ext_static_deps]

myapp_libraries = []
myapp_static_libraries = []

subdir('src')

executable(objs,
           include_directories: includes,
           link_whole: myapp_static_libraries,
           link_args: ldflags,
           c_args: cflags,
           dependencies: ext_static_deps,
           install: true)
src/meson.build
libraries = [
    'appa',
    'appb',
    'main'
]

deps = []

foreach l:libraries
  dirname = l
  libname = l

  cflags = default_cflags
  shared_deps = default_shared_deps
  static_deps = default_static_deps
  includes = []
  deps = []
  headers = []

  subdir(dirname)

  foreach d:deps
    if not is_variable('shared_myapp_' + d)
       error('Cannot build explicitly requested lib "@0@".\n'.format(libname)
         + '\tPlease add missing dependency "@0@" to "enable_libs" option'.format(d))
    else
      shared_deps += [get_variable('shared_myapp_' + d)]
      static_deps += [get_variable('static_myapp_' + d)]
    endif
  endforeach

  install_headers(headers)
  includes = include_directories(dirname)

  static_lib  = static_library(libname,
                             sources,
                             dependencies: static_deps,
                             c_args: cflags,
                             include_directories: includes,
                             install: true)

  static_dep = declare_dependency(link_with: static_lib,
                                  include_directories: includes,
                                  dependencies: static_deps)
  set_variable('static_myapp_' + libname, static_dep)


  shared_lib = shared_library(libname,
                              sources,
                              dependencies: shared_deps,
                              c_args: cflags,
                              include_directories: includes,
                              version: abi_version,
                              soversion: so_version,
                              install: true)

  shared_dep = declare_dependency(link_with: shared_lib,
                                  include_directories: includes,
                                  dependencies: shared_deps)
  set_variable('shared_myapp_' + libname, shared_dep)

  myapp_libraries += [shared_lib]
  myapp_static_libraries += [static_lib]
endforeach
src/appa/meson.build
sources = files('appa.c')
headers = files('appa.h')
src/appb/meson.build
sources = files('appb.c')
headers = files('appb.h')

deps += ['appa']
src/main/meson.build
sources = files('main.c')
headers = files('main.h')

deps += ['appa', 'appb']

编译执行命令

  1. 在projx目录下执行:meson setup build
  2. 到build目录下:cd build
  3. 编译项目:ninja
  4. install项目:ninja install;会被安装到/home/fwdpinstall目录下;
[root@dpdk-dev build]# ninja install
[0/1] Installing files.
Installing src/libappa.a to /home/myapp/lib64
Installing src/libappa.so.24.0 to /home/myapp/lib64
Installing src/libappb.a to /home/myapp/lib64
Installing src/libappb.so.24.0 to /home/myapp/lib64
Installing src/libmain.a to /home/myapp/lib64
Installing src/libmain.so.24.0 to /home/myapp/lib64
Installing myapp to /home/myapp/bin
Installing /home/projapp/src/appa/appa.h to /home/myapp/include
Installing /home/projapp/src/appb/appb.h to /home/myapp/include
Installing /home/projapp/src/main/main.h to /home/myapp/include
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值