vxkernel 0.6.0-26 : fonctional CMake build system! (candidate)

@add
> [vxdev] && [scripts]
  ¦ refacto the configuration script, now handle all compilation step
  ¦ proper cmake abstraction
  ¦ proper isolation between "core" and "command"

@update
> [CMakeLists.txt]
  ¦ support extra C flags configuration
  ¦ support installation request
  ¦ proper remove useless explicit path information
> [boards]
  ¦ [sdl2] move "toolchain" information in the vxsdk.toml (handled by vxSDK)
  ¦ [fxcg50] move "toolchain" information in the vxsdk.toml (handled by vxSDK)
> [vxsdk.toml]
  ¦ proper use of the new ENV configuration protocol
  ¦ isolate toolchain information of each board

@fix
> [.gitignore]
  ¦ use explicit exclusion instead of explicit inclusion
  ¦ add missing kernel source files (!)
This commit is contained in:
Yann MAGNIN 2022-12-03 16:50:02 +01:00
parent 693d9b0d8f
commit 20536b601b
17 changed files with 393 additions and 175 deletions

10
.gitignore vendored
View File

@ -1,7 +1,3 @@
*
!boards
!kernel
!scripts
!vxsdk.toml
!configure
!CMakeLists.txt
__pycache__
commit.txt
.vxsdk

View File

