feat(build): add build instructions in README and convert sources to .c.md format
- Add detailed build and bootstrap instructions to README.md. - Convert all source and header files from .c/.h to .c.md/.h.md. - Add bootstrap.sh script for automated building across version history. - Update Makefile and sources.mk to reflect new markdown-based source organization.
This commit is contained in:
parent
2cf16ff109
commit
80f7a1b9b6
28 changed files with 236 additions and 31 deletions
42
Makefile
42
Makefile
|
|
@ -1,32 +1,48 @@
|
|||
NAME = c-md
|
||||
VERSION = 1.0.0
|
||||
TEST_BIN= c-md.test
|
||||
|
||||
VERSION = 2.0.0
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
TEST_BIN= c-md.test
|
||||
CMD = ./$(NAME)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
include sources.mk
|
||||
|
||||
CC = clang
|
||||
CPPFLAGS = -std=c99 -I includes
|
||||
CPPFLAGS = -std=c99
|
||||
CFLAGS = -Wall -Wextra -Werror -pipe
|
||||
LDFLAGS =
|
||||
TEST_LDFLAGS = -lcriterion
|
||||
|
||||
BUILD_DIR = .build
|
||||
OBJ_DIR = $(BUILD_DIR)/objs
|
||||
MAP_DIR = $(BUILD_DIR)/maps
|
||||
|
||||
OBJ_DIR = .build
|
||||
GEN_SRCS = $(MD_SRCS:$(SRC_DIR)/%.c.md=$(BUILD_DIR)/srcs/%.c)
|
||||
GEN_HDRS = $(MD_HDRS:$(INC_DIR)/%.h.md=$(BUILD_DIR)/$(INC_DIR)/%.h)
|
||||
|
||||
OBJS = $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||
OBJS = $(GEN_SRCS:$(BUILD_DIR)/srcs/%.c=$(OBJ_DIR)/%.o)
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
|
||||
.SECONDARY: $(GEN_SRCS) $(GEN_HDRS)
|
||||
|
||||
.PHONY: all
|
||||
all: $(NAME)
|
||||
|
||||
$(NAME): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
$(NAME): $(GEN_HDRS) $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS)
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(BUILD_DIR)/srcs/%.c: $(SRC_DIR)/%.c.md
|
||||
@mkdir -p $(dir $@) $(dir $(MAP_DIR)/$*.map)
|
||||
$(CMD) -i $< -o $@ -m $(MAP_DIR)/$*.map
|
||||
|
||||
$(BUILD_DIR)/$(INC_DIR)/%.h: $(INC_DIR)/%.h.md
|
||||
@mkdir -p $(dir $@) $(dir $(MAP_DIR)/$*.h.map)
|
||||
$(CMD) -e c -i $< -o $@ -m $(MAP_DIR)/$*.h.map
|
||||
|
||||
$(OBJ_DIR)/%.o: $(BUILD_DIR)/srcs/%.c $(GEN_HDRS)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -I $(BUILD_DIR)/$(INC_DIR) -MMD -MP -c $< -o $@
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
|
|
@ -37,13 +53,12 @@ test: $(TEST_BIN)
|
|||
|
||||
$(TEST_BIN): $(TESTS) $(filter-out $(OBJ_DIR)/main.o,$(OBJS))
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(TEST_LDFLAGS) $^ -o $@
|
||||
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -I $(BUILD_DIR)/$(INC_DIR) $(TEST_LDFLAGS) $^ -o $@
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) -r $(OBJ_DIR)
|
||||
$(RM) -r $(BUILD_DIR)
|
||||
|
||||
.PHONY: fclean
|
||||
fclean: clean
|
||||
|
|
@ -53,4 +68,3 @@ fclean: clean
|
|||
.PHONY: re
|
||||
re: fclean
|
||||
$(MAKE) all
|
||||
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -106,6 +106,35 @@ For file `main.c.md` with `-e c`:
|
|||
|
||||
Multiple matching code blocks are concatenated with a blank line separator.
|
||||
|
||||
## Building
|
||||
|
||||
c-md is self-hosted
|
||||
(dogfooding)[https://en.wikipedia.org/wiki/Self-hosting_(compilers)]. The
|
||||
source code is written in `.c.md` format and requires c-md itself to build.
|
||||
|
||||
### First Build (Bootstrap)
|
||||
|
||||
After cloning or after `make fclean`, run the bootstrap script:
|
||||
|
||||
```bash
|
||||
./bootstrap.sh
|
||||
make
|
||||
```
|
||||
|
||||
The bootstrap script builds c-md by traversing major version tags,
|
||||
starting from v1.0.0 (plain C sources) up to the current version.
|
||||
|
||||
### Regular Build
|
||||
|
||||
Once c-md is available:
|
||||
|
||||
```bash
|
||||
make # build from .c.md sources
|
||||
make clean # remove build artifacts
|
||||
make fclean # remove everything including binary
|
||||
make re # rebuild from scratch
|
||||
```
|
||||
|
||||
## Line Mapping
|
||||
|
||||
The transpiler generates `.map` files that track the correspondence between
|
||||
|
|
@ -117,7 +146,7 @@ source lines (`.c.md`) and output lines (`.c`). This enables:
|
|||
|
||||
## Status
|
||||
|
||||
**v1.0.0** - Initial stable release
|
||||
**v2.0.0** - Initial stable release self-hosted.
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
103
bootstrap.sh
Executable file
103
bootstrap.sh
Executable file
|
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env sh
|
||||
# bootstrap.sh - Build c-md by traversing major version tags
|
||||
#
|
||||
# This script builds c-md from scratch by going through each major version
|
||||
# tag in order. Each version is built using the binary from the previous
|
||||
# version, starting from v1.0.0 which uses plain C sources.
|
||||
#
|
||||
# Use this script after a fresh clone or after 'make fclean'.
|
||||
|
||||
set -e
|
||||
|
||||
TMP_BIN="/tmp/c-md-bootstrap-$$"
|
||||
CURRENT=""
|
||||
STASH_NEEDED=0
|
||||
|
||||
cleanup() {
|
||||
# Restore original branch if we switched
|
||||
if [ -n "$CURRENT" ]; then
|
||||
CURRENT_BRANCH=$(git branch --show-current)
|
||||
if [ "$CURRENT_BRANCH" != "$CURRENT" ]; then
|
||||
echo "Restoring original branch..."
|
||||
git switch "$CURRENT" --quiet 2>/dev/null || git checkout "$CURRENT" --quiet 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Restore stashed changes
|
||||
if [ "$STASH_NEEDED" -eq 1 ]; then
|
||||
echo "Restoring stashed changes..."
|
||||
git stash pop --quiet 2>/dev/null || echo "Warning: Could not restore stashed changes"
|
||||
fi
|
||||
|
||||
rm -f "$TMP_BIN"
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
get_highest_major_tags() {
|
||||
git tag -l 'v*' \
|
||||
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
|
||||
| sort -V \
|
||||
| awk -F. '
|
||||
{
|
||||
m=substr($1, 2)+0;
|
||||
tag = $0
|
||||
tags[m] = tag # Overwrite; since input is sorted, last wins (highest)
|
||||
} END {
|
||||
for (m in tags) print tags[m]
|
||||
}' \
|
||||
| sort -V
|
||||
}
|
||||
|
||||
echo "Bootstrapping c-md..."
|
||||
|
||||
CURRENT=$(git branch --show-current)
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "Stashing local changes..."
|
||||
git stash --include-untracked --quiet
|
||||
STASH_NEEDED=1
|
||||
fi
|
||||
|
||||
TAGS=$(get_highest_major_tags)
|
||||
|
||||
if [ -z "$TAGS" ]; then
|
||||
echo "No version tags found. Building current version from C sources..."
|
||||
make --quiet
|
||||
echo "Bootstrap complete. Binary ready at ./c-md"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found major versions: $(echo $TAGS | tr '\n' ' ')"
|
||||
|
||||
for TAG in $TAGS; do
|
||||
echo "Building $TAG..."
|
||||
git switch --detach "$TAG" --quiet
|
||||
|
||||
if [ -f "$TMP_BIN" ]; then
|
||||
cp "$TMP_BIN" ./c-md
|
||||
fi
|
||||
|
||||
make --quiet
|
||||
cp c-md "$TMP_BIN"
|
||||
make fclean --quiet
|
||||
done
|
||||
|
||||
echo "Restoring current branch..."
|
||||
git switch "$CURRENT" --quiet
|
||||
|
||||
if [ "$STASH_NEEDED" -eq 1 ]; then
|
||||
echo "Restoring stashed changes..."
|
||||
git stash pop --quiet
|
||||
STASH_NEEDED=0
|
||||
fi
|
||||
|
||||
echo "Building current version..."
|
||||
cp "$TMP_BIN" ./c-md
|
||||
make --quiet
|
||||
cp c-md "$TMP_BIN"
|
||||
make fclean --quiet
|
||||
mv "$TMP_BIN" ./c-md
|
||||
|
||||
echo ""
|
||||
echo "Bootstrap complete. Binary ready at ./c-md"
|
||||
echo "Run 'make' to rebuild from sources."
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef CLI_H
|
||||
# define CLI_H
|
||||
|
||||
|
|
@ -19,3 +20,4 @@ void
|
|||
cli_print_help(const char *progname);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef MAP_INTERNAL_H
|
||||
# define MAP_INTERNAL_H
|
||||
|
||||
|
|
@ -17,3 +18,4 @@ int8_t
|
|||
write_ranges(FILE *f, t_map *map);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef TRANSPILE_INTERNAL_H
|
||||
# define TRANSPILE_INTERNAL_H
|
||||
|
||||
|
|
@ -35,3 +36,4 @@ int8_t
|
|||
handle_code_line(t_state *s, char *line);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef IO_H
|
||||
# define IO_H
|
||||
|
||||
|
|
@ -17,3 +18,4 @@ void
|
|||
io_close(t_io *io);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef MAP_H
|
||||
# define MAP_H
|
||||
|
||||
|
|
@ -33,3 +34,4 @@ void
|
|||
map_free(t_map *map);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef TRANSPILE_H
|
||||
# define TRANSPILE_H
|
||||
|
||||
|
|
@ -9,3 +10,4 @@ int8_t
|
|||
transpile(FILE *in, FILE *out, const char *ext, t_map *map);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef UTILS_H
|
||||
# define UTILS_H
|
||||
|
||||
|
|
@ -20,3 +21,4 @@ const char *
|
|||
infer_ext_from_filename(const char *path);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#ifndef VALIDATOR_H
|
||||
# define VALIDATOR_H
|
||||
|
||||
|
|
@ -8,3 +9,4 @@ int8_t
|
|||
validator_validate_args(t_args *args);
|
||||
|
||||
#endif
|
||||
```
|
||||
42
sources.mk
42
sources.mk
|
|
@ -1,21 +1,31 @@
|
|||
|
||||
SRC_DIR = srcs
|
||||
SRCS = $(SRC_DIR)/main.c \
|
||||
$(SRC_DIR)/io/streams.c \
|
||||
$(SRC_DIR)/utils/io/read_line.c \
|
||||
$(SRC_DIR)/utils/string/starts_with.c \
|
||||
$(SRC_DIR)/utils/string/extract_fence_ext.c \
|
||||
$(SRC_DIR)/utils/string/extract_file_ext.c \
|
||||
$(SRC_DIR)/utils/string/infer_ext_from_filename.c \
|
||||
$(SRC_DIR)/transpile/state.c \
|
||||
$(SRC_DIR)/transpile/fence.c \
|
||||
$(SRC_DIR)/transpile/code.c \
|
||||
$(SRC_DIR)/transpile/core.c \
|
||||
$(SRC_DIR)/map/core.c \
|
||||
$(SRC_DIR)/map/io.c \
|
||||
$(SRC_DIR)/cli/cli.c \
|
||||
$(SRC_DIR)/cli/help.c \
|
||||
$(SRC_DIR)/validator/validator.c
|
||||
MD_SRCS = $(SRC_DIR)/main.c.md \
|
||||
$(SRC_DIR)/io/streams.c.md \
|
||||
$(SRC_DIR)/utils/io/read_line.c.md \
|
||||
$(SRC_DIR)/utils/string/starts_with.c.md \
|
||||
$(SRC_DIR)/utils/string/extract_fence_ext.c.md \
|
||||
$(SRC_DIR)/utils/string/extract_file_ext.c.md \
|
||||
$(SRC_DIR)/utils/string/infer_ext_from_filename.c.md \
|
||||
$(SRC_DIR)/transpile/state.c.md \
|
||||
$(SRC_DIR)/transpile/fence.c.md \
|
||||
$(SRC_DIR)/transpile/code.c.md \
|
||||
$(SRC_DIR)/transpile/core.c.md \
|
||||
$(SRC_DIR)/map/core.c.md \
|
||||
$(SRC_DIR)/map/io.c.md \
|
||||
$(SRC_DIR)/cli/cli.c.md \
|
||||
$(SRC_DIR)/cli/help.c.md \
|
||||
$(SRC_DIR)/validator/validator.c.md
|
||||
|
||||
INC_DIR = includes
|
||||
MD_HDRS = $(INC_DIR)/cli.h.md \
|
||||
$(INC_DIR)/io.h.md \
|
||||
$(INC_DIR)/map.h.md \
|
||||
$(INC_DIR)/transpile.h.md \
|
||||
$(INC_DIR)/utils.h.md \
|
||||
$(INC_DIR)/validator.h.md \
|
||||
$(INC_DIR)/internal/map_internal.h.md \
|
||||
$(INC_DIR)/internal/transpile_internal.h.md
|
||||
|
||||
TESTS_DIR = tests
|
||||
TESTS = $(TESTS_DIR)/test_integration.c \
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stddef.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
|
|
@ -110,3 +111,4 @@ handle_map(t_args *args, const char *value)
|
|||
{
|
||||
args->map_path = value;
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cli.h"
|
||||
|
|
@ -19,3 +20,4 @@ cli_print_help(const char *progname)
|
|||
fprintf(stderr, " %s -i main.c.md -o main.c\n", progname);
|
||||
fprintf(stderr, " %s -e h -i file.md -o file.h -m file.map\n", progname);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
#include "io.h"
|
||||
|
|
@ -30,3 +31,4 @@ io_close(t_io *io)
|
|||
if (NULL != io->out && io->out != stdout)
|
||||
fclose(io->out);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cli.h"
|
||||
#include "validator.h"
|
||||
|
|
@ -65,3 +67,4 @@ run(t_args *args)
|
|||
io_close(&io);
|
||||
return (ret);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "map.h"
|
||||
|
|
@ -53,3 +54,4 @@ map_grow(t_map *map)
|
|||
map->capacity = new_cap;
|
||||
return (0);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
#include "map.h"
|
||||
|
|
@ -53,3 +54,4 @@ map_write(t_map *map, const char *path, const char *source, const char *target)
|
|||
fclose(f);
|
||||
return (ret);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
#include "internal/transpile_internal.h"
|
||||
|
|
@ -10,3 +11,4 @@ handle_code_line(t_state *s, char *line)
|
|||
s->dst_line++;
|
||||
return (0);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "transpile.h"
|
||||
|
|
@ -36,3 +37,4 @@ transpile(FILE *in, FILE *out, const char *ext, t_map *map)
|
|||
free(line);
|
||||
return (ret);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -48,3 +49,4 @@ handle_fence_close(t_state *s)
|
|||
}
|
||||
return (0);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include "internal/transpile_internal.h"
|
||||
|
||||
void
|
||||
|
|
@ -14,3 +15,4 @@ state_init(t_state *s, FILE *in, FILE *out, const char *ext, t_map *map)
|
|||
s->in_block = 0;
|
||||
s->first_block = 1;
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
@ -22,3 +23,4 @@ read_line(FILE *f)
|
|||
}
|
||||
return (line);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -30,3 +31,4 @@ extract_fence_ext(const char *fence)
|
|||
ext[len] = '\0';
|
||||
return (ext);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
|
@ -12,3 +13,4 @@ extract_file_ext(const char *path)
|
|||
return (NULL);
|
||||
return (dot + 1);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
|
@ -35,3 +36,4 @@ infer_ext_from_filename(const char *path)
|
|||
ext_buffer[ext_len] = '\0';
|
||||
return (ext_buffer);
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -11,3 +12,4 @@ starts_with(const char *str, const char *prefix)
|
|||
prefix_len = strlen(prefix);
|
||||
return (0 == strncmp(str, prefix, prefix_len));
|
||||
}
|
||||
```
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
```c
|
||||
#include <stddef.h>
|
||||
|
||||
#include "validator.h"
|
||||
|
|
@ -20,3 +21,4 @@ validator_validate_args(t_args *args)
|
|||
}
|
||||
return (0);
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Reference in a new issue