I'm playing around with bare-metal x86 and I've hit a snag porting my build from straight-up makefiles to cmake.
In my makefile my objects are defined like this:
LINK_LIST=\
$(LDFLAGS) \
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(LIBS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \
crtbegin.o and crtend.o are 'generated', that is, provided by my cross-compiler (-print-file-name flag). $(LIBS) are -l flags, like -lgcc, etc. Since this is passed directly to the linker the order is as specified.
My cmake target is defines as follows:
ADD_EXECUTABLE(loader
"${INIT_SRC}"
"${INIT_OBJ}"
"${PLATFORM_SRCS}"
"${ISA_SRCS}"
"${GENERIC_SRCS}"
"${FINI_OBJ}"
"${FINI_SRC}")
INIT_OBJ and FINI_OBJ have EXTERNAL_OBJECT and GENERATED set to true in source file properties. Looking at the command line when running the generated makefile I see that all source files are in the order specified, but init and fini objects are last in the list.
Here is the resulting command line (edited for brevity):
i686-elf-gcc -nostdlib -ffreestanding -nostdinc -T linker.ld -lgcc crti.s.obj boot.s.obj loader.c.obj crtn.s.obj crtbegin.o crtend.o -o loader
The -lgcc flag is explicit in my LINK_FLAGS, which is also something I would like to change.
So I have a few questions regarding this:
Why isn't cmake using the order for the two external object files, but IS using it for the compiled ones?
How can I tell cmake to treat these objects the same as the ones coming from my sources?
How could I get a complete clone of the setup I have in my Makefile (with the library flags between my object files)
I did also check out CMAKE_C_LINK_EXECUTABLE as well, but it doesn't seem to have enough granularity/control over the linker params to achieve this.
I'm using cmake 3.10.2 on ubuntu.
And another (off-topic) question about cmake:
It doesn't treat .S as a standard assembly file extension. I tried adding it with LIST(APPEND CMAKE_ASM-ATT_SOURCE_FILE_EXTENSIONS S), and it does add it just fine, however the files still aren't getting compiled unless I change it to .s. Has anyone else had this issue?
Thanks!
Objects crtbegin.o and crtend.o, which has specific requirement about position in the link command, may be treated as a part of toolchain. If you decide that, then you can set the variable CMAKE_C_LINK_EXECUTABLE to reflect this specific:
SET(ARCHDIR "<...>")
# Object 'crtbegin.o' will be linked before all other objects and libraries.
# Object 'crtend.o' will be linked after all other objects and libraries.
SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS>
<LINK_FLAGS>
${ARCHDIR}/crtbegin.o
<OBJECTS> -o <TARGET> <LINK_LIBRARIES>
${ARCHDIR}/crtend.o")
This setting should be done in the toolchain file, which is passed to cmake with option -DCMAKE_TOOLCHAIN=<path/to/toolchain/file>.
With such toolchain, in the CMakeLists.txt you may simply write
ADD_EXECUTABLE(loader ${PLATFORM_SRCS} ${ISA_SRCS} ${GENERIC_SRCS})
Using CMAKE_C_LINK_EXECUTABLE variable you may also position options such as
-nostdlib -ffreestanding -nostdinc -T linker.ld -lgcc
which are very toolchain-related too.
See also this mailing: https://cmake.org/pipermail/cmake/2010-June/037641.html.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With