如何使用meson构建C语言项目

meson是用python写的一个程序构建工具,meson的官网在https://mesonbuild.com/index.html,这里有meson的使用手册,这个手册很好用。

meson和make一样,需要写描述文件告诉meson要构建什么,这个描述文件 就是meson.buildmeson

meson.build中的定义生成具体的构建定义文件build.ninja, ninja根据build.ninja完成具体构建。

所以,不像make直接根据Makefile文件完成构建,meson 需要和ninja配合一起完成构建。

图片[1]-如何使用meson构建C语言项目-不念博客

一.不同系统安装Meson和Ninja工具包

在 Ubuntu 上安装 Meson 和 Ninja:

# 更新软件包列表
sudo apt-get update
# 安装 Meson 和 Ninja
sudo apt-get install meson ninja-build

在 CentOS 上安装 Meson 和 Ninja:

# 更新软件包列表
sudo yum update
# 安装 Meson 和 Ninja
sudo yum install meson ninja-build

二.构建简单的C语言项目

建立一个项目目录meson_project,包括多个源文件和头文件,在这个示例中,我将展示如何组织一个稍微复杂的项目。

2.1 项目结构

假设你的项目有以下结构:

project_root/ #项目源码目录
|-- src/
|   |-- main.c
|   |-- util/
|       |-- helper.c
|       |-- helper.h
|-- include/
|   |-- project.h
|-- meson.build # 描述meson如何组织文件进行构建
|-- native-file.txt  #指定gcc,g++,cpu架构版本信息

# 构建的时候,新建一个Build目录放构建的产出结果,可以根据不同的编译配置创建不同的build目录
# 示范如下 
$ meson arm-build --cross-file config_file.txt  #指定arm架构的编译器构建
$ ninja -C build_dir #输出到build_dir目录下
project_root/ 
|-- x86_build/
|-- arm_build/

main.c

#include <stdio.h>
#include "project.h"
#include "util/helper.h"

int main() {
    printf("Hello, Meson!\n");
    print_hello_from_helper();
    return 0;
}

util/helper.c

#include <stdio.h>
#include "helper.h"

void print_hello_from_helper() {
    printf("Hello from helper!\n");
}

util/helper.h

#ifndef HELPER_H
#define HELPER_H

void print_hello_from_helper();

#endif

include/project.h

#ifndef PROJECT_H
#define PROJECT_H

// Your project-specific declarations go here

#endif

meson.build

这个文件定义了一个my_project的工程,并且定义了my_hello这个构建目标,以及使用的源文件,头文件等等。

project('my_project', 'c')

# Define sources
src_files = files(['src/main.c', 'src/util/helper.c'])

# Define include directories
inc_path = include_directories('include')

# Set CC environment variable to specify the compiler

# Add an executable
executable('my_hello', src_files, include_directories: inc_path)

native-file.txt

该文件指定一些构建要用的参数

[binaries]
c = ['ccache', 'x86_64-linux-gnu-gcc']
cpp = ['ccache', 'x86_64-linux-gnu-g++']
ar = 'x86_64-linux-gnu-gcc-ar'
strip = 'x86_64-linux-gnu-strip'
pkgconfig = 'x86_64-linux-gnu-pkg-config'
pcap-config = ''
cmake = 'cmake'

2.2 完整构建meson_project项目

1. meson setup build 创建构建目录

这个是告诉meson在哪个目录下构建(这里是源码根目录下的build目录),meson一定要在一个和源码独立的目录里做构建,这样多次构建可以指定不同的构建目录和构建配置,相互之间不受影响,比如对于同样的程序,构建一个riscv版本可以这样指定构建目录:

meson setup --cross-file ./rv_cross_file rv_builddir

开始创建build目录

$ meson setup build  # 创建build目录
The Meson build system
Version: 0.61.2
Source dir: /home/meson_project
Build dir: /home/meson_project/build
Build type: native build
Project name: my_project
Project version: undefined
C compiler for the host machine: cc (gcc 11.4.0 "cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0")
C linker for the host machine: cc ld.bfd 2.38
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 1

Found ninja-1.10.1 at /usr/bin/ninja

2.根据native_file.txt配置文件,指定构建目录

meson_project$ ls
build  include  meson.build  native-file.txt  src
meson_project$ meson build --cross-file native-file.txt
Directory already configured.

Just run your build command (e.g. ninja) and Meson will regenerate as necessary.
If ninja fails, run "ninja reconfigure" or "meson --reconfigure"
to force Meson to regenerate.

If build failures persist, run "meson setup --wipe" to rebuild from scratch
using the same options as passed when configuring the build.
To change option values, run "meson configure" instead.

3.使用ninja将源码编译并输出到build目录下

meson_project$ ninja -C build -v
ninja: Entering directory `build'
[1/3] cc -Imy_hello.p -I. -I.. -I../include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -g -MD -MQ my_hello.p/src_util_helper.c.o -MF my_hello.p/src_util_helper.c.o.d -o my_hello.p/src_util_helper.c.o -c ../src/util/helper.c
[2/3] cc -Imy_hello.p -I. -I.. -I../include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -g -MD -MQ my_hello.p/src_main.c.o -MF my_hello.p/src_main.c.o.d -o my_hello.p/src_main.c.o -c ../src/main.c
[3/3] cc  -o my_hello my_hello.p/src_main.c.o my_hello.p/src_util_helper.c.o -Wl,--as-needed -Wl,--no-undefined
meson_project$
meson_project$
meson_project$ ls
build  include  meson.build  native-file.txt  src

4.进入build目录查看构建结果

# 进入build目录查看构建结果
meson_project$ cd build/
meson_project/build$ ls
build.ninja  compile_commands.json  meson-info  meson-logs  meson-private  my_hello  my_hello.p
meson_project/build$ ./my_hello
Hello, Meson!
Hello from helper!
meson_project/build$

5.修改main.c文件,重新构建项目

$ vim main.c
#include <stdio.h>
#include "project.h"
#include "util/helper.h"

int main() {
    printf("Hello, Meson!\n");
    printf("Hello, now you can you use it to build project!\n");
    print_hello_from_helper();
    return 0;
}

回到根目录meson_project重新构建.

meson_project $ meson build --cross-file native-file.txt
Directory already configured.

Just run your build command (e.g. ninja) and Meson will regenerate as necessary.
If ninja fails, run "ninja reconfigure" or "meson --reconfigure"
to force Meson to regenerate.

If build failures persist, run "meson setup --wipe" to rebuild from scratch
using the same options as passed when configuring the build.
To change option values, run "meson configure" instead.
meson_project$ ninja -C build
ninja: Entering directory `build'
[2/2] Linking target my_hello
meson_project$ cd build/
meson_project/build$ ./my_hello
Hello, Meson!
Hello, now you can you use it to build project!
Hello from helper!
meson_project/build$

© 版权声明
THE END