Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake : specify linux kernel module output build directory

Tags:

cmake

kbuild

Here is my cmake to build linux kernle hello world module.

if ( UNIX )
    # Version number
    set ( DRV_MAJOR 1 )
    set ( DRV_MINOR 0 )
    set ( DRV_PATCH 0 )

    set ( DRV_VERSION ${DRV_MAJOR}.${DRV_MINOR}.${DRV_PATCH} )

    configure_file( drv_config.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/drv_config.h )
    execute_process(COMMAND uname -r
                    OUTPUT_VARIABLE os_version
                    OUTPUT_STRIP_TRAILING_WHITESPACE)

    set(module_path /lib/modules/${os_version})
    set(module_build_path ${module_path}/build)

    add_custom_command(OUTPUT drv.ko
                       COMMAND ${CMAKE_MAKE_PROGRAM} -C ${module_build_path} M=${CMAKE_CURRENT_SOURCE_DIR}
                       DEPENDS driver.c Kbuild
                       COMMENT "Building drv.ko"
                      )

    add_custom_target(drv ALL DEPENDS drv.ko)

endif( UNIX )

And my Kbuild :

obj-m += drv.o
drv-objs := driver.o

How can I specify the output directory for all object files and related stuff? For the moment build stuff is generated at the source directory location. And I'd like not to mix source and obj files. Any ideas?

like image 300
Dmitry Avatar asked Jun 15 '18 14:06

Dmitry


1 Answers

This answer above helped me, figure it out. If someone is curious upon how.

Check out it out and gitlab: https://gitlab.com/christophacham/cmake-kernel-module

In the end the cmake file looks like the following:

cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)

project(driver VERSION 0.1.0 LANGUAGES C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

# Find kernel headers
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
find_package(KernelHeaders REQUIRED)
include_directories(${KERNELHEADERS_INCLUDE_DIRS})

set(DRIVER_FILE hello.ko)
set(KBUILD_CMD ${CMAKE_MAKE_PROGRAM} -C ${KERNELHEADERS_DIR} modules M=${CMAKE_CURRENT_BINARY_DIR} src=${CMAKE_CURRENT_SOURCE_DIR})

# Generate the Kbuild file through cmake.
FILE(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Kbuild "obj-m := hello.o")

add_custom_command(OUTPUT ${DRIVER_FILE}
        COMMAND ${KBUILD_CMD}
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
        DEPENDS hello.c VERBATIM)

add_custom_target(driver ALL DEPENDS ${DRIVER_FILE})

This together with the FindKernelHeaders.cmake allowed me to build the kernel module with cmake in a build folder. It was never meant to be shared, but was done anyway as there seems to be interest in this question.

like image 160
Christoph Acham Avatar answered Nov 15 '22 09:11

Christoph Acham