Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
136 lines (106 loc) · 5.73 KB
/
Copy pathMakefile
File metadata and controls
136 lines (106 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# Root Makefile — Multi-Language Keyword Extraction & Benchmarking Suite
# ── Directories ────────────────────────────────────────────────
CPP_DIR = cpp
MD_YAML_DIR = $(CPP_DIR)/md_to_yaml
KW_EXT_DIR = $(CPP_DIR)/keyword_extractor
PYTHON_DIR = python
NOTEBOOKS_DIR = notebooks
BUILD_DIR = build
INPUT_DIR = data/input
OUTPUT_DIR = data/output
# ── Compiler settings ──────────────────────────────────────────
CXX = clang++-10
CXXFLAGS = -Wall -Wextra -O2 -std=c++20 -fPIC
# Standalone md_to_yaml flags & libraries (uses md4c & yaml-cpp)
MD_YAML_INC = -I$(MD_YAML_DIR)/include $(shell pkg-config --cflags yaml-cpp md4c 2>/dev/null)
MD_YAML_LIBS = $(shell pkg-config --libs yaml-cpp md4c 2>/dev/null || echo "-lyaml-cpp -lmd4c")
# Standalone keyword_extractor flags (zero dependency on md_to_yaml / md4c / yaml-cpp)
KW_EXT_INC = -I$(KW_EXT_DIR)/include
PYBIND_INCLUDES = $(shell python3 -m pybind11 --includes)
PY_EXT = .so
# ── Build Artifacts ────────────────────────────────────────────
MD_YAML_LIB = $(BUILD_DIR)/lib/libmdtoyaml.a
MD_YAML_BIN = $(BUILD_DIR)/bin/md_to_yaml
KW_EXT_LIB = $(BUILD_DIR)/lib/libkeyword_extractor.a
PYBIND_SO = $(PYTHON_DIR)/analytics/keyword_extractor_cpp$(PY_EXT)
MD_YAML_SRCS = $(MD_YAML_DIR)/src/document.cpp \
$(MD_YAML_DIR)/src/md_reader.cpp \
$(MD_YAML_DIR)/src/yaml_writer.cpp
MD_YAML_OBJS = $(patsubst $(MD_YAML_DIR)/src/%.cpp, $(BUILD_DIR)/md_to_yaml/%.o, $(MD_YAML_SRCS))
MD_MAIN_OBJ = $(BUILD_DIR)/md_to_yaml/main.o
KW_EXT_SRCS = $(KW_EXT_DIR)/src/tokenizer.cpp \
$(KW_EXT_DIR)/src/statistical.cpp \
$(KW_EXT_DIR)/src/graph_rank.cpp
KW_EXT_OBJS = $(patsubst $(KW_EXT_DIR)/src/%.cpp, $(BUILD_DIR)/keyword_extractor/%.o, $(KW_EXT_SRCS))
PYBIND_OBJ = $(BUILD_DIR)/keyword_extractor/pybind_module.o
# ── Python Environment ─────────────────────────────────────────
VENV = .venv
PYTHON = $(VENV)/bin/python3
PIP = $(VENV)/bin/pip
export PYTHONPATH := $(CURDIR)/$(PYTHON_DIR)
# ── Default target ─────────────────────────────────────────────
all: md_to_yaml bindings parse
# ── C++ Component 1: Standalone Markdown -> YAML Parser ────────
md_to_yaml: $(MD_YAML_LIB) $(MD_YAML_BIN)
$(MD_YAML_LIB): $(MD_YAML_OBJS)
@mkdir -p $(dir $@)
ar rcs $@ $^
$(MD_YAML_BIN): $(MD_MAIN_OBJ) $(MD_YAML_LIB)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -o $@ $(MD_MAIN_OBJ) $(MD_YAML_LIB) $(MD_YAML_LIBS)
$(BUILD_DIR)/md_to_yaml/%.o: $(MD_YAML_DIR)/src/%.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(MD_YAML_INC) -c $< -o $@
# ── C++ Component 2: Standalone Keyword Extractor & Bindings ───
keyword_extractor: $(KW_EXT_LIB)
$(KW_EXT_LIB): $(KW_EXT_OBJS)
@mkdir -p $(dir $@)
ar rcs $@ $^
bindings: $(PYBIND_SO)
$(PYBIND_SO): $(PYBIND_OBJ) $(KW_EXT_LIB)
$(CXX) $(CXXFLAGS) -shared $(PYBIND_OBJ) $(KW_EXT_LIB) -o $@
$(BUILD_DIR)/keyword_extractor/%.o: $(KW_EXT_DIR)/src/%.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(KW_EXT_INC) -c $< -o $@
$(PYBIND_OBJ): $(KW_EXT_DIR)/bindings/pybind_module.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(KW_EXT_INC) $(PYBIND_INCLUDES) -c $< -o $@
# ── Document Parsing (Markdown -> YAML) ────────────────────────
parse: $(MD_YAML_BIN)
@mkdir -p $(OUTPUT_DIR)
@for f in $(wildcard $(INPUT_DIR)/*.md); do \
./$(MD_YAML_BIN) $$f $(OUTPUT_DIR); \
done
@echo "All Markdown files parsed to $(OUTPUT_DIR)/."
# ── Python Virtualenv & Editable Package Install ───────────────
$(VENV)/bin/activate:
python3 -m venv $(VENV) --without-pip
curl -sS https://bootstrap.pypa.io/pip/3.9/get-pip.py | $(VENV)/bin/python3
$(PIP) install matplotlib seaborn pandas numpy scipy networkx pyyaml nbformat jupyter nbconvert
$(PIP) install --no-build-isolation --no-deps -e $(PYTHON_DIR)
venv: $(VENV)/bin/activate
$(PIP) install --no-build-isolation --no-deps -e $(PYTHON_DIR)
@echo "Virtual environment ready: $(VENV)/"
# ── Analytics Pipeline & Notebooks ─────────────────────────────
analysis: bindings $(VENV)/bin/activate
@mkdir -p $(OUTPUT_DIR)/charts
$(PYTHON) -m analytics.cli
notebooks: bindings $(VENV)/bin/activate
@mkdir -p $(OUTPUT_DIR)/notebooks
cd $(NOTEBOOKS_DIR) && for nb in *.ipynb; do \
PYTHONPATH=$(CURDIR)/$(PYTHON_DIR) $(CURDIR)/$(PYTHON) -m nbconvert --to html --execute $$nb --output-dir $(CURDIR)/$(OUTPUT_DIR)/notebooks; \
done
notebook: bindings $(VENV)/bin/activate
cd $(NOTEBOOKS_DIR) && PYTHONPATH=$(CURDIR)/$(PYTHON_DIR) $(CURDIR)/$(PYTHON) -m jupyter notebook
# ── Cleanup ────────────────────────────────────────────────────
clean:
rm -rf $(BUILD_DIR)
clean-py:
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true
find . -type d -name .ipynb_checkpoints -exec rm -rf {} + 2>/dev/null || true
rm -f $(PYBIND_SO)
clean-data:
rm -rf $(OUTPUT_DIR)/charts $(OUTPUT_DIR)/notebooks $(OUTPUT_DIR)/*.yaml $(OUTPUT_DIR)/*_report.md
clean-all: clean clean-py clean-data
.PHONY: all md_to_yaml keyword_extractor bindings parse venv analysis notebooks notebook clean clean-py clean-data clean-all