@ -5,19 +5,27 @@ cmake_minimum_required(VERSION 3.15)
# handle vxSDK-specific
#---
if(NOT DEFINED ENV{VXSDK_PKG_NAME} OR NOT DEFINED ENV{VXSDK_PKG_VERSION})
if(
NOT DEFINED ENV{VXSDK_PKG_NAME}
OR NOT DEFINED ENV{VXSDK_PKG_VERSION}
OR NOT DEFINED ENV{VXSDK_BUILD_CFLAGS}
OR NOT DEFINED ENV{VXSDK_PREFIX_BUILD}
OR NOT DEFINED ENV{VXSDK_PREFIX_INSTALL})
message(FATAL_ERROR "You should use the vxSDK to build this project")
endif()
set(VXSDK_PKG_NAME $ENV{VXSDK_PKG_NAME})
set(VXSDK_PKG_VERSION $ENV{VXSDK_PKG_VERSION})
set(VXSDK_PREFIX_BUILD $ENV{VXSDK_PREFIX_BUILD})
set(VXSDK_PREFIX_INSTALL $ENV{VXSDK_PREFIX_INSTALL})
set(VXSDK_BUILD_CFLAGS $ENV{VXSDK_BUILD_CFLAGS})
#---
# handle configuration-specific information
#---
set(VXKERNEL_CONF ${CMAKE_CURRENT_SOURCE_DIR}/.vxsdk/vxkernel_config.cmake)
set(VXKERNEL_CONF ${VXSDK_PREFIX_BUILD}/vxkernel_config.cmake)
if(NOT EXISTS ${VXKERNEL_CONF})
message(FATAL_ERROR "You should performs project configuration")
@ -48,22 +56,14 @@ set(VXKERNEL_INC_TARGETS "")
set(VXKERNEL_DIR_TARGETS "")
foreach(mod ${VXKERNEL_ENABLE_MODULES})
list(
APPEND
VXKERNEL_DIR_TARGETS
${CMAKE_CURRENT_SOURCE_DIR}/kernel/src/modules/${mod}
)
list(APPEND VXKERNEL_DIR_TARGETS kernel/src/modules/${mod})
endforeach()
foreach(drv ${VXKERNEL_ENABLE_DRIVERS})
list(
APPEND
VXKERNEL_DIR_TARGETS
${CMAKE_CURRENT_SOURCE_DIR}/kernel/src/drivers/${drv}
)
list(APPEND VXKERNEL_DIR_TARGETS kernel/src/drivers/${drv})
endforeach()
set(board_prefix ${CMAKE_CURRENT_SOURCE_DIR}/boards/${VXKERNEL_ENABLE_BOARD})
set(board_prefix boards/${VXKERNEL_ENABLE_BOARD})
if(EXISTS ${board_prefix}/src)
list(APPEND VXKERNEL_DIR_TARGETS ${board_prefix}/src)
endif()
@ -73,11 +73,10 @@ foreach(dir ${VXKERNEL_DIR_TARGETS})
list(APPEND VXKERNEL_SRC_TARGETS ${dir_src})
endforeach()
set(dir ${CMAKE_CURRENT_SOURCE_DIR}/kernel/src)
file(GLOB dir_src ${dir}/*.c ${dir}/*.S ${dir}/*.s)
file(GLOB dir_src kernel/src/*.c kernel/src/*.S kernel/src/*.s)
list(APPEND VXKERNEL_SRC_TARGETS ${dir_src})
list(APPEND VXKERNEL_INC_TARGETS ${CMAKE_CURRENT_SOURCE_DIR}/kernel/include)
list(APPEND VXKERNEL_INC_TARGETS kernel/include)
if(EXISTS ${board_prefix}/include)
list(APPEND VXKERNEL_INC_TARGETS ${board_prefix}/include)
endif()
@ -97,5 +96,13 @@ endif()
#---
include_directories(${VXKERNEL_INC_TARGETS})
add_compile_options(-Wall -Wextra ${VXKERNEL_EXTRA_CFLAGS})
add_compile_options(-Wall -Wextra ${VXSDK_BUILD_CFLAGS})
add_library(vxkernel ${VXKERNEL_SRC_TARGETS})
#---
# Install-specific declaration
#---
set(CMAKE_INSTALL_PREFIX ${VXSDK_PREFIX_INSTALL})
install(TARGETS vxkernel DESTINATION "lib")
install(DIRECTORY kernel/include/ DESTINATION "include")

View File

@ -17,22 +17,3 @@ drivers = [
'screen:R61524',
'mpu:sh:sh7305'
]
[toolchain]
file = 'toolchain-sh.cmake'
cflags = [
'-DFXCG50',
'-m4-nofpu',
'-mb',
'-ffreestanding',
'-nostdlib',
'-fPIE',
'-O1',
'-fstrict-volatile-bitfields',
'-Wa,--dsp'
]
libs = [
'-lc',
'-lgcc'
]

View File

@ -14,9 +14,3 @@ modules = [
drivers = [
'mpu:common:sdl2'
]
[toolchain]
cflags = [
'-D__VXKERNEL_SUPPORT_SDL2__',
'-g3'
]

30
kernel/src/kernel.c Normal file
View File

@ -0,0 +1,30 @@
#include <vhex/kernel.h>
#include <vhex/module.h>
//---
// Initialization and unloading
//---
/* kinit(): Install and start vhex */
void kinit(void)
{
struct vhex_module *mtable;
mtable = vhex_module_table();
for (int i = 0; i < vhex_module_count(); ++i) {
if (mtable[i].init != NULL)
mtable[i].init();
}
}
/* kquit(): Quit vhex and give back control to the system */
void kquit(void)
{
struct vhex_module *mtable;
mtable = vhex_module_table();
for (int i = 0; i < vhex_module_count(); ++i) {
if (mtable[i].quit != NULL)
mtable[i].quit();
}
}

View File

@ -1,56 +1,34 @@
"""
Expose configure script part
"""
from scripts.board import board_select, board_command
from scripts.format import format_select, format_command
from scripts.confile import config_file_generate
from scripts.configure import configure_entry
from scripts.build import build_entry
from scripts.install import install_entry
from scripts.uninstall import uninstall_entry
__all__ = [
'select',
'subcommand',
'generate_confile'
'configure',
'build',
'install',
'uninstall',
]
#---
# Public
#---
def select(target, kernconf, arg):
""" perform target selection
def configure(argv):
""" invoke configuration script """
return configure_entry(argv)
@args
> target (str) - subcommand target (assumed valid)
> kernconf (dict) - kernel configuration information
> arg (str) - argument for the selection
def build(argv):
""" invoke build script """
return build_entry(argv)
@return
> Nothing, hangout if error. (return are only here for syntax sugar)
"""
if target == 'board':
return board_select(kernconf, arg)
return format_select(kernconf, arg)
def install(argv):
""" invoke install script """
return install_entry(argv)
def subcommand(target, argv):
""" hand-off kernel configuration for a particular subcommand
@arg
> target (str) - subcommand target (assumed valid)
> argv (list,str) - subcommand arguments
@return
> Never (return are only here for syntax sugar)
"""
if target == 'board':
return board_command(argv)
return format_command(argv)
def generate_confile(kernconf):
""" Generate the configuration file
@args
> kernconf (dict) - kernel configuration
@return
> 0 if success, negative value otherwise
"""
return config_file_generate(kernconf)
def uninstall(argv):
""" invoke uninstall script """
return uninstall_entry(argv)

47
scripts/build.py Normal file
View File

@ -0,0 +1,47 @@
"""
Vhex kernel build script
"""
import os
import sys
from scripts.core.cmake import cmake_build
__all__ = [
'build_entry'
]
__HELP__ = """ usage: vxdev build [OPTIONS] ...
Build script for the Vhex kernel
Options:
-h, --help display this message
-v, --verbose display more information during the building process
"""
#---
# Public
#---
def build_entry(argv):
""" Build entry """
if '-h' in argv or '--help' in argv:
print(__HELP__)
sys.exit(0)
enable_verbose = False
for arg in argv:
if arg in ['-v', '--verbose']:
enable_verbose = True
continue
print(f"unrecognized argument '{arg}'", file=sys.stderr)
sys.exit(84)
if 'VXSDK_PREFIX_BUILD' not in os.environ:
print(
"unable to generate the configuration file, you should use the "
"vxSDK",
file=sys.stderr
)
sys.exit(84)
return cmake_build(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)

52
configure → scripts/configure.py Executable file → Normal file
View File

@ -1,13 +1,19 @@
#! /usr/bin/env python3
"""
Vhex kernel configuration script
"""
import os
import sys
import scripts
from scripts.core.board import board_command, board_select
from scripts.core.format import format_command, format_select
from scripts.core.config_file import config_file_generate
from scripts.core.cmake import cmake_configure
__HELP__ = """ usage: configure [OTPIONS ...] [ACTIONS ...]
__all__ = [
'configure_entry'
]
__HELP__ = """ usage: vxdev configure [OTPIONS ...] [ACTIONS ...]
Configuration script for the Vhex unikernel.
@ -23,7 +29,6 @@ Actions:
Options:
-h,--help display this message
--verbose display more information during the compilation step
--board=<board> select the board to target
--format=<target>
select the format of the library generation. You can use two format:
@ -35,7 +40,7 @@ Options:
# Public
#---
def main(argv):
def configure_entry(argv):
""" main entry of the script """
# early check
if '-h' in argv or '--help' in argv:
@ -49,7 +54,7 @@ def main(argv):
# default behaviour
if not argv:
print(__HELP__)
sys.exit(0)
sys.exit(84)
# configure default value
kernconf = {
@ -59,21 +64,32 @@ def main(argv):
'VXKERNEL_TARGET_FORMAT' : 'vdso',
}
# check subcommand
if argv[0] == 'board':
sys.exit(board_command(argv[1:]))
if argv[0] == 'format':
sys.exit(format_command(argv[1:]))
# check user arguments
for i, arg in enumerate(argv):
if arg == '--verbose':
kernconf['VXKERNEL_ENABLE_VERBOSE'] = True
elif arg.find('--board=') == 0:
scripts.select('board', kernconf, arg[8:])
for arg in argv:
if arg.find('--board=') == 0:
board_select(kernconf, arg[8:])
elif arg.find('--format=') == 0:
scripts.select('format', kernconf, arg[9:])
elif arg in ['board', 'format']:
scripts.subcommand(arg, argv[i+1:])
format_select(kernconf, arg[9:])
else:
print(f"argument '{arg}' not recognized", file=sys.stderr)
sys.exit(84)
# generate the configuration file
return scripts.generate_confile(kernconf)
main(sys.argv[1:])
# check vxSDK validity
try:
prefix_src = os.environ['VXSDK_CURRENT_SOURCE_DIR']
prefix_build = os.environ['VXSDK_PREFIX_BUILD']
if config_file_generate(kernconf, prefix_build) == 0:
sys.exit(cmake_configure(prefix_build, prefix_src))
except KeyError:
print(
"unable to generate the configuration file, you should use the "
"vxSDK",
file=sys.stderr
)
sys.exit(84)

0
scripts/core/__init__.py Normal file
View File

View File

@ -14,6 +14,8 @@ __all__ = [
# Internal functions
#---
__PROJ_PREFIX__ = f"{os.path.dirname(__file__)}/../.."
def _warning(text):
print(text, file=sys.stderr)
@ -61,13 +63,13 @@ def _board_fetch_info_config(board_info, board_desc, board):
if 'drivers' not in board_desc['config']:
_warning(f"board '{board}' : missing drivers declaration")
return -3
mod_prefix = f"{os.path.dirname(__file__)}/../kernel/src/modules"
mod_prefix = f"{__PROJ_PREFIX__}/kernel/src/modules"
for mod in board_desc['config']['modules']:
if not os.path.exists(f"{mod_prefix}/{mod}"):
_warning(f"{board} : module '{mod}' does not exists, skipped")
continue
board_info['config']['modules'].append(mod)
drv_prefix = f"{os.path.dirname(__file__)}/../kernel/src/drivers"
drv_prefix = f"{__PROJ_PREFIX__}/kernel/src/drivers"
for drv in board_desc['config']['drivers']:
drv_path = drv.replace(':', '/')
if not os.path.exists(f"{drv_prefix}/{drv_path}"):
@ -76,29 +78,6 @@ def _board_fetch_info_config(board_info, board_desc, board):
board_info['config']['drivers'].append(drv_path)
return 0
def _board_fetch_info_toolchain(board_info, board_desc, _):
""" Fetch and check board configuration information
@args
> board_info (dict) - board information
> board_desc (dict) - board TOML parsed file
> board (str) - board name
@return
> 0 if success, negative value otherwise
"""
if 'toolchain' not in board_desc:
return 0
if 'file' in board_desc['toolchain']:
board_info['toolchain']['file'] = board_desc['toolchain']['file']
if 'cflags' in board_desc['toolchain']:
board_info['toolchain']['cflags'] = board_desc['toolchain']['cflags']
if 'ldflags' in board_desc['toolchain']:
board_info['toolchain']['ldflags'] = board_desc['toolchain']['ldflags']
if 'libs' in board_desc['toolchain']:
board_info['toolchain']['libs'] = board_desc['toolchain']['libs']
return 0
def _board_fetch_info(board):
""" Generate all information about a particular board
@ -120,7 +99,7 @@ def _board_fetch_info(board):
"""
board_info = {
'name' : board,
'path' : f"{os.path.dirname(__file__)}/../boards/{board}",
'path' : f"{__PROJ_PREFIX__}/boards/{board}",
'author' : 'unknown',
'desc' : 'unknown',
'config' : {
@ -156,10 +135,6 @@ def _board_fetch_info(board):
if _board_fetch_info_config(board_info, board_desc, board) != 0:
return {}
# check toolchain extra configuration if available
if _board_fetch_info_toolchain(board_info, board_desc, board) != 0:
return {}
# return the board information
return board_info
@ -170,7 +145,7 @@ def _board_fetch_available_board():
> a list of all available board name
"""
# fetch folder information
board_prefix = f"{os.path.dirname(__file__)}/../boards"
board_prefix = f"{__PROJ_PREFIX__}/boards"
if not (available_list := list(os.walk(board_prefix))):
return []
# fetch folder content only
@ -189,13 +164,9 @@ def _board_generate_conf(kernconf, board_info):
@return
> nothing
"""
kernconf['VXKERNEL_ENABLE_BOARD'] = board_info['name']
kernconf['VXKERNEL_ENABLE_BOARD'] = board_info['name']
kernconf['VXKERNEL_ENABLE_MODULES'] = board_info['config']['modules']
kernconf['VXKERNEL_ENABLE_DRIVERS'] = board_info['config']['drivers']
kernconf['VXKERNEL_TOOLCHAIN_FILE'] = board_info['toolchain']['file']
kernconf['VXKERNEL_EXTRA_CFLAGS'] = board_info['toolchain']['cflags']
kernconf['VXKERNEL_EXTRA_LDFLAGS'] = board_info['toolchain']['ldflags']
kernconf['VXKERNEL_EXTRA_LIBS'] = board_info['toolchain']['libs']
def _board_display_list(verbose, board_target):
""" Display board information

62
scripts/core/cmake.py Normal file
View File

@ -0,0 +1,62 @@
"""
CMake abstraction
"""
import os
import sys
import subprocess
__all__ = [
'cmake_configure',
'cmake_build',
'cmake_install',
'cmake_uninstall',
]
#---
# Pulbic
#---
def cmake_configure(prefix_build, prefix_src):
""" Abstract cmake configuration """
shell_cmd = f"cmake -B {prefix_build} -S {prefix_src}"
return subprocess.run(shell_cmd.split(), check=False).returncode
def cmake_build(prefix_build, verbose):
""" Abstract cmake configuration """
shell_cmd = f"cmake --build {prefix_build}"
if verbose:
shell_cmd += ' --verbose'
return subprocess.run(shell_cmd.split(), check=False).returncode
def cmake_install(prefix_build, verbose):
""" Abstract cmake installation """
shell_cmd = f"cmake --install {prefix_build}"
if verbose:
shell_cmd += ' --verbose'
return subprocess.run(shell_cmd.split(), check=False).returncode
def cmake_uninstall(prefix_build, verbose):
""" Abstract cmake uninstall
Note that CMake does not offert a easy way to uninstall project, but it
generate a file which contains all installed pathname
"""
manifile = f"{prefix_build}/install_manifest.txt"
if not os.path.exists(manifile):
print('project not installed')
return -1
retcode = 0
with open(manifile, 'r', encoding='utf8') as manifest:
for pathname in manifest.readlines():
pathname = pathname.strip()
if not os.path.exists(pathname):
continue
if verbose:
print("-- Removing {pathname}")
ret = subprocess.run(f"rm {pathname}".split(), check=False)
if ret.returncode == 0:
continue
print("warning : error during removing file", file=sys.stderr)
retcode -= 1
return retcode

View File

@ -2,7 +2,6 @@
Configuration file handling
"""
import os
import sys
__all__ = [
'config_file_generate'
@ -12,24 +11,16 @@ __all__ = [
# Public
#---
def config_file_generate(kernconf):
def config_file_generate(kernconf, confile_prefix):
""" Generate the kernel configuration file for CMake build system
@args
> kernconf (dict) - kernel configuration information
> kernconf (dict) - kernel configuration information
> confile_prefix (str) - build prefix
@return
> 0 on success, negative value otherwise
"""
if 'VXSDK_PREFIX_BUILD' not in os.environ:
print(
"unable to generate the configuration file, you should use the "
"vxSDK",
file=sys.stderr
)
sys.exit(84)
confile_prefix = os.environ['VXSDK_PREFIX_BUILD']
if not os.path.exists(confile_prefix):
os.makedirs(confile_prefix)
@ -42,7 +33,6 @@ def config_file_generate(kernconf):
content += f"set({item[0]} {data})\n"
confile_path = f"{confile_prefix}/vxkernel_config.cmake"
with open(confile_path, "w+", encoding='utf8') as file:
with open(confile_path, 'w+', encoding='utf8') as file:
file.write(content)
return 0

50
scripts/install.py Normal file
View File

@ -0,0 +1,50 @@
"""
Vhex kernel install script
"""
import os
import sys
from scripts.core.cmake import cmake_install
__all__ = [
'install_entry'
]
__HELP__ = """ usage: vxdev install [OPTIONS] ...
Install script for the Vhex kernel
Options:
-h, --help display this message
-v, --verbose display more information during the building process
"""
#---
# Public
#---
def install_entry(argv):
""" Install entry """
if '-h' in argv or '--help' in argv:
print(__HELP__)
sys.exit(0)
enable_verbose = False
for arg in argv:
if arg in ['-v', '--verbose']:
enable_verbose = True
continue
print(f"unrecognized argument '{arg}'", file=sys.stderr)
sys.exit(84)
try:
_ = os.environ['VXSDK_PREFIX_BUILD']
__ = os.environ['VXSDK_PREFIX_INSTALL']
except KeyError:
print(
"unable to generate the configuration file, you should use the "
"vxSDK",
file=sys.stderr
)
sys.exit(84)
return cmake_install(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)

50
scripts/uninstall.py Normal file
View File

@ -0,0 +1,50 @@
"""
Vhex kernel uninstall script
"""
import os
import sys
from scripts.core.cmake import cmake_uninstall
__all__ = [
'uninstall_entry'
]
__HELP__ = """ usage: vxdev uninstall [OPTIONS] ...
uninstall script for the Vhex kernel
Options:
-h, --help display this message
-v, --verbose display more information during the building process
"""
#---
# Public
#---
def uninstall_entry(argv):
""" uninstall entry """
if '-h' in argv or '--help' in argv:
print(__HELP__)
sys.exit(0)
enable_verbose = False
for arg in argv:
if arg in ['-v', '--verbose']:
enable_verbose = True
continue
print(f"unrecognized argument '{arg}'", file=sys.stderr)
sys.exit(84)
try:
_ = os.environ['VXSDK_PREFIX_BUILD']
__ = os.environ['VXSDK_PREFIX_INSTALL']
except KeyError:
print(
"unable to generate the configuration file, you should use the "
"vxSDK",
file=sys.stderr
)
sys.exit(84)
return cmake_uninstall(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)

46
vxdev Executable file
View File

@ -0,0 +1,46 @@
#! /usr/bin/env python3
"""
Vhex kernel developement script
"""
import sys
import scripts
__HELP__ = """ usage: vxdev [ACTION] ...
Actions:
configure perform configuration step
build perfrom build step
install perform installation step
uninstall perform uninstallation step
Options:
-h,--help display this message
You can try `vxdev <action> --help` for more information about each action
"""
#---
# Public
#---
def _main(argv):
""" main entry of the script """
if '-h' in argv or '--help' in argv:
print(__HELP__)
sys.exit(0)
if not argv:
print(__HELP__)
sys.exit(84)
if argv[0] == 'configure':
sys.exit(scripts.configure(argv[1:]))
if argv[0] == 'build':
sys.exit(scripts.build(argv[1:]))
if argv[0] == 'install':
sys.exit(scripts.install(argv[1:]))
if argv[0] == 'uninstall':
sys.exit(scripts.uninstall(argv[1:]))
print(f"unrecognized argument '{argv[0]}'", file=sys.stderr)
sys.exit(84)
sys.exit(_main(sys.argv[1:]))

View File

@ -5,27 +5,20 @@ target = [
'fxcg50',
'sdl2'
]
option = [
'release',
'debug'
]
[build]
configure = './configure'
build = 'make'
install = 'make install'
uninstall = 'make uninstall'
configure = './vxdev configure'
build = './vxdev build --verbose'
install = './vxdev install'
uninstall = './vxdev uninstall'
[fxcg50]
[dependencies]
[fxcg50.dependencies]
sh-elf-vhex = 'master@superh'
[config]
VXSDK_BUILD_GCC_PREFIX = 'sh-elf-vhex-'
VXSDK_BUILD_CFLAGS = [
'-DFXCG50',
'-m4-nofpu',
'-mb',
[fxcg50.env]
VXSDK_COMMON_BUILD_CFLAGS = [
'-D__SUPPORT_FXCG50__',
'-ffreestanding',
'-nostdlib',
'-fPIE',
@ -33,7 +26,14 @@ uninstall = 'make uninstall'
'-fstrict-volatile-bitfields',
'-Wa,--dsp'
]
VXSDK_BUILD_LIBS = [
VXSDK_PUBLIC_BUILD_LIBS = [
'-lc',
'-lgcc'
]
[sdl2]
[sdl2.env]
VXSDK_COMMON_BUILD_CFLAGS = [
'-D__VXKERNEL_SUPPORT_SDL2__',
'-g3'
]