|
| 1 | +# Find Rust toolchain |
| 2 | +find_program(CARGO_COMMAND cargo REQUIRED) |
| 3 | +find_program(RUSTC_COMMAND rustc REQUIRED) |
| 4 | + |
| 5 | +# Rust target specification - use built-in x86_64-unknown-none |
| 6 | +set(RUST_TARGET "x86_64-unknown-none") |
| 7 | +set(RUST_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/target") |
| 8 | + |
| 9 | +# Rust flags to match kernel compilation requirements |
| 10 | +set(RUST_FLAGS "-C code-model=kernel -C relocation-model=static") |
| 11 | + |
| 12 | +# Build profile selection based on CMAKE_BUILD_TYPE |
| 13 | +if(CMAKE_BUILD_TYPE STREQUAL "Release") |
| 14 | + set(RUST_BUILD_PROFILE "release") |
| 15 | + set(RUST_PROFILE_FLAG "--release") |
| 16 | +else() |
| 17 | + set(RUST_BUILD_PROFILE "debug") |
| 18 | + set(RUST_PROFILE_FLAG "") |
| 19 | +endif() |
| 20 | + |
| 21 | +# List of Rust modules to build |
| 22 | +list(APPEND rust_modules_list |
| 23 | + hello_rust_mod |
| 24 | +) |
| 25 | + |
| 26 | +foreach(rust_module ${rust_modules_list}) |
| 27 | + set(module_dir "${CMAKE_CURRENT_SOURCE_DIR}/${rust_module}") |
| 28 | + set(module_lib "${RUST_TARGET_DIR}/${RUST_TARGET}/${RUST_BUILD_PROFILE}/lib${rust_module}.a") |
| 29 | + set(module_ko "${CMAKE_CURRENT_BINARY_DIR}/${rust_module}.ko") |
| 30 | + set(temp_dir "${CMAKE_CURRENT_BINARY_DIR}/temp_${rust_module}") |
| 31 | + |
| 32 | + # Build Rust static library with cargo |
| 33 | + add_custom_command( |
| 34 | + OUTPUT ${module_lib} |
| 35 | + COMMAND ${CMAKE_COMMAND} -E env RUSTFLAGS=${RUST_FLAGS} |
| 36 | + ${CARGO_COMMAND} build |
| 37 | + --target ${RUST_TARGET} |
| 38 | + --target-dir ${RUST_TARGET_DIR} |
| 39 | + ${RUST_PROFILE_FLAG} |
| 40 | + --manifest-path ${module_dir}/Cargo.toml |
| 41 | + DEPENDS |
| 42 | + ${module_dir}/Cargo.toml |
| 43 | + ${module_dir}/src/lib.rs |
| 44 | + WORKING_DIRECTORY ${module_dir} |
| 45 | + COMMENT "Building Rust module: ${rust_module}" |
| 46 | + VERBATIM |
| 47 | + ) |
| 48 | + |
| 49 | + # Convert static library to relocatable object (.ko) |
| 50 | + # Extract object files from the archive and combine them |
| 51 | + add_custom_command( |
| 52 | + OUTPUT ${module_ko} |
| 53 | + COMMAND ${CMAKE_COMMAND} -E make_directory ${temp_dir} |
| 54 | + COMMAND cd ${temp_dir} && ar x ${module_lib} |
| 55 | + COMMAND sh -c "ld.lld -r -o ${module_ko} ${temp_dir}/*.o" |
| 56 | + COMMAND ${CMAKE_COMMAND} -E rm -rf ${temp_dir} |
| 57 | + DEPENDS ${module_lib} |
| 58 | + COMMENT "Creating kernel module: ${rust_module}.ko" |
| 59 | + ) |
| 60 | + |
| 61 | + add_custom_target(${rust_module}_rust_ko ALL DEPENDS ${module_ko}) |
| 62 | + list(APPEND rust_module_ko_files ${module_ko}) |
| 63 | + |
| 64 | + # Install .ko file to lib directory (same as C modules) |
| 65 | + install(FILES ${module_ko} DESTINATION lib COMPONENT initrd) |
| 66 | +endforeach() |
| 67 | + |
| 68 | +add_custom_target(rust_kernel_modules DEPENDS ${rust_module_ko_files}) |
0 commit comments