《从0开始写一个微内核操作系统》1-构建GN-base

GN-base

https://github.com/jingjin666/GN-base.git

BUILD.gn

BUILD.gn是GN构建的核心配置文件,GN-base中只用到了一些基本语法,其他高级语法可参考goolge官方文档https://gn.googlesource.com/gn/进行扩展

GN最小系统

  • .gn
  • BUILD.gn
  • build/config/BUILDCONFIG.gn
  • build/toolchain/BUILD.gn

.gn

buildconfig = "//build/config/BUILDCONFIG.gn"

BUILD.gn

executable

executable为最后输出的可执行文件,依赖于os_modules,一个系统中可以根据需要生成多个可执行文件
os_config为生成可执行文件的配置文件,也就是ldflags

gcc下的ldflags参考https://sourceware.org/binutils/docs-2.38/ld/Options.html#Options

os_modules模块依赖于os下的BUILD.gn

import("//build/config/compiler.gni")

group("os_modules") {
    deps = [ 
        "//os",
    ]
}

config("os_config") {
    defines = []
    ld_script = rebase_path("//os/linker.lds")
    ldflags = [
        "-g",
        "-T",
        "$ld_script"
    ]
}

executable("os") {
    configs = []
    configs += [ ":os_config" ]

    sources = []

    deps = [
        ":os_modules",
    ]
}

target = "$root_out_dir/os.elf"
target_elf = "$root_out_dir/image/os.elf"
target_bin = "$root_out_dir/image/os.bin"
target_hex = "$root_out_dir/image/os.hex"
target_dump = "$root_out_dir/image/os.dump"

copy("copy_os") {
    deps = [ ":os" ]
    sources = [ "$target" ]
    outputs = [ "$target_elf" ]
}

action("build_image") {
    deps = [
        ":copy_os",
    ]

    script = "//build/py_script/elf_format.py"
    sources = [
        "$target_elf",
    ]
    
    outputs = [
        "$target_bin",
        "$target_hex",
        "$target_dump",
    ]

    args = [
        "--format_tool",
        "$crossdev",
        "--elf",
        rebase_path("$target_elf"),
        "--bin",
        rebase_path("$target_bin"),
        "--hex",
        rebase_path("$target_hex"),
        "--dump",
        rebase_path("$target_dump"),
        "--dir",
        rebase_path("$root_out_dir/image"),
        "--flag",
        "bd",
    ]
}

copy

copy为拷贝动作,定义在build/toolchain/BUILD.gn中

action

当生成可执行文件后,你还需要一些后续操作,这个时候你可以定义action,actoin实际上是通过python脚本来实现自定义操作

build/config/BUILDCONFIG.gn

配置GN使用的编译器,配置toolchain变量来配置使用gcc或者clang等编译器

toolchain = "gcc"
#toolchain = "clang"

target_toolchain = "//build/toolchain:${toolchain}"

set_default_toolchain(target_toolchain)

build/toolchain/BUILD.gn

配置gcc或者clang等其他编译的具体编译选项

gcc

gcc变量定义在build/config/compiler.gni头文件中

