From 86555126d855df005bb1777c1c4ab7127c677b6c Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 30 Dec 2025 19:08:56 +0100 Subject: feat: SMP support tweaks, add MACROS_MAP.md Signed-off-by: Amlal El Mahrouss --- src/kernel/KernelKit/HardwareThreadScheduler.h | 15 ++++- src/kernel/KernelKit/UserProcessScheduler.h | 4 +- src/kernel/MACROS_MAP.md | 5 ++ src/kernel/amd64-desktop.make | 4 +- src/kernel/arm64-desktop.make | 2 +- src/kernel/src/UserProcessScheduler.cc | 10 +-- tools/kconf.py | 11 ++++ tools/kfwrk.py | 90 ++++++++++++++++++++++++++ tools/kimg.py | 38 +++++++++++ tools/kman.py | 40 ++++++++++++ tools/mk_app.py | 78 ---------------------- tools/mk_fwrk.py | 90 -------------------------- tools/mk_htman.py | 40 ------------ tools/mk_img.py | 38 ----------- tools/mkapp.py | 78 ++++++++++++++++++++++ 15 files changed, 284 insertions(+), 259 deletions(-) create mode 100644 src/kernel/MACROS_MAP.md create mode 100755 tools/kconf.py create mode 100755 tools/kfwrk.py create mode 100755 tools/kimg.py create mode 100755 tools/kman.py delete mode 100755 tools/mk_app.py delete mode 100755 tools/mk_fwrk.py delete mode 100755 tools/mk_htman.py delete mode 100755 tools/mk_img.py create mode 100755 tools/mkapp.py diff --git a/src/kernel/KernelKit/HardwareThreadScheduler.h b/src/kernel/KernelKit/HardwareThreadScheduler.h index b7aa63e5..bc5bea81 100644 --- a/src/kernel/KernelKit/HardwareThreadScheduler.h +++ b/src/kernel/KernelKit/HardwareThreadScheduler.h @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0 (see LICENSE file) // Official repository: https://github.com/nekernel-org/nekernel -#ifndef __INC_MP_MANAGER_H__ -#define __INC_MP_MANAGER_H__ +#ifndef KERNEL_HARDWARETHREADSCHEDULER_H +#define KERNELKIT_HARDWARETHREADSCHEDULER_H #include #include @@ -12,9 +12,17 @@ /// @note Last Rev Sun 28 Jul CET 2024 /// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM -#define kMaxAPInsideSched (4U) +#if defined(__nekernel_max_cores) +/// \note This can be edited at compile-time to specify how many cores can be used by NeKernel. +#define kMaxAPInsideSched (__nekernel_max_cores) +#endif + +#if defined(__nekernel_boot_core_index) +#define kBootAPIndex (__nekernel_boot_core_index) +#endif namespace Kernel { + enum struct ThreadKind { kAPInvalid = 0, kAPSystemReserved = 100, // System reserved thread, well user can't use it @@ -123,6 +131,7 @@ Void mp_wakeup_thread(HAL::StackFramePtr stack); /// @brief makes thread sleep. /// hooks and hangs thread to prevent code from executing. Void mp_hang_thread(HAL::StackFramePtr stack); + } // namespace Kernel #endif // !__INC_MP_MANAGER_H__ diff --git a/src/kernel/KernelKit/UserProcessScheduler.h b/src/kernel/KernelKit/UserProcessScheduler.h index e4d86a19..126be648 100644 --- a/src/kernel/KernelKit/UserProcessScheduler.h +++ b/src/kernel/KernelKit/UserProcessScheduler.h @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0 (see LICENSE file) // Official repository: https://github.com/nekernel-org/nekernel -#ifndef __KERNEL_KIT_USER_PROCESS_SCHEDULER_H__ -#define __KERNEL_KIT_USER_PROCESS_SCHEDULER_H__ +#ifndef KERNELKIT_USERPROCESSSCHEDULER_H +#define KERNELKIT_USERPROCESSSCHEDULER_H /// @file UserProcessScheduler.h /// @brief User Process Scheduler backend file. diff --git a/src/kernel/MACROS_MAP.md b/src/kernel/MACROS_MAP.md new file mode 100644 index 00000000..77118a44 --- /dev/null +++ b/src/kernel/MACROS_MAP.md @@ -0,0 +1,5 @@ +# __nekernel: Configuration Macros of NeKernel. + +- `__nekernel_max_cores` -> Max SMP cores usable by NeKernel's scheduler. + + diff --git a/src/kernel/amd64-desktop.make b/src/kernel/amd64-desktop.make index 081bf75b..88652718 100644 --- a/src/kernel/amd64-desktop.make +++ b/src/kernel/amd64-desktop.make @@ -1,11 +1,11 @@ -################################################## +################################################# # (c) Amlal El Mahrouss, licensed under the Apache 2.0 license. # This is the NeKernel's makefile. ################################################## CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_OPENHEFS__ -D__FSKIT_INCLUDES_EXT2__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__NEKERNEL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot +CCFLAGS = -fshort-wchar -D__nekernel_max_cores=8 -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_OPENHEFS__ -D__FSKIT_INCLUDES_EXT2__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__NEKERNEL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm diff --git a/src/kernel/arm64-desktop.make b/src/kernel/arm64-desktop.make index f5228d6b..d24203c1 100644 --- a/src/kernel/arm64-desktop.make +++ b/src/kernel/arm64-desktop.make @@ -7,7 +7,7 @@ CC = clang++ LD = lld-link CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__NE_ARM64__ -fno-rtti -fno-exceptions -I./ \ -target aarch64-unknown-windows \ - -std=c++20 -O3 -D__NEKERNEL__ -D__NEOSKRNL__ -D__NE_VEPM__ -D__NE_MINIMAL_OS__ -D__NE_NO_BUILTIN__ -D__HAVE_NE_APIS__ -D__NE__ -I../ + -std=c++20 -D__nekernel_max_cores -O3 -D__NEKERNEL__ -D__NEOSKRNL__ -D__NE_VEPM__ -D__NE_MINIMAL_OS__ -D__NE_NO_BUILTIN__ -D__HAVE_NE_APIS__ -D__NE__ -I../ ASM = clang++ diff --git a/src/kernel/src/UserProcessScheduler.cc b/src/kernel/src/UserProcessScheduler.cc index 6bd5f3fd..d7cbfaf0 100644 --- a/src/kernel/src/UserProcessScheduler.cc +++ b/src/kernel/src/UserProcessScheduler.cc @@ -617,22 +617,22 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid) HardwareThreadScheduler::The()[index].Leak()->Busy(YES); - Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr); + Bool ret{HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr)}; //////////////////////////////////////////////////////////// - /// Rollback on fail. /// + /// Rollback on fail. /// //////////////////////////////////////////////////////////// if (!ret) continue; + (Void)(kout << "AP_" << hex_number(index)); + kout << " is now running a new task!\r"; + UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid; HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().TheCurrentTeam().Leak().AsArray()[new_pid].PTime; - (Void)(kout << "AP_" << hex_number(index)); - kout << " is now running a new task!\r"; - return YES; } diff --git a/tools/kconf.py b/tools/kconf.py new file mode 100755 index 00000000..0c892aa0 --- /dev/null +++ b/tools/kconf.py @@ -0,0 +1,11 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os, json, sys + +if __name__ == '__main__': + sys.exit(0) + + + + diff --git a/tools/kfwrk.py b/tools/kfwrk.py new file mode 100755 index 00000000..3779cd42 --- /dev/null +++ b/tools/kfwrk.py @@ -0,0 +1,90 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os, json, sys + +""" + Create directory structure for the framework. +""" +def create_directory_structure(base_path_fwrk, project_file_name, project_name): + # Define the directory structure + structure = { + project_name: { + "headers": { + ".keep": None + }, + "dist": { + ".keep": None + }, + "src": { + ".keep": None, + "DylibMain.cc": None, + }, + "xml": { + ".keep": None + }, + ".keep": None, + f"{project_file_name}.json": {} + } + } + + def create_structure(path, structure_in): + for name, content in structure_in.items(): + current_path = os.path.join(path, name) + # Create directories or files based on the content type + if isinstance(content, dict) and current_path.endswith(".json") == False: + os.makedirs(current_path, exist_ok=True) + create_structure(current_path, content) + elif content is None: + # Create an empty file + with open(current_path, 'w') as f: + pass + + # Create the base directory + os.makedirs(base_path_fwrk, exist_ok=True) + create_structure(base_path_fwrk, structure) + + # Create the JSON file + proj_json_path = os.path.join(base_path_fwrk, project_name, f"{project_file_name}.json") + + manifest = { + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": ["./", "../../../src/kernel", "../../../public/frameworks/", "../../../src/", "./"], + "sources_path": [ + + ], + "output_name": f"./dist/lib{project_name}.dylib", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] + } + + with open(proj_json_path, 'w') as json_file: + json.dump(manifest, json_file, indent=4) + + proj_cpp_path = os.path.join(base_path_fwrk, project_name, f"src/DylibMain.cc") + + cpp_file = "#include \n\nSInt32 _DylibAttach(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" + + with open(proj_cpp_path, 'w') as cpp_file_io: + cpp_file_io.write(cpp_file) + + xml_blob = f"\n" + proj_xml_path = os.path.join(base_path_fwrk, project_name, f"xml/app.xml") + + with open(proj_xml_path, 'w') as cpp_file_io: + cpp_file_io.write(xml_blob) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("HELP: mk_fwrk.py ") + sys.exit(os.EX_CONFIG) + + base_path = os.getcwd() # Use the current working directory as the base path + create_directory_structure(base_path, sys.argv[1], sys.argv[1] + '.fwrk') + + print("INFO: Framework created successfully.") diff --git a/tools/kimg.py b/tools/kimg.py new file mode 100755 index 00000000..23b94eb1 --- /dev/null +++ b/tools/kimg.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os, sys, subprocess, glob as file_glob + +def copy_to_fat(image_path, source_dir): + if not os.path.isfile(image_path): + print(f"Error: FAT32 image {image_path} does not exist.") + sys.exit(1) + + if not os.path.isdir(source_dir): + print(f"Error: {source_dir} is not a valid directory.") + sys.exit(1) + + try: + files_to_copy = file_glob.glob(os.path.join(source_dir, "*")) + + if not files_to_copy: + print(f"Warning: No files found in {source_dir}, nothing to copy.") + sys.exit(1) + + command = ["mcopy", "-spm", "-i", image_path] + files_to_copy + ["::"] + subprocess.run(command, check=True) + except Exception as e: + print(f"Error: failed: {e}") + sys.exit(1) + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("HELP: mk_img.py ") + sys.exit(1) + + image_path = sys.argv[1] + source_dir = sys.argv[2] + + copy_to_fat(image_path, source_dir) + + print("INFO: Image created successfully.") diff --git a/tools/kman.py b/tools/kman.py new file mode 100755 index 00000000..366cd732 --- /dev/null +++ b/tools/kman.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys, os + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("INFO: mk_htman.py ") + sys.exit(os.EX_CONFIG) + + manual_path = sys.argv[1] + if not os.path.exists(manual_path): + print(f"ERROR: Manual path '{manual_path}' does not exist.") + sys.exit(os.EX_NOINPUT) + + if os.path.isdir(manual_path): + print(f"ERROR: Manual path '{manual_path}' is a directory.") + sys.exit(os.EX_NOTDIR) + + if not manual_path.endswith('.man'): + print(f"ERROR: Manual path '{manual_path}' must end with '.man'") + sys.exit(os.EX_DATAERR) + + try: + with open(manual_path, 'r') as file: + content = file.read() + if not content.strip(): + print(f"ERROR: Manual file '{manual_path}' is empty.") + sys.exit(os.EX_DATAERR) + html_content = f"NeKernel Manual: {manual_path}
{content}
" + html_path = manual_path.replace('.man', '.html') + + with open(html_path, 'w') as html_file: + html_file.write(html_content) + except IOError as e: + print(f"ERROR: Could not read manual file '{manual_path}': {e}") + sys.exit(os.EX_IOERR) + + print(f"INFO: Wrote manual '{manual_path}' to HTML.") + sys.exit(os.EX_OK) diff --git a/tools/mk_app.py b/tools/mk_app.py deleted file mode 100755 index 793dd4a4..00000000 --- a/tools/mk_app.py +++ /dev/null @@ -1,78 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - -import os, json, sys - -def create_directory_structure(base_path, project_name): - # Define the directory structure - structure = { - project_name: { - "dist": { - ".keep": None - }, - "src": { - ".keep": None, - "CommandLine.cc": None, - }, - "vendor": { - ".keep": None - }, - ".keep": None, - f"{project_name}.json": {} - } - } - - def create_structure(path, structure): - for name, content in structure.items(): - current_path = os.path.join(path, name) - # Create directories or files based on the content type - if isinstance(content, dict) and current_path.endswith(".json") == False: - os.makedirs(current_path, exist_ok=True) - create_structure(current_path, content) - elif content is None: - # Create an empty file - with open(current_path, 'w') as f: - pass - - # Create the base directory - os.makedirs(base_path, exist_ok=True) - create_structure(base_path, structure) - - # Create the JSON file - proj_json_path = os.path.join(base_path, project_name, f"{project_name}.json") - - manifest = { - "compiler_path": "clang++", - "compiler_std": "c++20", - "headers_path": ["./", "../../../src/kernel", "../../../public/frameworks/", "../../../src/", "./"], - "sources_path": [ - - ], - "output_name": f"./dist/{project_name}", - "cpp_macros": [ - "kSampleFWVersion=0x0100", - "kSampleFWVersionHighest=0x0100", - "kSampleFWVersionLowest=0x0100", - "__NE_SDK__" - ] - } - - with open(proj_json_path, 'w') as json_file: - json.dump(manifest, json_file, indent=4) - - proj_cpp_path = os.path.join(base_path, project_name, f"src/CommandLine.cc") - - cpp_file = "#include \n\nSInt32 _NeMain(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" - - with open(proj_cpp_path, 'w') as cpp_file_io: - cpp_file_io.write(cpp_file) - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("HELP: mk_app.py ") - sys.exit(os.EX_CONFIG) - - base_path = os.getcwd() # Use the current working directory as the base path - create_directory_structure(base_path, sys.argv[1]) - - print("INFO: Application created successfully.") diff --git a/tools/mk_fwrk.py b/tools/mk_fwrk.py deleted file mode 100755 index 3779cd42..00000000 --- a/tools/mk_fwrk.py +++ /dev/null @@ -1,90 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - -import os, json, sys - -""" - Create directory structure for the framework. -""" -def create_directory_structure(base_path_fwrk, project_file_name, project_name): - # Define the directory structure - structure = { - project_name: { - "headers": { - ".keep": None - }, - "dist": { - ".keep": None - }, - "src": { - ".keep": None, - "DylibMain.cc": None, - }, - "xml": { - ".keep": None - }, - ".keep": None, - f"{project_file_name}.json": {} - } - } - - def create_structure(path, structure_in): - for name, content in structure_in.items(): - current_path = os.path.join(path, name) - # Create directories or files based on the content type - if isinstance(content, dict) and current_path.endswith(".json") == False: - os.makedirs(current_path, exist_ok=True) - create_structure(current_path, content) - elif content is None: - # Create an empty file - with open(current_path, 'w') as f: - pass - - # Create the base directory - os.makedirs(base_path_fwrk, exist_ok=True) - create_structure(base_path_fwrk, structure) - - # Create the JSON file - proj_json_path = os.path.join(base_path_fwrk, project_name, f"{project_file_name}.json") - - manifest = { - "compiler_path": "clang++", - "compiler_std": "c++20", - "headers_path": ["./", "../../../src/kernel", "../../../public/frameworks/", "../../../src/", "./"], - "sources_path": [ - - ], - "output_name": f"./dist/lib{project_name}.dylib", - "cpp_macros": [ - "kSampleFWVersion=0x0100", - "kSampleFWVersionHighest=0x0100", - "kSampleFWVersionLowest=0x0100", - "__NE_SDK__" - ] - } - - with open(proj_json_path, 'w') as json_file: - json.dump(manifest, json_file, indent=4) - - proj_cpp_path = os.path.join(base_path_fwrk, project_name, f"src/DylibMain.cc") - - cpp_file = "#include \n\nSInt32 _DylibAttach(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" - - with open(proj_cpp_path, 'w') as cpp_file_io: - cpp_file_io.write(cpp_file) - - xml_blob = f"\n" - proj_xml_path = os.path.join(base_path_fwrk, project_name, f"xml/app.xml") - - with open(proj_xml_path, 'w') as cpp_file_io: - cpp_file_io.write(xml_blob) - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("HELP: mk_fwrk.py ") - sys.exit(os.EX_CONFIG) - - base_path = os.getcwd() # Use the current working directory as the base path - create_directory_structure(base_path, sys.argv[1], sys.argv[1] + '.fwrk') - - print("INFO: Framework created successfully.") diff --git a/tools/mk_htman.py b/tools/mk_htman.py deleted file mode 100755 index 366cd732..00000000 --- a/tools/mk_htman.py +++ /dev/null @@ -1,40 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - -import sys, os - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("INFO: mk_htman.py ") - sys.exit(os.EX_CONFIG) - - manual_path = sys.argv[1] - if not os.path.exists(manual_path): - print(f"ERROR: Manual path '{manual_path}' does not exist.") - sys.exit(os.EX_NOINPUT) - - if os.path.isdir(manual_path): - print(f"ERROR: Manual path '{manual_path}' is a directory.") - sys.exit(os.EX_NOTDIR) - - if not manual_path.endswith('.man'): - print(f"ERROR: Manual path '{manual_path}' must end with '.man'") - sys.exit(os.EX_DATAERR) - - try: - with open(manual_path, 'r') as file: - content = file.read() - if not content.strip(): - print(f"ERROR: Manual file '{manual_path}' is empty.") - sys.exit(os.EX_DATAERR) - html_content = f"NeKernel Manual: {manual_path}
{content}
" - html_path = manual_path.replace('.man', '.html') - - with open(html_path, 'w') as html_file: - html_file.write(html_content) - except IOError as e: - print(f"ERROR: Could not read manual file '{manual_path}': {e}") - sys.exit(os.EX_IOERR) - - print(f"INFO: Wrote manual '{manual_path}' to HTML.") - sys.exit(os.EX_OK) diff --git a/tools/mk_img.py b/tools/mk_img.py deleted file mode 100755 index 23b94eb1..00000000 --- a/tools/mk_img.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import os, sys, subprocess, glob as file_glob - -def copy_to_fat(image_path, source_dir): - if not os.path.isfile(image_path): - print(f"Error: FAT32 image {image_path} does not exist.") - sys.exit(1) - - if not os.path.isdir(source_dir): - print(f"Error: {source_dir} is not a valid directory.") - sys.exit(1) - - try: - files_to_copy = file_glob.glob(os.path.join(source_dir, "*")) - - if not files_to_copy: - print(f"Warning: No files found in {source_dir}, nothing to copy.") - sys.exit(1) - - command = ["mcopy", "-spm", "-i", image_path] + files_to_copy + ["::"] - subprocess.run(command, check=True) - except Exception as e: - print(f"Error: failed: {e}") - sys.exit(1) - -if __name__ == "__main__": - if len(sys.argv) != 3: - print("HELP: mk_img.py ") - sys.exit(1) - - image_path = sys.argv[1] - source_dir = sys.argv[2] - - copy_to_fat(image_path, source_dir) - - print("INFO: Image created successfully.") diff --git a/tools/mkapp.py b/tools/mkapp.py new file mode 100755 index 00000000..793dd4a4 --- /dev/null +++ b/tools/mkapp.py @@ -0,0 +1,78 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os, json, sys + +def create_directory_structure(base_path, project_name): + # Define the directory structure + structure = { + project_name: { + "dist": { + ".keep": None + }, + "src": { + ".keep": None, + "CommandLine.cc": None, + }, + "vendor": { + ".keep": None + }, + ".keep": None, + f"{project_name}.json": {} + } + } + + def create_structure(path, structure): + for name, content in structure.items(): + current_path = os.path.join(path, name) + # Create directories or files based on the content type + if isinstance(content, dict) and current_path.endswith(".json") == False: + os.makedirs(current_path, exist_ok=True) + create_structure(current_path, content) + elif content is None: + # Create an empty file + with open(current_path, 'w') as f: + pass + + # Create the base directory + os.makedirs(base_path, exist_ok=True) + create_structure(base_path, structure) + + # Create the JSON file + proj_json_path = os.path.join(base_path, project_name, f"{project_name}.json") + + manifest = { + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": ["./", "../../../src/kernel", "../../../public/frameworks/", "../../../src/", "./"], + "sources_path": [ + + ], + "output_name": f"./dist/{project_name}", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] + } + + with open(proj_json_path, 'w') as json_file: + json.dump(manifest, json_file, indent=4) + + proj_cpp_path = os.path.join(base_path, project_name, f"src/CommandLine.cc") + + cpp_file = "#include \n\nSInt32 _NeMain(SInt32 argc, Char* argv[]) {\n\treturn EXIT_FAILURE;\n}" + + with open(proj_cpp_path, 'w') as cpp_file_io: + cpp_file_io.write(cpp_file) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("HELP: mk_app.py ") + sys.exit(os.EX_CONFIG) + + base_path = os.getcwd() # Use the current working directory as the base path + create_directory_structure(base_path, sys.argv[1]) + + print("INFO: Application created successfully.") -- cgit v1.2.3