Files
BBeOS/sdk/tools/bbeos-sdk.c
Eliott 7b53cde2ae
Some checks failed
CI / markdown-lint (push) Failing after 14s
Complete BBeOS project implementation with BlackBerry-inspired website
- Updated .gitignore with comprehensive exclusions for build artifacts, IDE files, and OS-specific files
- Created BlackBerry-inspired website with Heroicons and Gitea integration
- Added complete project structure with all 7 phases implemented
- Included kernel drivers, UI components, telephony stack, and packaging tools
- Added emulation scripts for testing and development
- Comprehensive documentation for all development phases
- Security analysis and hardware testing guides
- SDK and application framework for third-party development
2025-08-01 10:20:28 +02:00

638 lines
21 KiB
C

/*
* BBeOS Software Development Kit (SDK)
* BlackBerry Classic Q20 Application Development Tools
*
* This tool provides development utilities, project templates,
* and build tools for BBeOS application development.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <dirent.h>
#include <libgen.h>
#define BBEOS_SDK_VERSION "1.0.0"
#define BBEOS_SDK_PATH "/usr/share/bbeos/sdk"
#define BBEOS_TEMPLATES_PATH "/usr/share/bbeos/sdk/templates"
#define BBEOS_EXAMPLES_PATH "/usr/share/bbeos/sdk/examples"
/* Project types */
enum project_type {
PROJECT_TYPE_CONSOLE, /* Console application */
PROJECT_TYPE_GUI, /* GUI application */
PROJECT_TYPE_SERVICE, /* System service */
PROJECT_TYPE_LIBRARY, /* Shared library */
PROJECT_TYPE_DRIVER /* Kernel driver */
};
/* Project template structure */
struct project_template {
const char *name;
const char *description;
enum project_type type;
const char *template_dir;
const char *dependencies[];
};
/* Available project templates */
static struct project_template templates[] = {
{
"console-app",
"Simple console application",
PROJECT_TYPE_CONSOLE,
"console-app",
{"libc", NULL}
},
{
"gui-app",
"GUI application with Wayland",
PROJECT_TYPE_GUI,
"gui-app",
{"wayland", "cairo", "pango", NULL}
},
{
"system-service",
"System service daemon",
PROJECT_TYPE_SERVICE,
"system-service",
{"libc", "systemd", NULL}
},
{
"shared-lib",
"Shared library",
PROJECT_TYPE_LIBRARY,
"shared-lib",
{"libc", NULL}
},
{
"kernel-driver",
"Linux kernel driver",
PROJECT_TYPE_DRIVER,
"kernel-driver",
{"kernel-headers", NULL}
}
};
/* Build configuration */
struct build_config {
char project_name[64];
char project_version[32];
char author[64];
char description[256];
enum project_type type;
char dependencies[512];
char target_arch[16];
char compiler[32];
char cflags[256];
char ldflags[256];
};
/* Create directory recursively */
static int create_directory_recursive(const char *path) {
char *path_copy = strdup(path);
char *token = strtok(path_copy, "/");
char current_path[512] = "";
while (token != NULL) {
if (strlen(current_path) > 0) {
strcat(current_path, "/");
}
strcat(current_path, token);
if (mkdir(current_path, 0755) != 0 && errno != EEXIST) {
free(path_copy);
return -1;
}
token = strtok(NULL, "/");
}
free(path_copy);
return 0;
}
/* Copy file with template substitution */
static int copy_file_with_substitution(const char *src_path, const char *dst_path,
struct build_config *config) {
FILE *src, *dst;
char line[1024];
char *token, *replacement;
src = fopen(src_path, "r");
if (!src) {
fprintf(stderr, "Error: Cannot open source file %s: %s\n", src_path, strerror(errno));
return -1;
}
dst = fopen(dst_path, "w");
if (!dst) {
fprintf(stderr, "Error: Cannot create destination file %s: %s\n", dst_path, strerror(errno));
fclose(src);
return -1;
}
while (fgets(line, sizeof(line), src)) {
char *modified_line = strdup(line);
/* Replace template variables */
if (strstr(modified_line, "{{PROJECT_NAME}}")) {
token = "{{PROJECT_NAME}}";
replacement = config->project_name;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
if (strstr(modified_line, "{{PROJECT_VERSION}}")) {
token = "{{PROJECT_VERSION}}";
replacement = config->project_version;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
if (strstr(modified_line, "{{AUTHOR}}")) {
token = "{{AUTHOR}}";
replacement = config->author;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
if (strstr(modified_line, "{{DESCRIPTION}}")) {
token = "{{DESCRIPTION}}";
replacement = config->description;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
if (strstr(modified_line, "{{TARGET_ARCH}}")) {
token = "{{TARGET_ARCH}}";
replacement = config->target_arch;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
if (strstr(modified_line, "{{CFLAGS}}")) {
token = "{{CFLAGS}}";
replacement = config->cflags;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
if (strstr(modified_line, "{{LDFLAGS}}")) {
token = "{{LDFLAGS}}";
replacement = config->ldflags;
char *pos = strstr(modified_line, token);
if (pos) {
memmove(pos + strlen(replacement), pos + strlen(token),
strlen(pos + strlen(token)) + 1);
memcpy(pos, replacement, strlen(replacement));
}
}
fputs(modified_line, dst);
free(modified_line);
}
fclose(src);
fclose(dst);
return 0;
}
/* Copy directory recursively with template substitution */
static int copy_directory_recursive(const char *src_dir, const char *dst_dir,
struct build_config *config) {
DIR *dir;
struct dirent *entry;
char src_path[512];
char dst_path[512];
dir = opendir(src_dir);
if (!dir) {
fprintf(stderr, "Error: Cannot open source directory %s: %s\n", src_dir, strerror(errno));
return -1;
}
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
snprintf(src_path, sizeof(src_path), "%s/%s", src_dir, entry->d_name);
snprintf(dst_path, sizeof(dst_path), "%s/%s", dst_dir, entry->d_name);
struct stat st;
if (stat(src_path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
/* Create directory and recurse */
if (create_directory_recursive(dst_path) != 0) {
closedir(dir);
return -1;
}
if (copy_directory_recursive(src_path, dst_path, config) != 0) {
closedir(dir);
return -1;
}
} else {
/* Copy file with template substitution */
if (copy_file_with_substitution(src_path, dst_path, config) != 0) {
closedir(dir);
return -1;
}
}
}
}
closedir(dir);
return 0;
}
/* Create new project */
static int create_project(const char *project_name, const char *template_name,
struct build_config *config) {
char template_path[512];
char project_path[512];
struct project_template *template = NULL;
/* Find template */
for (int i = 0; i < sizeof(templates) / sizeof(templates[0]); i++) {
if (strcmp(templates[i].name, template_name) == 0) {
template = &templates[i];
break;
}
}
if (!template) {
fprintf(stderr, "Error: Unknown template '%s'\n", template_name);
return -1;
}
/* Set up project configuration */
strncpy(config->project_name, project_name, sizeof(config->project_name) - 1);
strcpy(config->project_version, "1.0.0");
strcpy(config->author, "BBeOS Developer");
snprintf(config->description, sizeof(config->description),
"BBeOS %s application", template->description);
config->type = template->type;
strcpy(config->target_arch, "armv7");
strcpy(config->compiler, "arm-linux-gnueabihf-gcc");
strcpy(config->cflags, "-Wall -Wextra -std=c99 -O2 -g");
strcpy(config->ldflags, "");
/* Build dependencies string */
config->dependencies[0] = '\0';
for (int i = 0; template->dependencies[i] != NULL; i++) {
if (i > 0) {
strcat(config->dependencies, " ");
}
strcat(config->dependencies, template->dependencies[i]);
}
/* Create project directory */
if (create_directory_recursive(project_name) != 0) {
fprintf(stderr, "Error: Cannot create project directory\n");
return -1;
}
/* Copy template files */
snprintf(template_path, sizeof(template_path), "%s/%s",
BBEOS_TEMPLATES_PATH, template->template_dir);
snprintf(project_path, sizeof(project_path), "%s", project_name);
if (copy_directory_recursive(template_path, project_path, config) != 0) {
fprintf(stderr, "Error: Cannot copy template files\n");
return -1;
}
printf("Project '%s' created successfully using template '%s'\n",
project_name, template_name);
printf("Project directory: %s\n", project_name);
return 0;
}
/* Build project */
static int build_project(const char *project_path) {
char makefile_path[512];
char cmd[1024];
snprintf(makefile_path, sizeof(makefile_path), "%s/Makefile", project_path);
if (access(makefile_path, F_OK) != 0) {
fprintf(stderr, "Error: No Makefile found in project directory\n");
return -1;
}
printf("Building project in %s...\n", project_path);
snprintf(cmd, sizeof(cmd), "cd %s && make clean && make", project_path);
int result = system(cmd);
if (result != 0) {
fprintf(stderr, "Error: Build failed\n");
return -1;
}
printf("Build completed successfully\n");
return 0;
}
/* Install project */
static int install_project(const char *project_path) {
char cmd[1024];
printf("Installing project from %s...\n", project_path);
snprintf(cmd, sizeof(cmd), "cd %s && make install", project_path);
int result = system(cmd);
if (result != 0) {
fprintf(stderr, "Error: Installation failed\n");
return -1;
}
printf("Installation completed successfully\n");
return 0;
}
/* Package project */
static int package_project(const char *project_path) {
char cmd[1024];
printf("Packaging project from %s...\n", project_path);
snprintf(cmd, sizeof(cmd), "cd %s && make package", project_path);
int result = system(cmd);
if (result != 0) {
fprintf(stderr, "Error: Packaging failed\n");
return -1;
}
printf("Packaging completed successfully\n");
return 0;
}
/* List available templates */
static void list_templates(void) {
printf("Available BBeOS project templates:\n");
printf("==================================\n");
for (int i = 0; i < sizeof(templates) / sizeof(templates[0]); i++) {
printf("%-15s - %s\n", templates[i].name, templates[i].description);
}
printf("\nUse 'bbeos-sdk create <project-name> <template>' to create a new project\n");
}
/* Show project information */
static void show_project_info(const char *project_path) {
char config_path[512];
FILE *config_file;
char line[256];
snprintf(config_path, sizeof(config_path), "%s/.bbeos-project", project_path);
config_file = fopen(config_path, "r");
if (!config_file) {
printf("No BBeOS project configuration found in %s\n", project_path);
return;
}
printf("BBeOS Project Information:\n");
printf("==========================\n");
while (fgets(line, sizeof(line), config_file)) {
line[strcspn(line, "\n")] = 0;
printf("%s\n", line);
}
fclose(config_file);
}
/* Create template files */
static int create_template_files(void) {
char template_dir[512];
/* Create console app template */
snprintf(template_dir, sizeof(template_dir), "%s/console-app", BBEOS_TEMPLATES_PATH);
create_directory_recursive(template_dir);
/* Create main.c */
char main_c_path[512];
snprintf(main_c_path, sizeof(main_c_path), "%s/main.c", template_dir);
FILE *main_c = fopen(main_c_path, "w");
if (main_c) {
fprintf(main_c, "#include <stdio.h>\n");
fprintf(main_c, "#include <stdlib.h>\n");
fprintf(main_c, "#include <unistd.h>\n");
fprintf(main_c, "\n");
fprintf(main_c, "int main(int argc, char *argv[]) {\n");
fprintf(main_c, " printf(\"Hello from {{PROJECT_NAME}} v{{PROJECT_VERSION}}\\n\");\n");
fprintf(main_c, " printf(\"Author: {{AUTHOR}}\\n\");\n");
fprintf(main_c, " printf(\"Description: {{DESCRIPTION}}\\n\");\n");
fprintf(main_c, " \n");
fprintf(main_c, " return 0;\n");
fprintf(main_c, "}\n");
fclose(main_c);
}
/* Create Makefile */
char makefile_path[512];
snprintf(makefile_path, sizeof(makefile_path), "%s/Makefile", template_dir);
FILE *makefile = fopen(makefile_path, "w");
if (makefile) {
fprintf(makefile, "# BBeOS {{PROJECT_NAME}} Makefile\n");
fprintf(makefile, "# Generated by BBeOS SDK\n");
fprintf(makefile, "\n");
fprintf(makefile, "CC = {{COMPILER}}\n");
fprintf(makefile, "CFLAGS = {{CFLAGS}}\n");
fprintf(makefile, "LDFLAGS = {{LDFLAGS}}\n");
fprintf(makefile, "TARGET = {{PROJECT_NAME}}\n");
fprintf(makefile, "SOURCES = main.c\n");
fprintf(makefile, "OBJECTS = $(SOURCES:.c=.o)\n");
fprintf(makefile, "\n");
fprintf(makefile, "all: $(TARGET)\n");
fprintf(makefile, "\n");
fprintf(makefile, "$(TARGET): $(OBJECTS)\n");
fprintf(makefile, "\t$(CC) $(OBJECTS) -o $@ $(LDFLAGS)\n");
fprintf(makefile, "\n");
fprintf(makefile, "%.o: %.c\n");
fprintf(makefile, "\t$(CC) $(CFLAGS) -c $< -o $@\n");
fprintf(makefile, "\n");
fprintf(makefile, "clean:\n");
fprintf(makefile, "\trm -f $(OBJECTS) $(TARGET)\n");
fprintf(makefile, "\n");
fprintf(makefile, "install: $(TARGET)\n");
fprintf(makefile, "\tinstall -d $(DESTDIR)/usr/bin\n");
fprintf(makefile, "\tinstall -m 755 $(TARGET) $(DESTDIR)/usr/bin/\n");
fprintf(makefile, "\n");
fprintf(makefile, "package: $(TARGET)\n");
fprintf(makefile, "\ttar -czf {{PROJECT_NAME}}-{{PROJECT_VERSION}}.tar.gz $(TARGET) README.md\n");
fprintf(makefile, "\n");
fprintf(makefile, ".PHONY: all clean install package\n");
fclose(makefile);
}
/* Create README.md */
char readme_path[512];
snprintf(readme_path, sizeof(readme_path), "%s/README.md", template_dir);
FILE *readme = fopen(readme_path, "w");
if (readme) {
fprintf(readme, "# {{PROJECT_NAME}}\n");
fprintf(readme, "\n");
fprintf(readme, "{{DESCRIPTION}}\n");
fprintf(readme, "\n");
fprintf(readme, "## Version\n");
fprintf(readme, "\n");
fprintf(readme, "{{PROJECT_VERSION}}\n");
fprintf(readme, "\n");
fprintf(readme, "## Author\n");
fprintf(readme, "\n");
fprintf(readme, "{{AUTHOR}}\n");
fprintf(readme, "\n");
fprintf(readme, "## Building\n");
fprintf(readme, "\n");
fprintf(readme, "```bash\n");
fprintf(readme, "make\n");
fprintf(readme, "```\n");
fprintf(readme, "\n");
fprintf(readme, "## Installation\n");
fprintf(readme, "\n");
fprintf(readme, "```bash\n");
fprintf(readme, "make install\n");
fprintf(readme, "```\n");
fprintf(readme, "\n");
fprintf(readme, "## Usage\n");
fprintf(readme, "\n");
fprintf(readme, "```bash\n");
fprintf(readme, "{{PROJECT_NAME}}\n");
fprintf(readme, "```\n");
fclose(readme);
}
/* Create project config */
char config_path[512];
snprintf(config_path, sizeof(config_path), "%s/.bbeos-project", template_dir);
FILE *config = fopen(config_path, "w");
if (config) {
fprintf(config, "Name: {{PROJECT_NAME}}\n");
fprintf(config, "Version: {{PROJECT_VERSION}}\n");
fprintf(config, "Author: {{AUTHOR}}\n");
fprintf(config, "Description: {{DESCRIPTION}}\n");
fprintf(config, "Type: Console Application\n");
fprintf(config, "Target: {{TARGET_ARCH}}\n");
fprintf(config, "Dependencies: {{DEPENDENCIES}}\n");
fclose(config);
}
return 0;
}
/* Main function */
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("BBeOS Software Development Kit (SDK)\n");
printf("====================================\n");
printf("Version: %s\n", BBEOS_SDK_VERSION);
printf("\n");
printf("Usage:\n");
printf(" %s create <project-name> <template> - Create new project\n", argv[0]);
printf(" %s build <project-path> - Build project\n", argv[0]);
printf(" %s install <project-path> - Install project\n", argv[0]);
printf(" %s package <project-path> - Package project\n", argv[0]);
printf(" %s templates - List available templates\n", argv[0]);
printf(" %s info <project-path> - Show project information\n", argv[0]);
printf(" %s init-templates - Initialize template files\n", argv[0]);
printf("\n");
printf("Examples:\n");
printf(" %s create my-app console-app - Create console application\n", argv[0]);
printf(" %s create my-gui gui-app - Create GUI application\n", argv[0]);
printf(" %s build my-app - Build my-app project\n", argv[0]);
return 1;
}
if (strcmp(argv[1], "create") == 0) {
if (argc != 4) {
fprintf(stderr, "Usage: %s create <project-name> <template>\n", argv[0]);
return 1;
}
struct build_config config;
return create_project(argv[2], argv[3], &config);
} else if (strcmp(argv[1], "build") == 0) {
if (argc != 3) {
fprintf(stderr, "Usage: %s build <project-path>\n", argv[0]);
return 1;
}
return build_project(argv[2]);
} else if (strcmp(argv[1], "install") == 0) {
if (argc != 3) {
fprintf(stderr, "Usage: %s install <project-path>\n", argv[0]);
return 1;
}
return install_project(argv[2]);
} else if (strcmp(argv[1], "package") == 0) {
if (argc != 3) {
fprintf(stderr, "Usage: %s package <project-path>\n", argv[0]);
return 1;
}
return package_project(argv[2]);
} else if (strcmp(argv[1], "templates") == 0) {
list_templates();
return 0;
} else if (strcmp(argv[1], "info") == 0) {
if (argc != 3) {
fprintf(stderr, "Usage: %s info <project-path>\n", argv[0]);
return 1;
}
show_project_info(argv[2]);
return 0;
} else if (strcmp(argv[1], "init-templates") == 0) {
return create_template_files();
} else {
fprintf(stderr, "Unknown command: %s\n", argv[1]);
return 1;
}
return 0;
}