-
Notifications
You must be signed in to change notification settings - Fork 1
/
CMakeLists.txt
151 lines (129 loc) · 5.9 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
cmake_minimum_required(VERSION 3.20)
# Suppress compiler checks.
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_SYSTEM_NAME Generic CACHE STRING "" FORCE)
# Project details.
project(thornhill)
# Set build system configuration.
set(CMAKE_GENERATOR "Unix Makefiles")
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
# Set project configuration.
set(TH_ARCH "x86_64")
set(CMAKE_BUILD_TYPE Debug)
# Set global build system filenames and locations.
get_filename_component(TH_BUILD_SCRIPTS_DIRECTORY "./scripts" ABSOLUTE)
get_filename_component(TH_OUTPUT_DIRECTORY "./out" ABSOLUTE)
get_filename_component(TH_TOOLCHAIN_DIRECTORY "./toolchain" ABSOLUTE)
# Set global build system properties.
set(TH_OUTPUT_IMG "thornhill.img")
# Check if the ./toolchain directory has been built.
# If all cross-compilers and tools were found, use them.
message("Looking for toolchain in ${TH_TOOLCHAIN_DIRECTORY}")
if(EXISTS "${TH_TOOLCHAIN_DIRECTORY}" AND EXISTS "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin")
# Attempt to use the toolchain prefix.
message("Found built toolchain in ${TH_TOOLCHAIN_DIRECTORY}. Using cross-compilers.")
set(CMAKE_ASM_LINK_EXECUTABLE "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin/x86_64-elf-as")
set(CMAKE_C_COMPILER "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin/x86_64-elf-gcc")
set(CMAKE_CXX_COMPILER "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin/x86_64-elf-g++")
set(CMAKE_C_LINK_EXECUTABLE_NAME "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin/x86_64-elf-ld")
set(CMAKE_CXX_LINK_EXECUTABLE_NAME "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin/x86_64-elf-g++")
set(OBJCOPY "${TH_TOOLCHAIN_DIRECTORY}/prefix/bin/x86_64-elf-objcopy")
# Using cross-compiler, so only use host system paths and not sysroot.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
else()
# Otherwise, try to find cross-compilers installed elsewhere on the system.
message("Did not locate a built toolchain in ${TH_TOOLCHAIN_DIRECTORY}. Checking elsewhere on system...")
# Look for cross-compiler binutils elsewhere on the system (both as and ld).
find_program(CROSS_ASM x86_64-elf-as)
find_program(CROSS_LDD x86_64-elf-ld)
# Look for cross-compiler GCC elsewhere on the system.
find_program(CROSS_GCC x86_64-elf-gcc)
if (CROSS_ASM AND CROSS_GCC AND CROSS_LDD)
message("Valid cross-compiler environment detected on system. Using cross-compilers.")
set(CMAKE_ASM_LINK_EXECUTABLE x86_64-elf-as)
set(CMAKE_C_COMPILER x86_64-elf-gcc)
set(CMAKE_CXX_COMPILER x86_64-elf-g++)
set(CMAKE_C_LINK_EXECUTABLE_NAME x86_64-elf-ld)
set(CMAKE_CXX_LINK_EXECUTABLE_NAME x86_64-elf-g++)
# Using cross-compiler, so only use host system paths and not sysroot.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
else()
message(FATAL_ERROR
"Missing cross-compiler.\n"
"You need freestanding versions of x86_64-elf-binutils and x86_64-elf-gcc.\n"
"Please refer to the wiki for more information.")
endif()
endif()
# Check dependencies and prerequisites.
if (NOT EXISTS /usr/include/efi AND NOT EXISTS /usr/local/include/efi)
message(FATAL_ERROR
"You must install gnu-efi. \
On macOS, this can be done by following the guide in the wiki.
On Debian/Ubuntu, this can be done with `sudo apt install gnu-efi`."
)
else()
if (EXISTS /usr/include/efi)
set(EFI_INCLUDE_ROOT /usr/include/efi)
set(EFI_INCLUDE_LIB /usr/lib)
elseif(EXISTS /usr/local/include/efi)
set(EFI_INCLUDE_ROOT /usr/local/include/efi)
set(EFI_INCLUDE_LIB /usr/local/lib)
endif()
endif()
find_program(OBJCOPY NAMES "objcopy" "x86_64-elf-objcopy")
if (NOT OBJCOPY)
message(FATAL_ERROR "Failed to find objcopy. If you're on Debian/Ubuntu, you might need to install binutils which"
" can be done with `sudo apt install binutils` or `sudo apt install binutils-common` depending on your"
" system version. On macOS, this can be done with `brew install x86_64-elf-binutils`.")
endif()
find_program(MKFSFAT NAMES "mkfs.fat")
if (NOT MKFSFAT)
message(FATAL_ERROR
"You must install dosfstools. \
On macOS, this can be done with `brew install dosfstools`. \
On Debian/Ubuntu, this can be done with `sudo apt install dosfstools`."
)
endif()
find_program(MTOOLS NAMES "mtools")
if (NOT MTOOLS)
message(FATAL_ERROR
"You must install mtools. \
On macOS, this can be done with `brew install mtools`. \
On Debian/Ubuntu, this can be done with `sudo apt install mtools`."
)
endif()
# Ensure output directory is ready.
execute_process(COMMAND "${CMAKE_COMMAND} -E make_directory ${TH_OUTPUT_DIRECTORY}")
# Run the version script.
add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/config/version.h
${CMAKE_CURRENT_SOURCE_DIR}/config/_version.h
COMMAND ${CMAKE_COMMAND} -DTH_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/version.cmake
)
add_custom_target(version ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/config/version.h)
# Include components.
add_subdirectory(boot)
add_subdirectory(kernel)
# Add `emulator` and `run` pseudo-targets
add_custom_target(emulator)
add_dependencies(emulator thornhill)
add_custom_command(TARGET emulator
COMMENT "Starting QEMU..."
COMMAND ${TH_BUILD_SCRIPTS_DIRECTORY}/startemulator.sh "${TH_OUTPUT_DIRECTORY}/thornhill.img"
)
add_custom_target(emulator_only)
add_custom_command(TARGET emulator_only
COMMENT "Starting QEMU (using previous build)..."
COMMAND ${TH_BUILD_SCRIPTS_DIRECTORY}/startemulator.sh "${TH_OUTPUT_DIRECTORY}/thornhill.img"
)
add_custom_target(hot)
add_custom_command(TARGET hot
COMMENT "Starting hot-reload toolchain..."
COMMAND ${TH_BUILD_SCRIPTS_DIRECTORY}/starthotreload.sh
)