build system switch to cmake
Remove old build system at the same time Change-Id: Ifdffe1fcd4cfece05f036d8de6e7cb74aca65f62
This commit is contained in:
46
cmake/README.cross_compilation
Normal file
46
cmake/README.cross_compilation
Normal file
@ -0,0 +1,46 @@
|
||||
Cross compilation:
|
||||
------------------
|
||||
|
||||
The standard way of cross compiling with cmake is to give cmake a "toolchain
|
||||
file" that describes the compiler prefix and where it can find libraries for
|
||||
the target system, we provide an example in cmake/cross-aarch64.cmake.
|
||||
|
||||
This obviously requires installing a toolchain and a rootfs with target
|
||||
libraries to link against.
|
||||
|
||||
In addition, mckernel borrows the Kbuild system from linux kernel, which also
|
||||
makes the assumption that you can run generated executables (Kbuild uses various
|
||||
scripts around module building and does not make the distinction between build
|
||||
target and host target); you can get this working by setting up qemu-user on your
|
||||
machine which the kernel will transparently use through binfmt magic when trying
|
||||
to execute other arch binaries.
|
||||
|
||||
# yum install gcc-aarch64-linux-gnu qemu-user
|
||||
(dnf brings in --forcearch, we use this to setup the sysroot ; there are other
|
||||
ways of building one. It is available on el7 in extras.)
|
||||
# yum install dnf dnf-plugins-core
|
||||
(install these separately because most scripts cannot be run, and dependency hell means we need them first)
|
||||
# dnf download --releasever=7 --forcearch=aarch64 filesystem centos-release
|
||||
# rpm --root /usr/aarch64-linux-gnu/sys-root --ignorearch --nodeps -ivh filesystem-*.rpm
|
||||
# rpm --root /usr/aarch64-linux-gnu/sys-root --ignorearch --nodeps -ivh centos-release-*.rpm
|
||||
# rpm --root /usr/aarch64-linux-gnu/sys-root --import /usr/aarch64-linux-gnu/sys-root/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
|
||||
# rpm --root /usr/aarch64-linux-gnu/sys-root --import /usr/aarch64-linux-gnu/sys-root/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7-aarch64
|
||||
# dnf install --releasever=7 --forcearch=aarch64 --installroot=/usr/aarch64-linux-gnu/sys-root/ --setopt=tsflags=noscripts glibc-devel kernel-devel numactl-devel systemd-devel binutils-devel
|
||||
|
||||
(el7 lacks a binfmt for aarch64... fix this)
|
||||
# echo ':qemu-aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64:' > /etc/binfmt.d/qemu-aarch64-dynamic.conf
|
||||
# systemctl restart systemd-binfmt
|
||||
|
||||
(optional) test your setup
|
||||
# gcc -xc - <<<'#include <stdio.h>'$'\n''int main() { printf("ok\n"); return 0; }'
|
||||
# export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/sys-root
|
||||
# file a.out
|
||||
a.out: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.7.0, BuildID[sha1]=5ff445d3353cad2dae0a22550fe4cc572287dd90, not stripped
|
||||
# ./a.out
|
||||
ok
|
||||
|
||||
finally, build mckernel!
|
||||
# mkdir build; cd build
|
||||
# export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/sys-root
|
||||
# cmake -DCMAKE_INSTALL_PREFIX=/tmp/install-aarch64 -DCMAKE_TOOLCHAIN_FILE=../cmake/cross-aarch64.cmake -DUNAME_R=4.14.0-115.2.2.el7a.aarch64 -DKERNEL_DIR=/usr/aarch64-linux-gnu/sys-root/usr/src/kernels/4.14.0-115.2.2.el7a.aarch64/ -DBUILD_TARGET=smp-arm64 ..
|
||||
# make -j
|
||||
10
cmake/cross-aarch64.cmake
Normal file
10
cmake/cross-aarch64.cmake
Normal file
@ -0,0 +1,10 @@
|
||||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
|
||||
SET(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
|
||||
SET(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
|
||||
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu/sys-root)
|
||||
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
100
cmake/modules/Kbuild.cmake
Normal file
100
cmake/modules/Kbuild.cmake
Normal file
@ -0,0 +1,100 @@
|
||||
# Interface to kbuild
|
||||
#
|
||||
# Generate Kbuild file as appropriate and call make to the kernel build system
|
||||
# Original goal was to be simple, but correctness is difficult...
|
||||
|
||||
set(UNAME_R ${CMAKE_SYSTEM_VERSION} CACHE STRING "Kernel version to build against")
|
||||
set(KERNEL_DIR "/lib/modules/${UNAME_R}/build" CACHE STRING "kernel build directory")
|
||||
|
||||
set(KBUILD_C_FLAGS "" CACHE STRING "Compiler flags to give to Kbuild.")
|
||||
set(KBUILD_MAKE_FLAGS "" CACHE STRING "Extra make arguments for Kbuild.")
|
||||
|
||||
mark_as_advanced(
|
||||
KBUILD_C_FLAGS
|
||||
KBUILD_MAKE_FLAGS
|
||||
)
|
||||
|
||||
function(kmod MODULE_NAME)
|
||||
cmake_parse_arguments(KMOD "" "INSTALL_DEST" "C_FLAGS;SOURCES;EXTRA_SYMBOLS;DEPENDS" ${ARGN})
|
||||
|
||||
add_custom_target(${MODULE_NAME}_ko ALL
|
||||
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}.ko"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Module.symvers")
|
||||
|
||||
string(REGEX REPLACE "\\.c(;|$)" ".o\\1" KMOD_OBJECTS "${KMOD_SOURCES}")
|
||||
string(REPLACE ";" " " OBJECTS "${KMOD_OBJECTS}")
|
||||
string(REPLACE ";" " " C_FLAGS "${KMOD_C_FLAGS}")
|
||||
string(REPLACE ";" " " EXTRA_SYMBOLS "${KMOD_EXTRA_SYMBOLS}")
|
||||
if(ENABLE_WERROR)
|
||||
set(ccflags "${KBUILD_C_FLAGS} ${C_FLAGS} -Werror")
|
||||
else(ENABLE_WERROR)
|
||||
set(ccflags "${KBUILD_C_FLAGS} ${C_FLAGS}")
|
||||
endif(ENABLE_WERROR)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/cmake/modules/Kbuild.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Kbuild)
|
||||
|
||||
if (${CMAKE_GENERATOR} STREQUAL Ninja)
|
||||
set(MAKE "make")
|
||||
list(APPEND KBUILD_MAKE_FLAGS "-j")
|
||||
else ()
|
||||
set(MAKE "$(MAKE)")
|
||||
endif ()
|
||||
if (NOT "${ARCH}" STREQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
string(REGEX REPLACE "ld$" "" CROSS_COMPILE "${CMAKE_LINKER}")
|
||||
list(APPEND KBUILD_MAKE_FLAGS "ARCH=${ARCH};CROSS_COMPILE=${CROSS_COMPILE}")
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "\\.c(;|$)" ".o.cmd\\1" KMOD_O_CMD "${KMOD_SOURCES}")
|
||||
string(REGEX REPLACE "[^/;]+(;|$)" ".\\0" KMOD_O_CMD "${KMOD_O_CMD}")
|
||||
|
||||
|
||||
# This custom command has two uses:
|
||||
# - first is to list kbuild output files, so make clean does something
|
||||
# (cmake does not let us add a custom command to make clean)
|
||||
# - this alone could have been added to the other command, but cmake insists
|
||||
# on messing with timestamps with touch_nocreate after the command runs,
|
||||
# so it would incorrectly make intermediary outputs newer than the .ko
|
||||
# and force kbuild to relink needlessly
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
old_timestamp
|
||||
${KMOD_OBJECTS}
|
||||
${KMOD_O_CMD}
|
||||
"${MODULE_NAME}.o"
|
||||
".${MODULE_NAME}.o.cmd"
|
||||
"${MODULE_NAME}.mod.c"
|
||||
"${MODULE_NAME}.mod.o"
|
||||
".${MODULE_NAME}.mod.o.cmd"
|
||||
".${MODULE_NAME}.ko.cmd"
|
||||
".tmp_versions/${MODULE_NAME}.mod"
|
||||
".tmp_versions"
|
||||
"modules.order"
|
||||
COMMAND touch old_timestamp
|
||||
)
|
||||
|
||||
# This custom command forces cmake to rebuild the module, so kbuild's dependencies
|
||||
# (including header files modifications) kick in everytime.
|
||||
# Ideally, should later be replaced by something parsing the .xxx.cmd files to have
|
||||
# the native build system do these checks, if possible at all...
|
||||
add_custom_command(OUTPUT kmod_always_rebuild COMMAND touch kmod_always_rebuild)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MODULE_NAME}.ko"
|
||||
"Module.symvers"
|
||||
COMMAND ${MAKE} ${KBUILD_MAKE_FLAGS} -C ${KERNEL_DIR}
|
||||
M=${CMAKE_CURRENT_BINARY_DIR} modules
|
||||
COMMAND rm -f kmod_always_rebuild
|
||||
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Kbuild"
|
||||
${KMOD_DEPENDS}
|
||||
kmod_always_rebuild
|
||||
old_timestamp
|
||||
COMMENT "Building kmod ${MODULE_NAME}"
|
||||
)
|
||||
|
||||
if (KMOD_INSTALL_DEST)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}.ko"
|
||||
DESTINATION "${KMOD_INSTALL_DEST}")
|
||||
endif (KMOD_INSTALL_DEST)
|
||||
|
||||
message("Defined module ${MODULE_NAME}")
|
||||
endfunction(kmod)
|
||||
7
cmake/modules/Kbuild.in
Normal file
7
cmake/modules/Kbuild.in
Normal file
@ -0,0 +1,7 @@
|
||||
ccflags-y := @ccflags@
|
||||
src := @CMAKE_CURRENT_SOURCE_DIR@
|
||||
|
||||
KBUILD_EXTRA_SYMBOLS := @EXTRA_SYMBOLS@
|
||||
|
||||
obj-m := @MODULE_NAME@.o
|
||||
@MODULE_NAME@-y := @OBJECTS@
|
||||
43
cmake/modules/Ksym.cmake
Normal file
43
cmake/modules/Ksym.cmake
Normal file
@ -0,0 +1,43 @@
|
||||
# Lookup symbol addresses from Ksymbol file
|
||||
|
||||
set(SYSTEM_MAP "${KERNEL_DIR}/System.map" CACHE STRING "System map to look for symbols")
|
||||
set(VMLINUX "${KERNEL_DIR}/vmlinux" CACHE STRING "kernel object file")
|
||||
|
||||
|
||||
function(ksym SYMBOL)
|
||||
cmake_parse_arguments(KSYM "" "PREFIX;SOURCE_FILE;SUFFIX" "" ${ARGN})
|
||||
|
||||
execute_process(COMMAND awk "/ ${SYMBOL}$/ { print $1 }" ${SYSTEM_MAP}
|
||||
OUTPUT_VARIABLE ADDRESS_CANDIDATES OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if (NOT ADDRESS_CANDIDATES)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# listify and get first element
|
||||
string(REPLACE "\n" ";" ADDRESS_CANDIDATES "${ADDRESS_CANDIDATES}")
|
||||
list(GET ADDRESS_CANDIDATES 0 ADDRESS)
|
||||
|
||||
if (SOURCE_FILE)
|
||||
foreach(ADDRESS IN LISTS ADDRESS_CANDIDATES)
|
||||
execute_process(COMMAND addr2line -e ${VMLINUX} ${ADDRESS}
|
||||
OUTPUT_VARIABLE LINE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(LINE MATCHES ".*${SOURCE_FILE}:.*")
|
||||
set(FOUND ADDRESS)
|
||||
break()
|
||||
endif()
|
||||
endforeach(ADDRESS)
|
||||
if(NOT FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# ?! why only if source_file?...
|
||||
execute_process(COMMAND "awk '/ __ksymtab_${SYMBOL}$/ { print $1 }'"
|
||||
OUTPUT_VARIABLE SYMBOL_EXPORTED OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (SYMBOL_EXPORTED)
|
||||
set(ADDRESS 0)
|
||||
endif(SYMBOL_EXPORTED)
|
||||
endif(SOURCE_FILE)
|
||||
|
||||
set(${KSYM_PREFIX}KSYM_${SYMBOL}${KSYM_SUFFIX} "0x${ADDRESS}" CACHE INTERNAL "symbol")
|
||||
endfunction(ksym)
|
||||
Reference in New Issue
Block a user