import("//build/config/compiler.gni")
toolchain("gcc") {
    tool("asm") {
        depfile = "{{output}}.d"
        command = "${crossdev}gcc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
        depsformat = "gcc"
        description = "ASM {{output}}"
        outputs =
            [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
    }

    tool("cc") {
        depfile = "{{output}}.d"
        command = "${crossdev}gcc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
        depsformat = "gcc"
        description = "CC {{output}}"
        outputs =
            [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
    }

    tool("cxx") {
        depfile = "{{output}}.d"
        command = "${crossdev}g++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
        depsformat = "gcc"
        description = "CXX {{output}}"
        outputs =
            [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
    }

    tool("link") {
        outfile = "{{target_output_name}}{{output_extension}}"
        rspfile = "$outfile.rsp"
        command = "${crossdev}ld {{ldflags}} -o $outfile --start-group @$rspfile {{solibs}} --end-group {{libs}}"
        description = "LINK $outfile"
        default_output_dir = "{{root_out_dir}}"
        rspfile_content = "{{inputs}}"
        outputs = [ outfile ]
        default_output_extension = ".elf"
    }

    tool("alink") {
        outfile = "{{target_output_name}}{{output_extension}}"
        rspfile = "$outfile.rsp"
        command = "${crossdev}ar cr $outfile @$rspfile"
        description = "AR $outfile"
        default_output_dir = "{{root_out_dir}}"
        rspfile_content = "{{inputs}}"
        outputs = [ outfile ]
        default_output_extension = ".a"
        output_prefix = "lib"
    }

    tool("solink") {
        outfile = "{{target_output_name}}{{output_extension}}"
        rspfile = "$outfile.rsp"
        command = "${crossdev}gcc --shared -fPIC -o $outfile @$rspfile"
        description = "SOLINK $outfile"
        default_output_dir = "{{root_out_dir}}"
        rspfile_content = "{{inputs}}"
        outputs = [ outfile ]
        default_output_extension = ".so"
        output_prefix = "lib"
    }

    tool("stamp") {
        command = "touch {{output}}"
        description = "STAMP {{output}}"
    }

    tool("copy") {
        command = "cp -af {{source}} {{output}}"
        description = "COPY  {{source}} {{output}}"
    }
}

toolchain("clang") {

}

clang

build/config/compiler.gni

gcc

gcc下通用的变量包括:

  • crossdev:是否需要交叉编译
  • defines:宏定义
  • include_dirs:头文件目录
  • asmflags:汇编编译选项
  • cflags:目标编译选项
  • cflags_c:C标准的编译选项
  • cflags_cc:C++标准编译选项

arch_flags定义了所选编译器针对目标硬件的编译选项,包括不限于:

  • arch_cpu
  • arch_c
  • debug
  • cpu
  • optimaztion

不同编译器对应不同cpu架构所支持的arch_flags是不一样的,这里的arch_flags只是gcc对应cpu的flags

gcc支持的flags参考https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html

arch_cpuflags =  []
arch_cpuflags =  [ "-mcpu=cortex-a53" ]

arch_cflags = []
arch_cflags = [ "-nostdlib",
                "-nostdinc",
                "-fno-builtin",
                "-fno-common",
                "-fno-stack-protector",
                "-fno-strict-overflow",
                "-fno-strict-aliasing" ]

debug_build_flags =  []
debug_build_flags =  [ "-g" ]
debug_build_flags += [ "-Wall",
                       "-Wstrict-prototypes",
                       "-Wshadow",
                       "-Wundef" ]

arch_optimaztion_flags = []

arch_flags  = arch_cpuflags + arch_cflags + debug_build_flags + arch_optimaztion_flags

crossdev = "aarch64-none-elf-"

cflags_c = [ "-std=gnu99" ]
cflags_cc = [ "-std=gnu++17" ]
cflags = arch_flags
asmflags = cflags
asmflags += [ "-D__ASSEMBLY__" ]
defines = [ "GIT_VERSION=" ]

添加新代码到GN-base中

1、新增文件夹os/test

2、修改os/BUILD.gn

添加deps和configs

group("os") {
    deps = []
    deps += [
        "arch",
        "test",
    ]
}

config("kernel") {
    configs = []
    configs += [
        "arch:kernel",
        "test:kernel",
    ]
}

3、新增源文件和头文件os/test/test.c,os/test/include/test.h

4、新增os/test/BUILD.gn

如果需要把当前头文件目录导出到系统头文件目录,需要在config-kernel中加入include_dirs
如果当前源文件需要导入kernel系统头文件目录,需要在configs中加入//build/config:kernel

module_name = get_path_info(rebase_path("."), "name")
source_set(module_name) {
    sources = [
        "test.c",
    ]

  	# 导入的配置目录
    configs = [
        "//build/config:kernel",
    ]
}

# 导出的头文件
config("kernel") {
    include_dirs =  [ "./include" ]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值