-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
215 lines (183 loc) · 6.34 KB
/
Makefile
File metadata and controls
215 lines (183 loc) · 6.34 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# Copyright 2024 archspec_cpp contributors
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
#
# Cross-platform Makefile for archspec_cpp
# Supports: Linux, macOS, FreeBSD, Windows (with MinGW or MSVC via nmake)
# Detect OS
ifeq ($(OS),Windows_NT)
UNAME := Windows
else
UNAME := $(shell uname -s)
endif
# Compiler settings
CXX ?= g++
AR ?= ar
# Base flags (no exceptions/RTTI for smaller binaries)
CXXFLAGS ?= -std=c++17 -Wall -Wextra -Werror -O2 -fno-exceptions -fno-rtti -DJSON_NOEXCEPTION
INCLUDES = -I./include -I./extern/json/single_include
# Platform-specific settings
ifeq ($(UNAME),Darwin)
# macOS
LDFLAGS ?=
SHARED_EXT = .dylib
SHARED_FLAGS = -dynamiclib
STATIC_EXT = .a
else ifeq ($(UNAME),Linux)
# Linux
LDFLAGS ?= -ldl
SHARED_EXT = .so
SHARED_FLAGS = -shared -fPIC
STATIC_EXT = .a
else ifeq ($(UNAME),FreeBSD)
# FreeBSD
LDFLAGS ?=
SHARED_EXT = .so
SHARED_FLAGS = -shared -fPIC
STATIC_EXT = .a
else ifeq ($(UNAME),Windows)
# Windows (native or cmd.exe)
LDFLAGS ?=
SHARED_EXT = .dll
SHARED_FLAGS = -shared
STATIC_EXT = .a
EXE_EXT = .exe
else ifneq (,$(findstring MINGW,$(UNAME)))
# MinGW (MSYS2 MINGW64/MINGW32 environment)
LDFLAGS ?=
SHARED_EXT = .dll
SHARED_FLAGS = -shared
STATIC_EXT = .a
EXE_EXT = .exe
else ifneq (,$(findstring MSYS,$(UNAME)))
# MSYS2 MSYS environment
LDFLAGS ?=
SHARED_EXT = .dll
SHARED_FLAGS = -shared
STATIC_EXT = .a
EXE_EXT = .exe
else ifneq (,$(findstring CYGWIN,$(UNAME)))
# Cygwin
LDFLAGS ?=
SHARED_EXT = .dll
SHARED_FLAGS = -shared
STATIC_EXT = .a
EXE_EXT = .exe
else
# Unknown Unix-like (fallback to Linux-like settings)
LDFLAGS ?=
SHARED_EXT = .so
SHARED_FLAGS = -shared -fPIC
STATIC_EXT = .a
endif
# Directories
SRCDIR = src
INCDIR = include
TESTDIR = tests
EXAMPLEDIR = examples
BUILDDIR = build
OBJDIR = $(BUILDDIR)/obj
LIBDIR = $(BUILDDIR)/lib
BINDIR = $(BUILDDIR)/bin
# Source files
SOURCES = $(SRCDIR)/cpuid.cpp $(SRCDIR)/microarchitecture.cpp $(SRCDIR)/detect.cpp $(SRCDIR)/archspec_c.cpp $(SRCDIR)/llvm_compat.cpp
OBJECTS = $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SOURCES))
# Library names
LIB_NAME = archspec
STATIC_LIB = $(LIBDIR)/lib$(LIB_NAME)$(STATIC_EXT)
# Test sources
TEST_SOURCES = $(wildcard $(TESTDIR)/*.cpp)
TEST_BINARIES = $(patsubst $(TESTDIR)/%.cpp,$(BINDIR)/%$(EXE_EXT),$(TEST_SOURCES))
# Example sources
EXAMPLE_SOURCES = $(wildcard $(EXAMPLEDIR)/*.cpp)
EXAMPLE_BINARIES = $(patsubst $(EXAMPLEDIR)/%.cpp,$(BINDIR)/%$(EXE_EXT),$(EXAMPLE_SOURCES))
# Default target
all: directories $(STATIC_LIB) examples tests
# Create directories
directories:
@mkdir -p $(OBJDIR) $(LIBDIR) $(BINDIR)
# Compile source files
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
# Build static library
$(STATIC_LIB): $(OBJECTS)
$(AR) rcs $@ $^
# Build examples
examples: $(EXAMPLE_BINARIES) $(BINDIR)/c_api_example$(EXE_EXT)
$(BINDIR)/%$(EXE_EXT): $(EXAMPLEDIR)/%.cpp $(STATIC_LIB)
$(CXX) $(CXXFLAGS) $(INCLUDES) $< -L$(LIBDIR) -l$(LIB_NAME) $(LDFLAGS) -o $@
# C example - compile as C, link with C++ runtime
$(BINDIR)/c_api_example$(EXE_EXT): $(EXAMPLEDIR)/c_api_example.c $(STATIC_LIB)
$(CC) -Wall -Wextra -Werror -O2 $(INCLUDES) -c $< -o $(OBJDIR)/c_api_example.o
$(CXX) $(OBJDIR)/c_api_example.o -L$(LIBDIR) -l$(LIB_NAME) $(LDFLAGS) -o $@
# Build tests
tests: $(TEST_BINARIES)
$(BINDIR)/%$(EXE_EXT): $(TESTDIR)/%.cpp $(STATIC_LIB)
$(CXX) $(CXXFLAGS) $(INCLUDES) $< -L$(LIBDIR) -l$(LIB_NAME) $(LDFLAGS) -o $@
# Run tests
check: tests
@echo "Running tests..."
@for test in $(TEST_BINARIES); do \
echo "Running $$test..."; \
$$test || exit 1; \
done
@echo "All tests passed!"
# Run examples
run-examples: examples
@echo "Running examples..."
@for example in $(EXAMPLE_BINARIES); do \
echo "=== Running $$example ==="; \
$$example; \
echo ""; \
done
# Clean
clean:
rm -rf $(BUILDDIR)
# Install (optional, for system-wide installation)
PREFIX ?= /usr/local
install: $(STATIC_LIB)
mkdir -p $(PREFIX)/lib $(PREFIX)/include/archspec
cp $(STATIC_LIB) $(PREFIX)/lib/
cp -r $(INCDIR)/archspec/* $(PREFIX)/include/archspec/
# Uninstall
uninstall:
rm -f $(PREFIX)/lib/lib$(LIB_NAME)$(STATIC_EXT)
rm -rf $(PREFIX)/include/archspec
# Debug build
debug: CXXFLAGS += -g -DDEBUG
debug: all
# Generate compile_commands.json for IDE support
compile_commands: clean
@which bear > /dev/null || (echo "bear not installed, skipping" && exit 0)
bear -- $(MAKE) all
# Path to archspec JSON data (from submodule)
ARCHSPEC_JSON_DIR = extern/archspec/archspec/json/cpu
# Regenerate embedded JSON data (convenience target)
regenerate-data:
@echo "Regenerating embedded JSON data from archspec submodule..."
@echo '// Auto-generated embedded JSON data - DO NOT EDIT' > $(SRCDIR)/microarchitectures_data.inc
@echo '// Generated from $(ARCHSPEC_JSON_DIR)/microarchitectures.json' >> $(SRCDIR)/microarchitectures_data.inc
@echo '//' >> $(SRCDIR)/microarchitectures_data.inc
@echo '// To regenerate: make regenerate-data' >> $(SRCDIR)/microarchitectures_data.inc
@echo '' >> $(SRCDIR)/microarchitectures_data.inc
@echo '#ifndef ARCHSPEC_MICROARCHITECTURES_DATA_INC' >> $(SRCDIR)/microarchitectures_data.inc
@echo '#define ARCHSPEC_MICROARCHITECTURES_DATA_INC' >> $(SRCDIR)/microarchitectures_data.inc
@echo '' >> $(SRCDIR)/microarchitectures_data.inc
@echo 'static const char* MICROARCHITECTURES_JSON = R"JSON_DATA(' >> $(SRCDIR)/microarchitectures_data.inc
@cat $(ARCHSPEC_JSON_DIR)/microarchitectures.json >> $(SRCDIR)/microarchitectures_data.inc
@echo ')JSON_DATA";' >> $(SRCDIR)/microarchitectures_data.inc
@echo '' >> $(SRCDIR)/microarchitectures_data.inc
@echo '#endif // ARCHSPEC_MICROARCHITECTURES_DATA_INC' >> $(SRCDIR)/microarchitectures_data.inc
@echo "Done!"
# Source files for formatting
FORMAT_SOURCES = $(shell find src include examples tests \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.c' \) 2>/dev/null)
# Format source code
format:
@echo "Formatting source files..."
@for f in $(FORMAT_SOURCES); do clang-format -i "$$f"; done
@echo "Done!"
# Check formatting (for CI)
format-check:
@echo "Checking format..."
@for f in $(FORMAT_SOURCES); do clang-format --dry-run --Werror "$$f" || exit 1; done
@echo "Format OK!"
.PHONY: all directories examples tests check run-examples clean install uninstall debug compile_commands regenerate-data format format-check