Executando verificação de segurança...
2

Amei este novo build system, talvez você também goste

Sempre fui um programador hobbysta mais chegado em linguagens de script, as vezes usava go para alguns projetos, php para outros, ruby ...

Até que decidi brincar de OSDEV, seguindo o wiki osdev, craft-your-own-x ...

E cheguei na conclusão que Makefile eram bem chatos e feios de se escrever apesar de obviamente ter muitas qualidades interessantes. (Opinião bem pessoal)

Se não me engano, até o próprio Linus Torvalds ficou com o mesmo pensamento quando adotou o Kbuilds dentro das ferramentas do kernel como uma forma de compilar o mesmo.

Outras opções como Premake, CMake, Meson... nunca chegaram a realmente me agradar.

Até que eu vi um vídeo no canal do Terminal Root sobre esse build system chamado Xmake e achei super-interessante.

Primeira que ele usa a linguagem brasileira lua com algumas funções incrementadas a ele externamente via C.

Segundo que ele dá suporte a exportar para diversos outros build-system se necessário.

Terceiro ele possui resolução de dependências de código integrado via xrepo

Então para mim que tenho alguns projetos como o:

  • FKernel
    Um projeto de kernel feito em C++ e Nasm que possui como objetivo ser um kernel hibrido para uso desktop.
  • Cardinal System
    Um projeto filho do projeto para a construção de uma semente mundial inspirado em Sword Art Online para criação de jogos Indie-MMO com preço muitas vezes mais barato que atualmente

Fica muito mais interessante o uso do que o convencional.


Algumas coisas que tenho que dizer, para projetos simples como o Cardinal, o xmake é muito fácil de usar:

add_rules("mode.debug", "mode.release")

set_languages("cxx20")

-- Add support to libuv, spdlog and sol2
add_requires("sol2", { system = false })
add_requires("libuv", { system = false })
add_requires("spdlog", { system = false })

target("cardinal-system")
set_kind("binary")

set_warnings("everything")

if is_mode("debug") then
	set_optimize("none")
	set_symbols("debug")
	add_defines("__CARDINAL_DEBUG__")
else
	set_optimize("fastest")
end

add_files("Src/**.cpp")
add_includedirs("Include")
add_packages("sol2", "libuv", "spdlog")
target_end() 

Afinal dentro dele não precisa de nenhum work-around para fazer as coisas funcionarem como deveria, e um adendo importante:

O xmake funciona com uma lista de linguagens e determinados tipos de projeto, então se precisa de algo para uma linguagem desconhecida e/ou pouco usada é importante visitar a documentação já que o xmake não é generalista.

E para casos mais complexos precisa saber de alguns work-arounds como faço no FKernel

add_rules("mode.debug", "mode.release")
set_policy("check.auto_ignore_flags", false)
set_targetdir("build")
set_objectdir("build/objs")

set_languages("cxx20", "c17")

toolchain("FKernel_Compiling")
set_kind("standalone")
set_toolset("cc", "clang", "tcc", "cl", "gcc")
set_toolset("cxx", "clang++", "cl", "g++")
set_toolset("ld", "ld.lld", "gold", "link", "ld")
set_toolset("as", "nasm", "yasm", "ml")
toolchain_end()

local flags = {
    general = {
        cxx = {
            "-ffreestanding",
            "-fno-threadsafe-statics",
            "-fno-exceptions",
            "-fno-rtti",
            "-fno-stack-protector",
            "-fno-use-cxa-atexit",
            "-fno-pic",
            "-fno-omit-frame-pointer",
            "-nostdlib",
            "-nostdinc",
            "-Wno-constant-conversion",
            "-Wno-c++11-narrowing",
        },
        asm = {
            "-w-label-orphan",
            "-w-implicit-abs-deprecated",
            "-w-zeroing",
            "-w-other",
        },
        ld = {
            "-T Config/linker.ld",
            "-nostdlib",
            "-z max-page-size=0x1000",
        },
    },
    x86_64 = {
        cxx = {
            "--target=x86_64-unknown-none-elf",
            "-mcmodel=kernel",
            "-mno-sse",
            "-mno-avx",
        },
        asm = {
            "-f elf64",
        },
    },
}

