Closed neko-para closed 2 years ago
Can I assume that the order of objects is exactly equal the order sources added?
Another problem
Is there a best practice for inserting prebuilt object files? They should be placed at a specified place, so it cannot be archived. Currently I only know that I can use custom rule for objects which just copy them. It is quite wierd.
About my project
Kernel linking:
$(CC) -T link.ld -o $@ -ffreestanding -nostdlib $(OBJS) -lgcc
Objects:
OBJS=$(patsubst %,$(BUILD)/%,$(ARCHROOT)/crti.o $(ARCHROOT)/crtbegin.o \
$(ARCHROOT)/boot.o $(ARCHROOT)/io.o $(ARCHROOT)/idt.o \
$(patsubst %.c,%.o,$(CSRCS)) \
$(ARCHROOT)/crtend.o $(ARCHROOT)/crtn.o)
Notice that crti and crtn is wrote by me and have corresponding .s file; crtbegin and crtend is copied by gcc
$(BUILD)/$(ARCHROOT)/crtbegin.o $(BUILD)/$(ARCHROOT)/crtend.o:
OBJ=`$(CC) $(CFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@
And these four object files' order is fixed, and others should be inside.
Can I assume that the order of objects is exactly equal the order sources added?
right
Is there a best practice for inserting prebuilt object files?
use add_files("xxx.o") or insert it in target/on_load
target("xxx")
on_load(function (target)
table.insert(target:objectfiles(), 1, "begin.o")
table.insert(target:objectfiles(), "end.o")
end)
add_files("src/*.c")
you can also write rule to add it.
But the verbose output shows that it changes the order 🤔
part of xmake.lua
target("kernel")
set_kind("binary")
set_toolchains("i686")
add_files("kernel/arch/i386/crti.s")
add_files("kernel/arch/i386/*.s|kernel/arch/i386/crtn.s")
add_files("kernel/arch/i386/*.c")
add_files("kernel/*.c")
add_files("libc/*.c")
add_files("kernel/arch/i386/crtn.s")
add_includedirs("$(projectdir)")
command in verbose output
/home/nekosu/osdev/inst/bin/i686-elf-gcc -o build/linux/x86_64/release/kernel
build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/crti.s.o build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/crtn.s.o
build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/io.s.o build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/boot.s.o build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/vga.c.o
build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/debug.c.o build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/term.c.o build/.objs/kernel/linux/x86_64/release/kernel/arch/i386/gengdt.c.o
build/.objs/kernel/linux/x86_64/release/kernel/keyboard.c.o build/.objs/kernel/linux/x86_64/release/kernel/mouse.c.o build/.objs/kernel/linux/x86_64/release/kernel/font.c.o build/.objs/kernel/linux/x86_64/release/kernel/memory.c.o build/.objs/kernel/linux/x86_64/release/kernel/idt.c.o build/.objs/kernel/linux/x86_64/release/kernel/kernel.c.o
build/.objs/kernel/linux/x86_64/release/kernel/gdt.c.o build/.objs/kernel/linux/x86_64/release/kernel/input.c.o build/.objs/kernel/linux/x86_64/release/libc/vector.c.o build/.objs/kernel/linux/x86_64/release/libc/queue.c.o build/.objs/kernel/linux/x86_64/release/libc/list.c.o build/.objs/kernel/linux/x86_64/release/libc/string.c.o -T link.ld -ffreestanding
The object link sequence of the same source file is fixed, but your project has two file types, .s and .c, and their object link sequence is not fixed.
all asm objects (fixed order) -> all c objects (fixed order)
You can write a little script to adjust the order, you can use custom rules, or you can write directly under the target
target("test")
set_kind("binary")
add_files("src/*.s")
add_files("src/*.cpp")
add_files("src/*.c")
after_load(function (target)
local beginidx, endidx
for idx, objectfile in ipairs(target:objectfiles()) do
local filename = path.filename(objectfile)
if filename == "crti.s.o" then
beginidx = idx
elseif filename == "crtn.s.o" then
endidx = idx
end
if beginidx and endidx then
break
end
end
if beginidx then
table.swap(target:objectfiles(), 1, beginidx)
end
if endidx then
table.swap(target:objectfiles(), #target:objectfiles(), endidx)
end
end)
It works! Thanks for your help. I've met another question.
There's a source generate by a shell script. I create a rule to excute it, but I cannot add the generated file to sources.
rule("shell")
set_extensions(".sh")
on_build_file(function (target, sourcefile, opt)
import("core.project.depend")
import("utils.progress")
os.mkdir(target:targetdir())
local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".s")
target:add("files", targetfile) -- I try adding this
depend.on_changed(function ()
os.vrunv('sh', {sourcefile, targetfile})
progress.show(opt.progress, "${color.build.object}shell %s", sourcefile)
end, {files = sourcefile})
end)
target("kernel")
set_kind("binary")
set_toolchains("i686")
add_rules("shell")
add_files("kernel/arch/i386/idt.sh") -- add shell script here
you can refer this https://github.com/xmake-io/xmake/blob/master/xmake/rules/lex_yacc/lex/xmake.lua
it will generate source file and compile it as object file, then insert object file to link list.
Is there a variable for output target path? After researching the document I only find variables for directories. I need to copy the build target to a certain directory for further process. Does it mean that I need to hardcode that path?
target:installdir()
target:autogendir()
os.tmpdir()
import("core.project.config")
config.buildir()
then the built binary is equal to target name?
then the built binary is equal to target name?
target:targetfile()
Where can I learn these methods then? I don't find any document about this.
Where can I learn these methods then? I don't find any document about this.
The relevant documentation is not yet complete, only a little bit at present https://xmake.io/#/manual/target_instance
You can look directly at the code first. https://github.com/xmake-io/xmake/blob/master/xmake/core/project/target.lua
Is your feature request related to a problem? Please describe.
I decided to use xmake to manage my OS kernel project. In this project, the order of object files matters. Specifically, crti.o, crtbegin.o must at the begining, and crtend.o, crtn.o must at the end.
Describe the solution you'd like
Support a new attribute for sources as the order of it during linking.
Hacky way is acceptable too. I really don't want to use Makefile to manage that mess anymore.