|
| 1 | +# Copyright 2024 archspec_cpp contributors |
| 2 | +# SPDX-License-Identifier: (Apache-2.0 OR MIT) |
| 3 | +# |
| 4 | +# Cross-platform Makefile for archspec_cpp |
| 5 | +# Supports: Linux, macOS, FreeBSD, Windows (with MinGW or MSVC via nmake) |
| 6 | + |
| 7 | +# Detect OS |
| 8 | +ifeq ($(OS),Windows_NT) |
| 9 | + UNAME := Windows |
| 10 | +else |
| 11 | + UNAME := $(shell uname -s) |
| 12 | +endif |
| 13 | + |
| 14 | +# Compiler settings |
| 15 | +CXX ?= g++ |
| 16 | +AR ?= ar |
| 17 | + |
| 18 | +# Base flags |
| 19 | +CXXFLAGS ?= -std=c++17 -Wall -Wextra -O2 |
| 20 | +INCLUDES = -I./include -I./extern/json/single_include |
| 21 | + |
| 22 | +# Platform-specific settings |
| 23 | +ifeq ($(UNAME),Darwin) |
| 24 | + # macOS |
| 25 | + LDFLAGS ?= |
| 26 | + SHARED_EXT = .dylib |
| 27 | + SHARED_FLAGS = -dynamiclib |
| 28 | + STATIC_EXT = .a |
| 29 | +else ifeq ($(UNAME),Linux) |
| 30 | + # Linux |
| 31 | + LDFLAGS ?= -ldl |
| 32 | + SHARED_EXT = .so |
| 33 | + SHARED_FLAGS = -shared -fPIC |
| 34 | + STATIC_EXT = .a |
| 35 | +else ifeq ($(UNAME),FreeBSD) |
| 36 | + # FreeBSD |
| 37 | + LDFLAGS ?= |
| 38 | + SHARED_EXT = .so |
| 39 | + SHARED_FLAGS = -shared -fPIC |
| 40 | + STATIC_EXT = .a |
| 41 | +else ifeq ($(UNAME),Windows) |
| 42 | + # Windows (MinGW) |
| 43 | + LDFLAGS ?= |
| 44 | + SHARED_EXT = .dll |
| 45 | + SHARED_FLAGS = -shared |
| 46 | + STATIC_EXT = .a |
| 47 | + EXE_EXT = .exe |
| 48 | +endif |
| 49 | + |
| 50 | +# Directories |
| 51 | +SRCDIR = src |
| 52 | +INCDIR = include |
| 53 | +TESTDIR = tests |
| 54 | +EXAMPLEDIR = examples |
| 55 | +BUILDDIR = build |
| 56 | +OBJDIR = $(BUILDDIR)/obj |
| 57 | +LIBDIR = $(BUILDDIR)/lib |
| 58 | +BINDIR = $(BUILDDIR)/bin |
| 59 | + |
| 60 | +# Source files |
| 61 | +SOURCES = $(SRCDIR)/cpuid.cpp $(SRCDIR)/microarchitecture.cpp $(SRCDIR)/detect.cpp $(SRCDIR)/archspec_c.cpp |
| 62 | +OBJECTS = $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SOURCES)) |
| 63 | + |
| 64 | +# Library names |
| 65 | +LIB_NAME = archspec |
| 66 | +STATIC_LIB = $(LIBDIR)/lib$(LIB_NAME)$(STATIC_EXT) |
| 67 | + |
| 68 | +# Test sources |
| 69 | +TEST_SOURCES = $(wildcard $(TESTDIR)/*.cpp) |
| 70 | +TEST_BINARIES = $(patsubst $(TESTDIR)/%.cpp,$(BINDIR)/%$(EXE_EXT),$(TEST_SOURCES)) |
| 71 | + |
| 72 | +# Example sources |
| 73 | +EXAMPLE_SOURCES = $(wildcard $(EXAMPLEDIR)/*.cpp) |
| 74 | +EXAMPLE_BINARIES = $(patsubst $(EXAMPLEDIR)/%.cpp,$(BINDIR)/%$(EXE_EXT),$(EXAMPLE_SOURCES)) |
| 75 | + |
| 76 | +# Default target |
| 77 | +all: directories $(STATIC_LIB) examples tests |
| 78 | + |
| 79 | +# Create directories |
| 80 | +directories: |
| 81 | + @mkdir -p $(OBJDIR) $(LIBDIR) $(BINDIR) |
| 82 | + |
| 83 | +# Compile source files |
| 84 | +$(OBJDIR)/%.o: $(SRCDIR)/%.cpp |
| 85 | + $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ |
| 86 | + |
| 87 | +# Build static library |
| 88 | +$(STATIC_LIB): $(OBJECTS) |
| 89 | + $(AR) rcs $@ $^ |
| 90 | + |
| 91 | +# Build examples |
| 92 | +examples: $(EXAMPLE_BINARIES) $(BINDIR)/c_api_example$(EXE_EXT) |
| 93 | + |
| 94 | +$(BINDIR)/%$(EXE_EXT): $(EXAMPLEDIR)/%.cpp $(STATIC_LIB) |
| 95 | + $(CXX) $(CXXFLAGS) $(INCLUDES) $< -L$(LIBDIR) -l$(LIB_NAME) $(LDFLAGS) -o $@ |
| 96 | + |
| 97 | +# C example needs special handling (link with C++ runtime) |
| 98 | +$(BINDIR)/c_api_example$(EXE_EXT): $(EXAMPLEDIR)/c_api_example.c $(STATIC_LIB) |
| 99 | + $(CXX) $(CXXFLAGS) $(INCLUDES) $< -L$(LIBDIR) -l$(LIB_NAME) $(LDFLAGS) -o $@ |
| 100 | + |
| 101 | +# Build tests |
| 102 | +tests: $(TEST_BINARIES) |
| 103 | + |
| 104 | +$(BINDIR)/%$(EXE_EXT): $(TESTDIR)/%.cpp $(STATIC_LIB) |
| 105 | + $(CXX) $(CXXFLAGS) $(INCLUDES) $< -L$(LIBDIR) -l$(LIB_NAME) $(LDFLAGS) -o $@ |
| 106 | + |
| 107 | +# Run tests |
| 108 | +check: tests |
| 109 | + @echo "Running tests..." |
| 110 | + @for test in $(TEST_BINARIES); do \ |
| 111 | + echo "Running $$test..."; \ |
| 112 | + $$test || exit 1; \ |
| 113 | + done |
| 114 | + @echo "All tests passed!" |
| 115 | + |
| 116 | +# Run examples |
| 117 | +run-examples: examples |
| 118 | + @echo "Running examples..." |
| 119 | + @for example in $(EXAMPLE_BINARIES); do \ |
| 120 | + echo "=== Running $$example ==="; \ |
| 121 | + $$example; \ |
| 122 | + echo ""; \ |
| 123 | + done |
| 124 | + |
| 125 | +# Clean |
| 126 | +clean: |
| 127 | + rm -rf $(BUILDDIR) |
| 128 | + |
| 129 | +# Install (optional, for system-wide installation) |
| 130 | +PREFIX ?= /usr/local |
| 131 | +install: $(STATIC_LIB) |
| 132 | + mkdir -p $(PREFIX)/lib $(PREFIX)/include/archspec |
| 133 | + cp $(STATIC_LIB) $(PREFIX)/lib/ |
| 134 | + cp -r $(INCDIR)/archspec/* $(PREFIX)/include/archspec/ |
| 135 | + |
| 136 | +# Uninstall |
| 137 | +uninstall: |
| 138 | + rm -f $(PREFIX)/lib/lib$(LIB_NAME)$(STATIC_EXT) |
| 139 | + rm -rf $(PREFIX)/include/archspec |
| 140 | + |
| 141 | +# Debug build |
| 142 | +debug: CXXFLAGS += -g -DDEBUG |
| 143 | +debug: all |
| 144 | + |
| 145 | +# Generate compile_commands.json for IDE support |
| 146 | +compile_commands: clean |
| 147 | + @which bear > /dev/null || (echo "bear not installed, skipping" && exit 0) |
| 148 | + bear -- $(MAKE) all |
| 149 | + |
| 150 | +# Path to archspec JSON data (from submodule) |
| 151 | +ARCHSPEC_JSON_DIR = extern/archspec/archspec/json/cpu |
| 152 | + |
| 153 | +# Regenerate embedded JSON data (convenience target) |
| 154 | +regenerate-data: |
| 155 | + @echo "Regenerating embedded JSON data from archspec submodule..." |
| 156 | + @echo '// Auto-generated embedded JSON data - DO NOT EDIT' > $(SRCDIR)/microarchitectures_data.inc |
| 157 | + @echo '// Generated from $(ARCHSPEC_JSON_DIR)/microarchitectures.json' >> $(SRCDIR)/microarchitectures_data.inc |
| 158 | + @echo '//' >> $(SRCDIR)/microarchitectures_data.inc |
| 159 | + @echo '// To regenerate: make regenerate-data' >> $(SRCDIR)/microarchitectures_data.inc |
| 160 | + @echo '' >> $(SRCDIR)/microarchitectures_data.inc |
| 161 | + @echo '#ifndef ARCHSPEC_MICROARCHITECTURES_DATA_INC' >> $(SRCDIR)/microarchitectures_data.inc |
| 162 | + @echo '#define ARCHSPEC_MICROARCHITECTURES_DATA_INC' >> $(SRCDIR)/microarchitectures_data.inc |
| 163 | + @echo '' >> $(SRCDIR)/microarchitectures_data.inc |
| 164 | + @echo 'static const char* MICROARCHITECTURES_JSON = R"JSON_DATA(' >> $(SRCDIR)/microarchitectures_data.inc |
| 165 | + @cat $(ARCHSPEC_JSON_DIR)/microarchitectures.json >> $(SRCDIR)/microarchitectures_data.inc |
| 166 | + @echo ')JSON_DATA";' >> $(SRCDIR)/microarchitectures_data.inc |
| 167 | + @echo '' >> $(SRCDIR)/microarchitectures_data.inc |
| 168 | + @echo '#endif // ARCHSPEC_MICROARCHITECTURES_DATA_INC' >> $(SRCDIR)/microarchitectures_data.inc |
| 169 | + @echo "Done!" |
| 170 | + |
| 171 | +.PHONY: all directories examples tests check run-examples clean install uninstall debug compile_commands regenerate-data |
| 172 | + |
0 commit comments