moved to gitea
This commit is contained in:
1157
source_code/code.txt
Normal file
1157
source_code/code.txt
Normal file
File diff suppressed because it is too large
Load Diff
65
source_code/shmake.sh
Executable file
65
source_code/shmake.sh
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake - the "Simple helpful make system" aka "the shell make system"
|
||||
# A POSIX-compliant build system for C projects
|
||||
# Author: Emilia Marigold
|
||||
# License: AGPL-3.0
|
||||
|
||||
set -u
|
||||
|
||||
SCRIPT_NAME="shmake"
|
||||
|
||||
# Get script directory once
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
|
||||
# Source all utility scripts
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_utils.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_help_message.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_init_project.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_add_module.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_download_library.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_link_library.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_sync_makefile.sh"
|
||||
. "$SCRIPT_DIR/shmake_source/shmake_process_license.sh"
|
||||
|
||||
#=========================================================================================
|
||||
# Main Entry Point
|
||||
#=========================================================================================
|
||||
main()
|
||||
{
|
||||
if [ $# -eq 0 ]; then
|
||||
help_message
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
help|--help|-h)
|
||||
help_message
|
||||
;;
|
||||
init)
|
||||
init_project
|
||||
;;
|
||||
module)
|
||||
shift
|
||||
add_module "$@"
|
||||
;;
|
||||
library)
|
||||
shift
|
||||
add_library "$@"
|
||||
;;
|
||||
link)
|
||||
shift
|
||||
add_linked_library "$@"
|
||||
;;
|
||||
sync)
|
||||
sync_project
|
||||
;;
|
||||
*)
|
||||
printf "Command unknown: %s\n" "$1"
|
||||
printf "Run '%s help' for usage.\n" "$SCRIPT_NAME"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
79
source_code/shmake_add_module.sh
Normal file
79
source_code/shmake_add_module.sh
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_module.sh - Module creation for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
add_module()
|
||||
{
|
||||
check_project_root
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
printf "Usage: %s module [name]\n" "$SCRIPT_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MODULE_NAME="$1"
|
||||
MODULE_DIR="source_code/MODULE_${MODULE_NAME}"
|
||||
MODULE_NAME_UPPER=$(printf "%s" "$MODULE_NAME" | tr '[:lower:]' '[:upper:]')
|
||||
|
||||
printf "Creating module '%s'...\n" "$MODULE_NAME"
|
||||
|
||||
mkdir -p "$MODULE_DIR"
|
||||
mkdir -p "$MODULE_DIR/internal"
|
||||
mkdir -p "$MODULE_DIR/tests"
|
||||
|
||||
cat > "$MODULE_DIR/${MODULE_NAME}.h" << EOF
|
||||
#ifndef ${MODULE_NAME_UPPER}_H
|
||||
#define ${MODULE_NAME_UPPER}_H
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
#endif /* ${MODULE_NAME_UPPER}_H */
|
||||
EOF
|
||||
|
||||
cat > "$MODULE_DIR/${MODULE_NAME}.c" << EOF
|
||||
#include "${MODULE_NAME}.h"
|
||||
|
||||
/* Function implementations */
|
||||
|
||||
EOF
|
||||
|
||||
cat > "$MODULE_DIR/internal/${MODULE_NAME}_internal.h" << EOF
|
||||
#ifndef ${MODULE_NAME_UPPER}_INTERNAL_H
|
||||
#define ${MODULE_NAME_UPPER}_INTERNAL_H
|
||||
|
||||
/* Internal function declarations (not exposed in public header) */
|
||||
|
||||
#endif /* ${MODULE_NAME_UPPER}_INTERNAL_H */
|
||||
EOF
|
||||
|
||||
cat > "$MODULE_DIR/internal/${MODULE_NAME}_internal.c" << EOF
|
||||
#include "${MODULE_NAME}_internal.h"
|
||||
#include "../${MODULE_NAME}.h"
|
||||
|
||||
/* Internal function implementations */
|
||||
|
||||
EOF
|
||||
|
||||
cat > "$MODULE_DIR/tests/${MODULE_NAME}_test.h" << EOF
|
||||
#ifndef ${MODULE_NAME_UPPER}_TEST_H
|
||||
#define ${MODULE_NAME_UPPER}_TEST_H
|
||||
|
||||
/* Test function declarations */
|
||||
|
||||
#endif /* ${MODULE_NAME_UPPER}_TEST_H */
|
||||
EOF
|
||||
|
||||
cat > "$MODULE_DIR/tests/${MODULE_NAME}_test.c" << EOF
|
||||
#include "${MODULE_NAME}_test.h"
|
||||
#include "../${MODULE_NAME}.h"
|
||||
|
||||
/* Test implementations */
|
||||
|
||||
EOF
|
||||
|
||||
printf "Module '%s' created successfully!\n" "$MODULE_NAME"
|
||||
printf " Location: %s\n" "$MODULE_DIR"
|
||||
printf " Next: Add your implementation to the .c files.\n"
|
||||
printf " Run 'shmake sync' after adding source files to update Makefile.\n"
|
||||
}
|
||||
72
source_code/shmake_clone_test_library.sh
Normal file
72
source_code/shmake_clone_test_library.sh
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_testlib.sh - Test library cloning for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
clone_test_library()
|
||||
{
|
||||
test_lib="$1"
|
||||
LIBRARY_DIR="external_code/test_only/source_code"
|
||||
LIB_URL=""
|
||||
LIB_NAME=""
|
||||
|
||||
case "$test_lib" in
|
||||
Unity|unity)
|
||||
LIB_URL="https://github.com/ThrowTheSwitch/Unity.git"
|
||||
LIB_NAME="Unity"
|
||||
;;
|
||||
CMocka|cmocka|CMOCKA)
|
||||
LIB_URL="https://github.com/clibs/cmocka.git"
|
||||
LIB_NAME="cmocka"
|
||||
;;
|
||||
Check|check)
|
||||
LIB_URL="https://github.com/libcheck/check.git"
|
||||
LIB_NAME="check"
|
||||
;;
|
||||
None|none)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
printf "Warning: Unknown test library '%s'. Skipping auto-clone.\n" "$test_lib"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "\nAuto-cloning test library '%s' to %s...\n" "$test_lib" "$LIBRARY_DIR"
|
||||
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
printf "Warning: 'git' not found. Library '%s' will need to be added manually.\n" "$test_lib"
|
||||
printf "URL: %s\n" "$LIB_URL"
|
||||
mkdir -p "shmake_config"
|
||||
printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -d "$LIBRARY_DIR/$LIB_NAME" ]; then
|
||||
printf "Note: '%s' already exists in %s\n" "$LIB_NAME" "$LIBRARY_DIR"
|
||||
printf "Overwrite? [y/N]: "
|
||||
read -r overwrite
|
||||
case "$overwrite" in
|
||||
y|Y)
|
||||
rm -rf "$LIBRARY_DIR/$LIB_NAME"
|
||||
;;
|
||||
*)
|
||||
printf "Keeping existing installation.\n"
|
||||
printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
mkdir -p "$LIBRARY_DIR"
|
||||
printf "Cloning %s (shallow)...\n" "$LIB_NAME"
|
||||
if git clone "$LIB_URL" "$LIBRARY_DIR/$LIB_NAME"; then
|
||||
printf "Test library '%s' cloned successfully!\n" "$test_lib"
|
||||
printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
|
||||
else
|
||||
printf "Warning: Failed to clone '%s'. You may need to add it manually.\n" "$test_lib"
|
||||
printf "URL: %s\n" "$LIB_URL"
|
||||
printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
89
source_code/shmake_download_library.sh
Normal file
89
source_code/shmake_download_library.sh
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_library.sh - External library addition for shmake
|
||||
# Author: Emilia Marigold - 2026
|
||||
|
||||
download_library()
|
||||
{
|
||||
check_project_root
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
printf "Usage: %s library [url]\n" "$SCRIPT_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LIBRARY_URL="$1"
|
||||
LIBRARY_DIR="external_code/shared_libraries/source_code"
|
||||
|
||||
printf "Adding library from '%s' to %s...\n" "$LIBRARY_URL" "$LIBRARY_DIR"
|
||||
|
||||
LIBRARY_NAME=$(printf "%s" "$LIBRARY_URL" | sed 's|.*/||' | sed 's|.git$||')
|
||||
|
||||
if [ -d "$LIBRARY_DIR/$LIBRARY_NAME" ]; then
|
||||
printf "Warning: '%s' already exists in %s\n" "$LIBRARY_NAME" "$LIBRARY_DIR"
|
||||
printf "Overwrite? [y/N]: "
|
||||
read -r overwrite
|
||||
|
||||
case "$overwrite" in
|
||||
y|Y)
|
||||
rm -rf "$LIBRARY_DIR/$LIBRARY_NAME"
|
||||
;;
|
||||
*)
|
||||
printf "Aborted.\n" && exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "$LIBRARY_URL" in
|
||||
*.git)
|
||||
printf "Detected Git repository. Using git clone (shallow)...\n"
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
mkdir -p "$LIBRARY_DIR"
|
||||
git clone "$LIBRARY_URL" "$LIBRARY_DIR/$LIBRARY_NAME"
|
||||
if [ $? -eq 0 ]; then
|
||||
printf "Library '%s' cloned successfully!\n" "$LIBRARY_NAME"
|
||||
printf "%s\n" "$LIBRARY_URL" >> "shmake_config/project_external_libraries.config"
|
||||
else
|
||||
printf "Error: Git clone failed.\n"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
printf "Error: 'git' not found. Please install git.\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
printf "Detected file download. Trying wget/curl...\n"
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
printf "Using wget...\n"
|
||||
mkdir -p "$LIBRARY_DIR"
|
||||
wget "$LIBRARY_URL" -O "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
tar -xzf "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" -C "$LIBRARY_DIR" 2>/dev/null
|
||||
rm "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz"
|
||||
printf "Library '%s' downloaded successfully!\n" "$LIBRARY_NAME"
|
||||
printf "%s\n" "$LIBRARY_URL" >> "shmake_config/project_external_libraries.config"
|
||||
else
|
||||
printf "Error: wget download failed.\n"
|
||||
exit 1
|
||||
fi
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
printf "Using curl...\n"
|
||||
mkdir -p "$LIBRARY_DIR"
|
||||
curl -L "$LIBRARY_URL" -o "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
tar -xzf "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" -C "$LIBRARY_DIR" 2>/dev/null
|
||||
rm "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz"
|
||||
printf "Library '%s' downloaded successfully!\n" "$LIBRARY_NAME"
|
||||
printf "%s\n" "$LIBRARY_URL" >> "shmake_config/project_external_libraries.config"
|
||||
else
|
||||
printf "Error: curl download failed.\n"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
printf "Error: Neither 'wget' nor 'curl' found. Please install one.\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
30
source_code/shmake_help_message.sh
Normal file
30
source_code/shmake_help_message.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_help.sh - Help message for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
help_message()
|
||||
{
|
||||
printf "USAGE:\n"
|
||||
printf " %s [command] [options]\n\n" "$SCRIPT_NAME"
|
||||
printf "COMMANDS:\n"
|
||||
printf " help Show this help menu\n"
|
||||
printf " init Initialize a new C project structure\n"
|
||||
printf " module [name] Create a new module in source_code/MODULE_name/\n"
|
||||
printf " library [url] Add a library from URL (git clone or wget/curl)\n"
|
||||
printf " link [libs] Add linked libraries (e.g., 'link X11 pthread m')\n"
|
||||
printf " sync Auto-generate Build Configs from source files\n\n"
|
||||
printf "BUILD MODES (via make BUILD_MODE=...):\n"
|
||||
printf " debug Build with debug symbols and debug_only sources\n"
|
||||
printf " release Build with optimizations and release_only sources\n"
|
||||
printf " test Build with test flags and test_only sources\n"
|
||||
printf " (Default: release)\n\n"
|
||||
printf "EXAMPLES:\n"
|
||||
printf " %s\n" "$SCRIPT_NAME"
|
||||
printf " %s init\n" "$SCRIPT_NAME"
|
||||
printf " %s module my_feature\n" "$SCRIPT_NAME"
|
||||
printf " %s library https://github.com/user/repo.git\n" "$SCRIPT_NAME"
|
||||
printf " %s link X11 pthread m\n" "$SCRIPT_NAME"
|
||||
printf " %s sync\n" "$SCRIPT_NAME"
|
||||
printf " make BUILD_MODE=debug\n"
|
||||
}
|
||||
323
source_code/shmake_init_project.sh
Normal file
323
source_code/shmake_init_project.sh
Normal file
@@ -0,0 +1,323 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_init.sh - Project initialization for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
init_project()
|
||||
{
|
||||
printf "Initializing new project...\n\n"
|
||||
read_input "Project Name" "" PROJECT_NAME
|
||||
|
||||
if [ -z "$PROJECT_NAME" ]; then
|
||||
printf "Error: Project Name cannot be empty.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read_input "C Compiler (gcc, clang, tcc, cc)" "gcc" COMPILER
|
||||
read_input "C Standard (C99, C11, C17, C23)" "C11" C_VERSION
|
||||
read_input "Test Library (Unity, Check, CMOCKA, None)" "None" TEST_LIB
|
||||
|
||||
printf "\nSelect License:\n"
|
||||
printf " 1) 0BSD\n"
|
||||
printf " 2) AGPL-3.0\n"
|
||||
printf " 3) Apache-2.0\n"
|
||||
printf " 4) BSD-2-Clause\n"
|
||||
printf " 5) BSD-3-Clause\n"
|
||||
printf " 6) BSD-3-Clause-Clear\n"
|
||||
printf " 7) BSL-1.0\n"
|
||||
printf " 8) CC0-1.0\n"
|
||||
printf " 9) CC-BY-4.0\n"
|
||||
printf " 10) CC-BY-SA-4.0\n"
|
||||
printf " 11) EPL-1.0\n"
|
||||
printf " 12) EPL-2.0\n"
|
||||
printf " 13) EUPL-1.2\n"
|
||||
printf " 14) GPL-2.0\n"
|
||||
printf " 15) GPL-3.0\n"
|
||||
printf " 16) ISC\n"
|
||||
printf " 17) LGPL-2.1\n"
|
||||
printf " 18) LGPL-3.0\n"
|
||||
printf " 19) MIT\n"
|
||||
printf " 20) MIT-0\n"
|
||||
printf " 21) MPL-2.0\n"
|
||||
printf " 22) MulanPSL-2.0\n"
|
||||
printf " 23) OFL-1.1\n"
|
||||
printf " 24) OSL-3.0\n"
|
||||
printf " 25) Unlicense\n"
|
||||
printf " 26) UPL-1.0\n"
|
||||
printf " 27) WTFPL\n"
|
||||
printf " 28) Zlib\n"
|
||||
printf " 29) Custom/None\n"
|
||||
printf "\nOption [1-29]: "
|
||||
read -r LICENSE_CHOICE
|
||||
|
||||
case "$LICENSE_CHOICE" in
|
||||
1) LICENSE="0BSD" ;;
|
||||
2) LICENSE="AGPL-3.0" ;;
|
||||
3) LICENSE="Apache-2.0" ;;
|
||||
4) LICENSE="BSD-2-Clause" ;;
|
||||
5) LICENSE="BSD-3-Clause" ;;
|
||||
6) LICENSE="BSD-3-Clause-Clear" ;;
|
||||
7) LICENSE="BSL-1.0" ;;
|
||||
8) LICENSE="CC0-1.0" ;;
|
||||
9) LICENSE="CC-BY-4.0" ;;
|
||||
10) LICENSE="CC-BY-SA-4.0" ;;
|
||||
11) LICENSE="EPL-1.0" ;;
|
||||
12) LICENSE="EPL-2.0" ;;
|
||||
13) LICENSE="EUPL-1.2" ;;
|
||||
14) LICENSE="GPL-2.0" ;;
|
||||
15) LICENSE="GPL-3.0" ;;
|
||||
16) LICENSE="ISC" ;;
|
||||
17) LICENSE="LGPL-2.1" ;;
|
||||
18) LICENSE="LGPL-3.0" ;;
|
||||
19) LICENSE="MIT" ;;
|
||||
20) LICENSE="MIT-0" ;;
|
||||
21) LICENSE="MPL-2.0" ;;
|
||||
22) LICENSE="MulanPSL-2.0" ;;
|
||||
23) LICENSE="OFL-1.1" ;;
|
||||
24) LICENSE="OSL-3.0" ;;
|
||||
25) LICENSE="Unlicense" ;;
|
||||
26) LICENSE="UPL-1.0" ;;
|
||||
27) LICENSE="WTFPL" ;;
|
||||
28) LICENSE="Zlib" ;;
|
||||
29)
|
||||
printf "Enter license name: "
|
||||
read -r LICENSE
|
||||
[ -z "$LICENSE" ] && LICENSE="Custom"
|
||||
;;
|
||||
*)
|
||||
printf "Invalid selection. Defaulting to Custom\n"
|
||||
LICENSE="Custom"
|
||||
;;
|
||||
esac
|
||||
|
||||
TARGETS="linux macos windows bsd ios ipados android"
|
||||
ENABLED_TARGETS=""
|
||||
|
||||
printf "\nSelect Build Targets (y/n for each):\n"
|
||||
for target in $TARGETS; do
|
||||
printf " Enable %s? [y/n]: " "$target"
|
||||
read -r choice
|
||||
case "$choice" in
|
||||
y|Y) ENABLED_TARGETS="$ENABLED_TARGETS $target" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -z "$ENABLED_TARGETS" ] && printf "No targets selected. Defaulting to linux.\n" && ENABLED_TARGETS=" linux"
|
||||
|
||||
printf "\nDo you need a resources folder? [y/n]: "
|
||||
read -r NEED_RESOURCES
|
||||
ENABLED_RESOURCES=""
|
||||
|
||||
if [ "$NEED_RESOURCES" = "y" ] || [ "$NEED_RESOURCES" = "Y" ]; then
|
||||
printf "\nSelect Resource Sub-directories (y/n for each):\n"
|
||||
RESOURCE_TYPES="fonts images models music sound_effects text textures"
|
||||
for resource in $RESOURCE_TYPES; do
|
||||
printf " Enable %s? [y/n]: " "$resource"
|
||||
read -r choice
|
||||
case "$choice" in
|
||||
y|Y) ENABLED_RESOURCES="$ENABLED_RESOURCES $resource" ;;
|
||||
esac
|
||||
done
|
||||
[ -z "$ENABLED_RESOURCES" ] && printf "No resources selected. Enabling all by default.\n" && ENABLED_RESOURCES=" fonts images models music sound_effects text textures"
|
||||
fi
|
||||
|
||||
printf "\nVersion Control (git, hg, svn, fossil, bzr, darcs, none): "
|
||||
read -r VCS
|
||||
[ -z "$VCS" ] && VCS="git"
|
||||
|
||||
VERSION=$(date +"%y.%j.%H%M")
|
||||
|
||||
printf "\nCreating project folder '%s'...\n" "$PROJECT_NAME"
|
||||
mkdir -p "$PROJECT_NAME"
|
||||
cd "$PROJECT_NAME" || { printf "Error: Failed to enter project directory.\n"; exit 1; }
|
||||
|
||||
printf "Creating subdirectories...\n"
|
||||
mkdir -p "source_code"
|
||||
mkdir -p "external_code/shared_libraries/source_code"
|
||||
mkdir -p "external_code/shared_libraries/binary"
|
||||
mkdir -p "external_code/test_only/source_code"
|
||||
mkdir -p "external_code/test_only/binary"
|
||||
mkdir -p "external_code/debug_only/source_code"
|
||||
mkdir -p "external_code/debug_only/binary"
|
||||
mkdir -p "external_code/release_only/source_code"
|
||||
mkdir -p "external_code/release_only/binary"
|
||||
mkdir -p "build_output"
|
||||
mkdir -p "intermediate_code"
|
||||
mkdir -p "shmake_config"
|
||||
mkdir -p "shmake_config/shmake_cache"
|
||||
|
||||
for resource in $ENABLED_RESOURCES; do
|
||||
mkdir -p "resources/$resource"
|
||||
done
|
||||
|
||||
if [ "$LICENSE_CHOICE" != "29" ]; then
|
||||
process_license "$PROJECT_NAME" "$LICENSE" || { printf "Error: License processing failed.\n"; exit 1; }
|
||||
else
|
||||
printf "Custom license selected. Creating stub...\n"
|
||||
cat > "LICENSE" << EOF
|
||||
$LICENSE License
|
||||
|
||||
Copyright (c) $(date +%Y) $PROJECT_NAME
|
||||
|
||||
Permission is hereby granted...
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$TEST_LIB" != "None" ] && [ "$TEST_LIB" != "none" ]; then
|
||||
clone_test_library "$TEST_LIB" || printf "Note: Test library may need manual installation.\n"
|
||||
fi
|
||||
|
||||
printf "Creating files...\n"
|
||||
|
||||
cat > "shmake_config/project.conf" << EOF
|
||||
PROJECT_NAME=$PROJECT_NAME
|
||||
COMPILER=$COMPILER
|
||||
C_VERSION=$C_VERSION
|
||||
TEST_LIB=$TEST_LIB
|
||||
LICENSE=$LICENSE
|
||||
VCS=$VCS
|
||||
VERSION=$VERSION
|
||||
ENABLED_RESOURCES=$ENABLED_RESOURCES
|
||||
ENABLED_TARGETS=$ENABLED_TARGETS
|
||||
EOF
|
||||
|
||||
cat > "README.md" << EOF
|
||||
# $PROJECT_NAME
|
||||
|
||||
A C project built with **shmake**.
|
||||
|
||||
## Requirements
|
||||
- C Compiler: $COMPILER
|
||||
- C Standard: $C_VERSION Support
|
||||
- Test Library: $TEST_LIB
|
||||
|
||||
## License
|
||||
$LICENSE
|
||||
|
||||
## Build
|
||||
Run \`shmake sync\` to generate Makefile configs, then \`make\` to build.
|
||||
|
||||
## Build Modes
|
||||
- \`make\` (Default: Release)
|
||||
- \`make BUILD_MODE=debug\`
|
||||
- \`make BUILD_MODE=test\`
|
||||
|
||||
## Version
|
||||
$VERSION
|
||||
|
||||
## Resources
|
||||
$(for res in $ENABLED_RESOURCES; do printf "- %s\n" "$res"; done)
|
||||
EOF
|
||||
|
||||
case "$VCS" in
|
||||
git)
|
||||
cat > ".gitignore" << EOF
|
||||
build_output/
|
||||
intermediate_code/
|
||||
external_code/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
shmake_config/
|
||||
EOF
|
||||
;;
|
||||
hg)
|
||||
cat > ".hgignore" << EOF
|
||||
syntax: glob
|
||||
build_output/
|
||||
intermediate_code/
|
||||
external_code/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
shmake_config/
|
||||
EOF
|
||||
;;
|
||||
svn)
|
||||
cat > ".svnignore" << EOF
|
||||
build_output
|
||||
intermediate_code
|
||||
external_code
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
shmake_config
|
||||
EOF
|
||||
;;
|
||||
*)
|
||||
cat > ".gitignore" << EOF
|
||||
build_output/
|
||||
intermediate_code/
|
||||
external_code/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
shmake_config/
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
cat > "source_code/main.c" << EOF
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
printf("Hello, %s!\\n", "$PROJECT_NAME");
|
||||
printf("Version: %s\\n", "$VERSION");
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
for conf in makefile.conf makefile_test.conf makefile_debug.conf makefile_release.conf makefile_clean.conf; do
|
||||
printf "# %s - Initialized by shmake\n" "$conf" > "shmake_config/$conf"
|
||||
done
|
||||
|
||||
cat > "shmake_config/linked.conf" << 'EOF'
|
||||
# --- shmake Linked Libraries Configuration ---
|
||||
# Format: library names (automatically converted to -l flags)
|
||||
# Example: LINKED_LIBS = -lX11 -lpthread -lm
|
||||
LINKED_LIBS =
|
||||
EOF
|
||||
|
||||
cat > "Makefile" << 'EOF'
|
||||
# Generated by shmake init
|
||||
# Run 'shmake sync' to populate build configurations.
|
||||
# Portable: Works on GNU Make, bmake, BSD Make (macOS)
|
||||
|
||||
include shmake_config/makefile.conf
|
||||
|
||||
PROJECT_NAME = $(PROJECT_NAME)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
@echo "Please run 'shmake sync' to generate build rules."
|
||||
@echo "Then run 'make' to build."
|
||||
|
||||
clean:
|
||||
rm -rf build_output intermediate_code
|
||||
EOF
|
||||
|
||||
printf "\nProject '%s' initialized successfully!\n" "$PROJECT_NAME"
|
||||
printf " Version: %s\n" "$VERSION"
|
||||
printf " Build Targets: %s\n" "$ENABLED_TARGETS"
|
||||
printf " Resources: %s\n" "$ENABLED_RESOURCES"
|
||||
printf " License: %s\n" "$LICENSE"
|
||||
printf " Test Library: %s\n" "$TEST_LIB"
|
||||
[ "$TEST_LIB" != "None" ] && [ "$TEST_LIB" != "none" ] && printf " Test Library Location: external_code/test_only/source_code/\n"
|
||||
printf " Next steps:\n"
|
||||
printf " 1. Add your source files to source_code/\n"
|
||||
printf " 2. Run 'shmake sync' to generate Makefile build rules\n"
|
||||
printf " 3. Run 'make' to build\n"
|
||||
printf " 4. Use 'make BUILD_MODE=test' for test builds\n"
|
||||
printf " 5. Use 'shmake link X11 pthread m' to add linked libraries\n"
|
||||
|
||||
# Return to parent directory
|
||||
cd ..
|
||||
}
|
||||
62
source_code/shmake_link_library.sh
Normal file
62
source_code/shmake_link_library.sh
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_link.sh - Linked library configuration for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
add_linked_library()
|
||||
{
|
||||
check_project_root
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
printf "Usage: %s link [library_names]\n" "$SCRIPT_NAME"
|
||||
printf "Example: %s link X11 pthread m\n" "$SCRIPT_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LIB_NAMES="$*"
|
||||
|
||||
LIB_FLAGS=""
|
||||
for lib in $LIB_NAMES; do
|
||||
if [ -z "$LIB_FLAGS" ]; then
|
||||
LIB_FLAGS="-l$lib"
|
||||
else
|
||||
LIB_FLAGS="$LIB_FLAGS -l$lib"
|
||||
fi
|
||||
done
|
||||
|
||||
printf "Adding linked libraries: %s\n" "$LIB_FLAGS"
|
||||
|
||||
mkdir -p "shmake_config"
|
||||
|
||||
if [ -f "shmake_config/linked.conf" ]; then
|
||||
printf "Note: 'linked.conf' already exists.\n"
|
||||
printf "Current linked libraries:\n"
|
||||
cat "shmake_config/linked.conf"
|
||||
printf "\nAppend? [y/N]: "
|
||||
read -r append_choice
|
||||
case "$append_choice" in
|
||||
y|Y)
|
||||
old_libs=$(grep '^LINKED_LIBS' "shmake_config/linked.conf" | sed 's/^LINKED_LIBS = //')
|
||||
new_libs="$old_libs $LIB_FLAGS"
|
||||
sed -i '/^LINKED_LIBS/d' "shmake_config/linked.conf"
|
||||
printf "LINKED_LIBS = %s\n" "$new_libs" >> "shmake_config/linked.conf"
|
||||
printf "Linked libraries appended successfully!\n"
|
||||
;;
|
||||
*)
|
||||
sed -i '/^LINKED_LIBS/d' "shmake_config/linked.conf"
|
||||
printf "LINKED_LIBS = %s\n" "$LIB_FLAGS" >> "shmake_config/linked.conf"
|
||||
printf "Linked libraries overwritten successfully!\n"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
cat > "shmake_config/linked.conf" << EOF
|
||||
# --- shmake Linked Libraries Configuration ---
|
||||
# Format: library names (automatically converted to -l flags)
|
||||
# Example: LINKED_LIBS = -lX11 -lpthread -lm
|
||||
LINKED_LIBS = $LIB_FLAGS
|
||||
EOF
|
||||
printf "Linked libraries configured successfully!\n"
|
||||
fi
|
||||
|
||||
printf "\nRun 'shmake sync' to update Makefile with these libraries.\n"
|
||||
}
|
||||
67
source_code/shmake_process_license.sh
Normal file
67
source_code/shmake_process_license.sh
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_license.sh - License processing for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
process_license()
|
||||
{
|
||||
project_name="$1"
|
||||
license_name="$2"
|
||||
|
||||
script_dir=$(get_script_dir)
|
||||
licenses_dir="$script_dir/licenses"
|
||||
|
||||
printf "Processing license: %s...\n" "$license_name"
|
||||
|
||||
if [ ! -d "$licenses_dir" ]; then
|
||||
printf "Error: Licenses directory not found at '%s'.\n" "$licenses_dir"
|
||||
printf "Ensure 'shmake' is installed with its 'licenses' folder alongside it.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$licenses_dir/$license_name" ]; then
|
||||
printf "Warning: License file '%s' not found in script directory. Creating stub.\n" "$license_name"
|
||||
cat > "LICENSE" << EOF
|
||||
$license_name License
|
||||
|
||||
Copyright (c) $(date +%Y) $project_name
|
||||
|
||||
Permission is hereby granted... (See full text for $license_name)
|
||||
EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
cp "$licenses_dir/$license_name" "LICENSE"
|
||||
|
||||
printf "\nEnter your name (for copyright): "
|
||||
read -r user_name
|
||||
[ -z "$user_name" ] && user_name="Your Name"
|
||||
|
||||
printf "Enter organization (optional, press Enter to skip): "
|
||||
read -r user_org
|
||||
[ -z "$user_org" ] && user_org="None"
|
||||
|
||||
printf "Enter project start year: "
|
||||
read -r project_year
|
||||
[ -z "$project_year" ] && project_year=$(date +%Y)
|
||||
|
||||
current_year=$(date +%Y)
|
||||
|
||||
escaped_name=$(printf "%s" "$user_name" | sed 's/[&/\]/\\&/g')
|
||||
escaped_org=$(printf "%s" "$user_org" | sed 's/[&/\]/\\&/g')
|
||||
|
||||
tmp_file=$(mktemp)
|
||||
|
||||
sed \
|
||||
-e "s|(name)|$escaped_name|g" \
|
||||
-e "s|(year)|$current_year|g" \
|
||||
-e "s|(year1)|$project_year|g" \
|
||||
-e "s|(year2)|$current_year|g" \
|
||||
-e "s|(project_name)|$project_name|g" \
|
||||
-e "s|(org)|$escaped_org|g" \
|
||||
"LICENSE" > "$tmp_file"
|
||||
|
||||
mv "$tmp_file" "LICENSE"
|
||||
|
||||
printf "License '%s' applied successfully!\n" "$license_name"
|
||||
}
|
||||
276
source_code/shmake_sync_makefile.sh
Normal file
276
source_code/shmake_sync_makefile.sh
Normal file
@@ -0,0 +1,276 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_sync_makefile.sh - Project synchronization for shmake
|
||||
# Target: bmake with .POSIX: compatibility
|
||||
|
||||
sync_project()
|
||||
{
|
||||
printf "Syncing project files...\n"
|
||||
|
||||
SOURCE_FILES_LIST=$(mktemp)
|
||||
SHARED_SOURCE_LIST=$(mktemp)
|
||||
SHARED_BINARY_LIST=$(mktemp)
|
||||
TEST_SOURCE_LIST=$(mktemp)
|
||||
TEST_BINARY_LIST=$(mktemp)
|
||||
DEBUG_SOURCE_LIST=$(mktemp)
|
||||
DEBUG_BINARY_LIST=$(mktemp)
|
||||
RELEASE_SOURCE_LIST=$(mktemp)
|
||||
RELEASE_BINARY_LIST=$(mktemp)
|
||||
INCLUDE_DIRS_LIST=$(mktemp)
|
||||
LINKED_LIBS_LIST=$(mktemp)
|
||||
|
||||
trap 'rm -f "$SOURCE_FILES_LIST" "$SHARED_SOURCE_LIST" "$SHARED_BINARY_LIST" "$TEST_SOURCE_LIST" "$TEST_BINARY_LIST" "$DEBUG_SOURCE_LIST" "$DEBUG_BINARY_LIST" "$RELEASE_SOURCE_LIST" "$RELEASE_BINARY_LIST" "$INCLUDE_DIRS_LIST" "$LINKED_LIBS_LIST"' EXIT
|
||||
|
||||
printf "Scanning source_code/ for source files...\n"
|
||||
[ -d "source_code" ] && find source_code -type f -name '*.c' ! -path '*/internal/*' 2>/dev/null | while read -r f; do
|
||||
printf '%s\n' "$f" >> "$SOURCE_FILES_LIST"
|
||||
done
|
||||
|
||||
printf "Scanning external_code/shared_libraries/ for source files...\n"
|
||||
[ -d "external_code/shared_libraries/source_code" ] && find external_code/shared_libraries/source_code -type f -name '*.c' ! -path '*/internal/*' 2>/dev/null | while read -r f; do
|
||||
case "$f" in
|
||||
*example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
|
||||
*) printf '%s\n' "$f" >> "$SHARED_SOURCE_LIST" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf "Scanning external_code/shared_libraries/binary/ for binary libraries...\n"
|
||||
[ -d "external_code/shared_libraries/binary" ] && find external_code/shared_libraries/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
|
||||
printf '%s\n' "$f" >> "$SHARED_BINARY_LIST"
|
||||
done
|
||||
|
||||
printf "Scanning external_code/test_only/ for source files...\n"
|
||||
[ -d "external_code/test_only/source_code" ] && find external_code/test_only/source_code -type f -name '*.c' ! -path '*/internal/*' 2>/dev/null | while read -r f; do
|
||||
case "$f" in
|
||||
*example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
|
||||
*) printf '%s\n' "$f" >> "$TEST_SOURCE_LIST" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf "Scanning external_code/test_only/binary/ for test libraries...\n"
|
||||
[ -d "external_code/test_only/binary" ] && find external_code/test_only/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
|
||||
printf '%s\n' "$f" >> "$TEST_BINARY_LIST"
|
||||
done
|
||||
|
||||
printf "Scanning external_code/debug_only/ for source files...\n"
|
||||
[ -d "external_code/debug_only/source_code" ] && find external_code/debug_only/source_code -type f -name '*.c' ! -path '*/internal/*' 2>/dev/null | while read -r f; do
|
||||
case "$f" in
|
||||
*example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
|
||||
*) printf '%s\n' "$f" >> "$DEBUG_SOURCE_LIST" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf "Scanning external_code/debug_only/binary/ for debug libraries...\n"
|
||||
[ -d "external_code/debug_only/binary" ] && find external_code/debug_only/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
|
||||
printf '%s\n' "$f" >> "$DEBUG_BINARY_LIST"
|
||||
done
|
||||
|
||||
printf "Scanning external_code/release_only/ for source files...\n"
|
||||
[ -d "external_code/release_only/source_code" ] && find external_code/release_only/source_code -type f -name '*.c' ! -path '*/internal/*' 2>/dev/null | while read -r f; do
|
||||
case "$f" in
|
||||
*example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
|
||||
*) printf '%s\n' "$f" >> "$RELEASE_SOURCE_LIST" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf "Scanning external_code/release_only/binary/ for release libraries...\n"
|
||||
[ -d "external_code/release_only/binary" ] && find external_code/release_only/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
|
||||
printf '%s\n' "$f" >> "$RELEASE_BINARY_LIST"
|
||||
done
|
||||
|
||||
printf "Auto-detecting include directories across entire project...\n"
|
||||
find . -type d ! -path "*/internal/*" ! -path "./.git*" ! -path "./build_output*" ! -path "./intermediate_code*" ! -path "*/examples*" ! -path "*/example*" ! -path "./shmake_config*" 2>/dev/null | while read -r dir; do
|
||||
clean_dir=$(printf "%s" "$dir" | sed 's|^\./||')
|
||||
[ -z "$clean_dir" ] && continue
|
||||
[ "$clean_dir" = "." ] && continue
|
||||
find "$clean_dir" -maxdepth 1 -type f -name '*.h' 2>/dev/null | grep -q . && printf '%s\n' "$clean_dir" >> "$INCLUDE_DIRS_LIST"
|
||||
done
|
||||
|
||||
printf "Reading linked libraries from shmake_config/linked.conf...\n"
|
||||
[ -f "shmake_config/linked.conf" ] && grep '^LINKED_LIBS' "shmake_config/linked.conf" | sed 's/^LINKED_LIBS[[:space:]]*=[[:space:]]*//' | while read -r line; do
|
||||
printf '%s\n' "$line" >> "$LINKED_LIBS_LIST"
|
||||
done
|
||||
|
||||
printf "Sorting and deduplicating file lists...\n"
|
||||
for list in "$SOURCE_FILES_LIST" "$SHARED_SOURCE_LIST" "$SHARED_BINARY_LIST" \
|
||||
"$TEST_SOURCE_LIST" "$TEST_BINARY_LIST" "$DEBUG_SOURCE_LIST" \
|
||||
"$DEBUG_BINARY_LIST" "$RELEASE_SOURCE_LIST" "$RELEASE_BINARY_LIST" \
|
||||
"$INCLUDE_DIRS_LIST" "$LINKED_LIBS_LIST"; do
|
||||
sort -u "$list" -o "$list"
|
||||
done
|
||||
|
||||
printf "Reading project configuration...\n"
|
||||
if [ -f "shmake_config/project.conf" ]; then
|
||||
C_VERSION_RAW=$(grep -E '^C_VERSION[[:space:]]*=' "shmake_config/project.conf" | sed 's/^.*=[[:space:]]*//' | tr -d '"'\' | tr '[:upper:]' '[:lower:]')
|
||||
fi
|
||||
C_VERSION_LOWER=${C_VERSION_RAW:-c11}
|
||||
|
||||
[ ! -f "shmake_config/linked.conf" ] && touch "shmake_config/linked.conf"
|
||||
|
||||
write_objects_and_rules() {
|
||||
_list_file="$1"
|
||||
_prefix="$2"
|
||||
_conf_file="$3"
|
||||
|
||||
printf '%s_OBJECTS = \\\n' "$_prefix" >> "$_conf_file"
|
||||
while IFS= read -r file; do
|
||||
[ -z "$file" ] && continue
|
||||
obj="intermediate_code/${file%%.c}.o"
|
||||
printf ' %s \\\n' "$obj" >> "$_conf_file"
|
||||
done < "$_list_file"
|
||||
printf '\n' >> "$_conf_file"
|
||||
|
||||
while IFS= read -r file; do
|
||||
[ -z "$file" ] && continue
|
||||
obj="intermediate_code/${file%%.c}.o"
|
||||
dir_path=$(dirname "$obj")
|
||||
printf '%s: %s\n' "$obj" "$file" >> "$_conf_file"
|
||||
printf '\t@mkdir -p %s\n' "$dir_path" >> "$_conf_file"
|
||||
printf '\t$(CC) $(CFLAGS) -c %s -o %s\n\n' "$file" "$obj" >> "$_conf_file"
|
||||
done < "$_list_file"
|
||||
}
|
||||
|
||||
printf "Generating makefile.conf...\n"
|
||||
cat > "shmake_config/makefile.conf" << 'CONF_HEADER'
|
||||
# --- shmake Base Configuration (Always Included) ---
|
||||
CONF_HEADER
|
||||
printf 'CFLAGS += -std=%s\n' "$C_VERSION_LOWER" >> "shmake_config/makefile.conf"
|
||||
printf 'INCLUDE_DIRS = \\\n' >> "shmake_config/makefile.conf"
|
||||
while IFS= read -r dir; do
|
||||
[ -n "$dir" ] && printf ' -I%s \\\n' "$dir" >> "shmake_config/makefile.conf"
|
||||
done < "$INCLUDE_DIRS_LIST"
|
||||
printf '\nCFLAGS += $(INCLUDE_DIRS)\n\n' >> "shmake_config/makefile.conf"
|
||||
|
||||
printf 'SHARED_LIBS = \\\n' >> "shmake_config/makefile.conf"
|
||||
while IFS= read -r file; do
|
||||
[ -n "$file" ] && printf ' %s \\\n' "$file" >> "shmake_config/makefile.conf"
|
||||
done < "$SHARED_BINARY_LIST"
|
||||
printf '\n' >> "shmake_config/makefile.conf"
|
||||
|
||||
write_objects_and_rules "$SOURCE_FILES_LIST" "PROJECT" "shmake_config/makefile.conf"
|
||||
write_objects_and_rules "$SHARED_SOURCE_LIST" "SHARED" "shmake_config/makefile.conf"
|
||||
|
||||
printf "Generating makefile_test.conf...\n"
|
||||
cat > "shmake_config/makefile_test.conf" << 'CONF_HEADER'
|
||||
# --- shmake Test Configuration ---
|
||||
CONF_HEADER
|
||||
printf 'TEST_LIBS = \\\n' >> "shmake_config/makefile_test.conf"
|
||||
while IFS= read -r file; do
|
||||
[ -n "$file" ] && printf ' %s \\\n' "$file" >> "shmake_config/makefile_test.conf"
|
||||
done < "$TEST_BINARY_LIST"
|
||||
printf '\n' >> "shmake_config/makefile_test.conf"
|
||||
write_objects_and_rules "$TEST_SOURCE_LIST" "TEST" "shmake_config/makefile_test.conf"
|
||||
|
||||
printf "Generating makefile_debug.conf...\n"
|
||||
cat > "shmake_config/makefile_debug.conf" << 'CONF_HEADER'
|
||||
# --- shmake Debug Configuration ---
|
||||
CONF_HEADER
|
||||
printf 'DEBUG_LIBS = \\\n' >> "shmake_config/makefile_debug.conf"
|
||||
while IFS= read -r file; do
|
||||
[ -n "$file" ] && printf ' %s \\\n' "$file" >> "shmake_config/makefile_debug.conf"
|
||||
done < "$DEBUG_BINARY_LIST"
|
||||
printf '\n' >> "shmake_config/makefile_debug.conf"
|
||||
printf 'CFLAGS += -g -O0 -DDEBUG\n\n' >> "shmake_config/makefile_debug.conf"
|
||||
write_objects_and_rules "$DEBUG_SOURCE_LIST" "DEBUG" "shmake_config/makefile_debug.conf"
|
||||
|
||||
printf "Generating makefile_release.conf...\n"
|
||||
cat > "shmake_config/makefile_release.conf" << 'CONF_HEADER'
|
||||
# --- shmake Release Configuration ---
|
||||
CONF_HEADER
|
||||
printf 'RELEASE_LIBS = \\\n' >> "shmake_config/makefile_release.conf"
|
||||
while IFS= read -r file; do
|
||||
[ -n "$file" ] && printf ' %s \\\n' "$file" >> "shmake_config/makefile_release.conf"
|
||||
done < "$RELEASE_BINARY_LIST"
|
||||
printf '\n' >> "shmake_config/makefile_release.conf"
|
||||
printf 'CFLAGS += -O2 -DNDEBUG\n\n' >> "shmake_config/makefile_release.conf"
|
||||
write_objects_and_rules "$RELEASE_SOURCE_LIST" "RELEASE" "shmake_config/makefile_release.conf"
|
||||
|
||||
printf "Generating makefile_clean.conf...\n"
|
||||
cat > "shmake_config/makefile_clean.conf" << 'CONF_HEADER'
|
||||
# --- shmake Clean Configuration ---
|
||||
CLEAN_TARGETS = build_output
|
||||
EXTRA_CLEAN = intermediate_code
|
||||
CONF_HEADER
|
||||
|
||||
printf "Updating Root Makefile...\n"
|
||||
cat > "Makefile" << 'MAKEFILE_TEMPLATE'
|
||||
# --- shmake Root Makefile ---
|
||||
# Portable: Works on bmake in .POSIX: mode
|
||||
|
||||
.POSIX:
|
||||
|
||||
PROJECT_NAME ?= a.out
|
||||
.include "shmake_config/project.conf"
|
||||
.include "shmake_config/makefile.conf"
|
||||
|
||||
.include "shmake_config/linked.conf"
|
||||
|
||||
.if !defined(BUILD_MODE)
|
||||
BUILD_MODE = release
|
||||
.endif
|
||||
|
||||
.if "${BUILD_MODE}" == "test"
|
||||
.include "shmake_config/makefile_test.conf"
|
||||
ALL_MODE_OBJECTS = ${PROJECT_OBJECTS} ${SHARED_OBJECTS} ${TEST_OBJECTS}
|
||||
ALL_MODE_LIBS = ${SHARED_LIBS} ${LINKED_LIBS} ${TEST_LIBS}
|
||||
.endif
|
||||
|
||||
.if "${BUILD_MODE}" == "debug"
|
||||
.include "shmake_config/makefile_debug.conf"
|
||||
ALL_MODE_OBJECTS = ${PROJECT_OBJECTS} ${SHARED_OBJECTS} ${DEBUG_OBJECTS}
|
||||
ALL_MODE_LIBS = ${SHARED_LIBS} ${LINKED_LIBS} ${DEBUG_LIBS}
|
||||
.endif
|
||||
|
||||
.if "${BUILD_MODE}" == "release"
|
||||
.include "shmake_config/makefile_release.conf"
|
||||
ALL_MODE_OBJECTS = ${PROJECT_OBJECTS} ${SHARED_OBJECTS} ${RELEASE_OBJECTS}
|
||||
ALL_MODE_LIBS = ${SHARED_LIBS} ${LINKED_LIBS} ${RELEASE_LIBS}
|
||||
.endif
|
||||
|
||||
ALL_OBJECTS = ${ALL_MODE_OBJECTS}
|
||||
ALL_LIBS = ${ALL_MODE_LIBS}
|
||||
|
||||
OUTPUT_DIR = build_output
|
||||
OBJ_DIR = intermediate_code
|
||||
CC ?= gcc
|
||||
|
||||
.PHONY: all debug test release clean distclean
|
||||
|
||||
all:
|
||||
@if [ "${BUILD_MODE}" = "debug" ]; then \
|
||||
${MAKE} debug; \
|
||||
elif [ "${BUILD_MODE}" = "test" ]; then \
|
||||
${MAKE} test; \
|
||||
else \
|
||||
${MAKE} release; \
|
||||
fi
|
||||
|
||||
debug: ${OUTPUT_DIR}/${PROJECT_NAME}-debug
|
||||
|
||||
test: ${OUTPUT_DIR}/${PROJECT_NAME}-test
|
||||
|
||||
release: ${OUTPUT_DIR}/${PROJECT_NAME}
|
||||
|
||||
${OUTPUT_DIR}/${PROJECT_NAME}-debug: ${ALL_OBJECTS}
|
||||
@mkdir -p ${OUTPUT_DIR}
|
||||
${CC} ${CFLAGS} -o $@ ${ALL_OBJECTS} ${ALL_LIBS}
|
||||
|
||||
${OUTPUT_DIR}/${PROJECT_NAME}-test: ${ALL_OBJECTS}
|
||||
@mkdir -p ${OUTPUT_DIR}
|
||||
${CC} ${CFLAGS} -o $@ ${ALL_OBJECTS} ${ALL_LIBS}
|
||||
|
||||
${OUTPUT_DIR}/${PROJECT_NAME}: ${ALL_OBJECTS}
|
||||
@mkdir -p ${OUTPUT_DIR}
|
||||
${CC} ${CFLAGS} -o $@ ${ALL_OBJECTS} ${ALL_LIBS}
|
||||
|
||||
.include "shmake_config/makefile_clean.conf"
|
||||
|
||||
clean:
|
||||
rm -rf ${CLEAN_TARGETS} ${EXTRA_CLEAN}
|
||||
|
||||
distclean: clean
|
||||
rm -rf ${OBJ_DIR} ${OUTPUT_DIR}
|
||||
MAKEFILE_TEMPLATE
|
||||
|
||||
printf "\nSync complete!\n"
|
||||
}
|
||||
65
source_code/shmake_utils.sh
Normal file
65
source_code/shmake_utils.sh
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shmake_utils.sh - Utility functions for shmake
|
||||
# Author: Emilia Marigold
|
||||
|
||||
#=========================================================================================
|
||||
# Get script directory (POSIX-compliant)
|
||||
#=========================================================================================
|
||||
get_script_dir()
|
||||
{
|
||||
script_path="$0"
|
||||
|
||||
case "$script_path" in
|
||||
*/*) ;;
|
||||
*)
|
||||
resolved=$(command -v "$0" 2>/dev/null)
|
||||
if [ -n "$resolved" ]; then
|
||||
script_path="$resolved"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$script_path" in
|
||||
/*) ;;
|
||||
*) script_path="$(pwd)/$script_path" ;;
|
||||
esac
|
||||
|
||||
printf "%s" "$(cd "$(dirname "$script_path")" && pwd)"
|
||||
}
|
||||
|
||||
#=========================================================================================
|
||||
# Safe input reading for POSIX sh
|
||||
#=========================================================================================
|
||||
read_input()
|
||||
{
|
||||
prompt="$1"
|
||||
default="$2"
|
||||
variable_name="$3"
|
||||
|
||||
if [ -n "$default" ]; then
|
||||
printf "%s [%s]: " "$prompt" "$default"
|
||||
else
|
||||
printf "%s: " "$prompt"
|
||||
fi
|
||||
|
||||
read -r input_val
|
||||
|
||||
if [ -z "$input_val" ]; then
|
||||
input_val="$default"
|
||||
fi
|
||||
|
||||
eval "$variable_name='$input_val'"
|
||||
}
|
||||
|
||||
#=========================================================================================
|
||||
# Check if running from project root
|
||||
#=========================================================================================
|
||||
check_project_root()
|
||||
{
|
||||
if [ ! -f "shmake_config/project.conf" ]; then
|
||||
printf "Error: Not in a shmake project directory.\n"
|
||||
printf "Run 'shmake init' first or cd into your project folder.\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user