local kernel_non_archicteture_related = {
    "Src/Kernel/Boot/**.cpp",
    "Src/Kernel/Clock/**.cpp",
    "Src/Kernel/Driver/**.cpp",
    "Src/Kernel/Hardware/**.cpp",
    "Src/Kernel/Init/**.cpp",
    "Src/Kernel/Memory/**.cpp",
    "Src/Kernel/Posix/**.cpp",
    "Src/Kernel/Scheduler/**.cpp",
    "Src/LibC/**.c",
    "Src/LibC/**.cpp",
    "Src/LibFK/**.cpp",
}

-- Pré-Kernel
target("FKernel_PreKernel")
    set_kind("object")
    set_default(true)
    set_license("BSD-3-Clause")
    set_warnings("allextra", "error")

    if is_mode("release") then
        set_symbols("hidden")
        set_optimize("faster")
        set_strip("all")
    elseif is_mode("debug") then
        set_symbols("debug")
        set_optimize("fast")
        add_defines("FKERNEL_DEBUG")
    end

    add_cxflags(flags.general.cxx, {force=true})
    add_asflags(flags.general.asm, {force=true})
    add_ldflags(flags.general.ld, {force=true})

    if is_arch("x86_64", "x64") then
        add_cxflags(flags.x86_64.cxx)
        add_asflags(flags.x86_64.asm)
        add_files("Src/PreKernel/Arch/x86_64/*/**.asm")
    end
target_end()

-- Kernel
target("FKernel")
    set_kind("binary")
    set_default(true)
    set_filename("FKernel.bin")
    set_license("BSD-3-Clause")
    set_warnings("allextra", "error")

    add_deps("FKernel_PreKernel") -- garante pré-kernel primeiro

    if is_mode("release") then
        set_symbols("hidden")
        set_optimize("faster")
        set_strip("all")
    elseif is_mode("debug") then
        set_symbols("debug")
        set_optimize("fast")
        add_defines("FKERNEL_DEBUG")
    end

    add_cxflags(flags.general.cxx, {force=true})
    add_asflags(flags.general.asm, {force=true})
    add_ldflags(flags.general.ld, {force=true})

    add_includedirs("Include")

    if (is_arch("x86_64", "x64")) then
        add_cxflags(flags.x86_64.cxx)
        add_asflags(flags.x86_64.asm)
    
        add_files("Src/Kernel/Arch/x86_64/**.cpp")
        add_files("Src/Kernel/Arch/x86_64/**.asm")
    end

    add_files(kernel_non_archicteture_related)

    after_link(function(target)
        os.execv("lua Meta/x86_64-tools/mount_mockos.lua")
    end)

    on_run(function(target)
        os.execv("lua Meta/x86_64-tools/run_mockos.lua")
    end)

    on_clean(function(target)
        os.execv("rm -rf Build build logs/")
    end)

target_end()

-- Análise
task("analyze")
    set_category("plugin")
    set_menu({
        usage = "xmake analyze",
        description = "Run the script to analyze the kernel runtime",
    })
    on_run(function()
        os.execv("lua Meta/x86_64-tools/analyze_kernel_runtime.lua")
    end)
task_end()

Sinceramente, e por opinião pessoal se um dia vocês tentarem com as linguagens:

  • pascal
  • c++
  • zig
  • go
  • nim
  • dlang
  • cuda
  • rust
  • kotlin
  • vala
  • swift
  • fortran
  • objc
  • c
  • objc++

Vale muito a pena testar o xmake, principalmente se for apps mais comuns.

Muito interessante e empolgante esse tipo de uso e super recomendado.

Carregando publicação patrocinada...