diff --git a/CMakeLists.txt b/CMakeLists.txt index 22b6711b5..f6a66daa3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,14 +76,25 @@ option(LLAMA_BUILD_EXAMPLES "llama: build examples" ${LLAMA_STANDALONE}) # Build info header # -# Generate build-info.h initially +# Write header template to binary dir to keep source directory clean +file(WRITE "${CMAKE_BINARY_DIR}/BUILD_INFO.h.in" "\ +#ifndef BUILD_INFO_H\n\ +#define BUILD_INFO_H\n\ +\n\ +#define BUILD_NUMBER @BUILD_NUMBER@\n\ +#define BUILD_COMMIT \"@BUILD_COMMIT@\"\n\ +\n\ +#endif // BUILD_INFO_H\n\ +") + +# Generate initial build-info.h include(${CMAKE_CURRENT_SOURCE_DIR}/scripts/build-info.cmake) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") - # Add a custom target to regenerate build-info.h when .git/index changes + # Add a custom target for build-info.h add_custom_target(BUILD_INFO ALL DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/build-info.h") - # Add a custom command to generate build-info.h when .git/index changes + # Add a custom command to rebuild build-info.h when .git/index changes add_custom_command( OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/build-info.h" COMMENT "Generating build details from Git" diff --git a/Makefile b/Makefile index c0296c73b..6ebc3c5b9 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,6 @@ endif CCV := $(shell $(CC) --version | head -n 1) CXXV := $(shell $(CXX) --version | head -n 1) -GIT_INDEX = $(wildcard .git/index) - # Mac OS + Arm can report x86_64 # ref: https://github.com/ggerganov/whisper.cpp/issues/66#issuecomment-1282546789 ifeq ($(UNAME_S),Darwin) @@ -183,77 +181,56 @@ llama.o: llama.cpp ggml.h ggml-cuda.h llama.h llama-util.h common.o: examples/common.cpp examples/common.h $(CXX) $(CXXFLAGS) -c $< -o $@ -clean: - rm -vf *.o main quantize quantize-stats perplexity embedding benchmark-matmult build-info.h +libllama.so: llama.o ggml.o $(OBJS) + $(CXX) $(CXXFLAGS) -shared -fPIC -o $@ $^ $(LDFLAGS) -build-info.h: $(GIT_INDEX) - scripts/build-info.sh > $@ +clean: + rm -vf *.o main quantize quantize-stats perplexity embedding benchmark-matmult save-load-state build-info.h # # Examples # -TARGETS_CPP += main -DEPS_main := examples/main/main.cpp ggml.o llama.o common.o -EXEC_main :=\ -@echo;\ -echo "==== Run ./main -h for help. ====";\ -echo +main: examples/main/main.cpp build-info.h ggml.o llama.o common.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) + @echo + @echo '==== Run ./main -h for help. ====' + @echo -TARGETS_CPP += quantize -DEPS_quantize := examples/quantize/quantize.cpp ggml.o llama.o +quantize: examples/quantize/quantize.cpp build-info.h ggml.o llama.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) -TARGETS_CPP += quantize-stats -DEPS_quantize-stats := examples/quantize-stats/quantize-stats.cpp ggml.o llama.o +quantize-stats: examples/quantize-stats/quantize-stats.cpp build-info.h ggml.o llama.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) -TARGETS_CPP += perplexity -DEPS_perplexity := examples/perplexity/perplexity.cpp ggml.o llama.o common.o +perplexity: examples/perplexity/perplexity.cpp build-info.h ggml.o llama.o common.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) -TARGETS_CPP += embedding -DEPS_embedding := examples/embedding/embedding.cpp ggml.o llama.o common.o +embedding: examples/embedding/embedding.cpp build-info.h ggml.o llama.o common.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) -TARGETS_CPP += save-load-state -DEPS_save-load-state := examples/save-load-state/save-load-state.cpp ggml.o llama.o common.o +save-load-state: examples/save-load-state/save-load-state.cpp build-info.h ggml.o llama.o common.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) -TARGETS_CPP += vdot -DEPS_vdot := pocs/vdot/vdot.cpp ggml.o - -# -# libllama -# - -libllama.so: llama.o ggml.o $(OBJS) - $(CXX) $(CXXFLAGS) -shared -fPIC -o $@ $^ $(LDFLAGS) +build-info.h: $(wildcard .git/index) scripts/build-info.sh + @scripts/build-info.sh > $@.tmp + @if ! cmp -s $@.tmp $@; then \ + mv $@.tmp $@; \ + else \ + rm $@.tmp; \ + fi # # Tests # -TARGETS_CPP += benchmark -DEPS_benchmark := examples/benchmark/benchmark-matmult.cpp build-info.h ggml.o $(OBJS) -OUTP_benchmark := benchmark-matmult -EXEC_benchmark := ./benchmark-matmult +benchmark-matmult: examples/benchmark/benchmark-matmult.cpp build-info.h ggml.o $(OBJS) + $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LDFLAGS) + ./$@ + +vdot: pocs/vdot/vdot.cpp ggml.o $(OBJS) + $(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) .PHONY: tests tests: bash ./tests/run-tests.sh - -# -# Templates -# - -# C++ template -# To use this template: -# 1. Add your target to the TARGETS variable: TARGETS_CPP += target -# 2. Set target-specific dependencies: DEPS_target := source1 dependency1 dependency2 ... -# 3. Optionally, set target-specific output: OUTP_target := output_name -# 4. Optionally, set target-specific command: EXEC_target := command -define template_cpp -OUTP_$(1) ?= $(1) -$(1): $$(DEPS_$(1)) $$(OBJS) build-info.h - $$(CXX) $$(CXXFLAGS) $$(filter-out build-info.h,$$^) -o $$(OUTP_$(1)) $$(LDFLAGS) - $$(if $$(value EXEC_$(1)),$$(EXEC_$(1))) -endef - -# This iterates through TARGETS_CPP and call the template for each target -$(foreach target,$(TARGETS_CPP),$(eval $(call template_cpp,$(target)))) diff --git a/examples/benchmark/CMakeLists.txt b/examples/benchmark/CMakeLists.txt index 05deebcd1..037696194 100644 --- a/examples/benchmark/CMakeLists.txt +++ b/examples/benchmark/CMakeLists.txt @@ -2,3 +2,6 @@ set(TARGET benchmark) add_executable(${TARGET} benchmark-matmult.cpp) target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT}) target_compile_features(${TARGET} PRIVATE cxx_std_11) +if(TARGET BUILD_INFO) + add_dependencies(${TARGET} BUILD_INFO) +endif() diff --git a/examples/embedding/CMakeLists.txt b/examples/embedding/CMakeLists.txt index 88c425d4a..db73b6b44 100644 --- a/examples/embedding/CMakeLists.txt +++ b/examples/embedding/CMakeLists.txt @@ -2,3 +2,6 @@ set(TARGET embedding) add_executable(${TARGET} embedding.cpp) target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT}) target_compile_features(${TARGET} PRIVATE cxx_std_11) +if(TARGET BUILD_INFO) + add_dependencies(${TARGET} BUILD_INFO) +endif() diff --git a/examples/perplexity/CMakeLists.txt b/examples/perplexity/CMakeLists.txt index 5836df8b2..61b17b828 100644 --- a/examples/perplexity/CMakeLists.txt +++ b/examples/perplexity/CMakeLists.txt @@ -2,3 +2,6 @@ set(TARGET perplexity) add_executable(${TARGET} perplexity.cpp) target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT}) target_compile_features(${TARGET} PRIVATE cxx_std_11) +if(TARGET BUILD_INFO) + add_dependencies(${TARGET} BUILD_INFO) +endif() diff --git a/examples/quantize/CMakeLists.txt b/examples/quantize/CMakeLists.txt index fb27d4517..475fc8be8 100644 --- a/examples/quantize/CMakeLists.txt +++ b/examples/quantize/CMakeLists.txt @@ -2,3 +2,6 @@ set(TARGET quantize) add_executable(${TARGET} quantize.cpp) target_link_libraries(${TARGET} PRIVATE llama ${CMAKE_THREAD_LIBS_INIT}) target_compile_features(${TARGET} PRIVATE cxx_std_11) +if(TARGET BUILD_INFO) + add_dependencies(${TARGET} BUILD_INFO) +endif() diff --git a/examples/save-load-state/CMakeLists.txt b/examples/save-load-state/CMakeLists.txt index cff79fa1f..08dbe5c2b 100644 --- a/examples/save-load-state/CMakeLists.txt +++ b/examples/save-load-state/CMakeLists.txt @@ -2,3 +2,6 @@ set(TARGET save-load-state) add_executable(${TARGET} save-load-state.cpp) target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT}) target_compile_features(${TARGET} PRIVATE cxx_std_11) +if(TARGET BUILD_INFO) + add_dependencies(${TARGET} BUILD_INFO) +endif() diff --git a/scripts/build-info.cmake b/scripts/build-info.cmake index 592808708..fb46ed2b5 100644 --- a/scripts/build-info.cmake +++ b/scripts/build-info.cmake @@ -1,6 +1,9 @@ -set(HEAD "unknown") -set(COUNT 0) +set(TEMPLATE_FILE "${CMAKE_BINARY_DIR}/BUILD_INFO.h.in") +set(HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/build-info.h") +set(BUILD_NUMBER 0) +set(BUILD_COMMIT "unknown") +# Look for git find_package(Git) if(NOT Git_FOUND) execute_process( @@ -16,33 +19,35 @@ if(NOT Git_FOUND) endif() endif() +# Get the commit count and hash if(Git_FOUND) execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE TEMP_HEAD + OUTPUT_VARIABLE HEAD OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE GIT_HEAD_RESULT ) execute_process( COMMAND ${GIT_EXECUTABLE} rev-list --count HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE TEMP_COUNT + OUTPUT_VARIABLE COUNT OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE GIT_COUNT_RESULT ) if(GIT_HEAD_RESULT EQUAL 0 AND GIT_COUNT_RESULT EQUAL 0) - set(HEAD ${TEMP_HEAD}) - set(COUNT ${TEMP_COUNT}) + set(BUILD_COMMIT ${HEAD}) + set(BUILD_NUMBER ${COUNT}) endif() endif() -file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/build-info.h" "\ -#ifndef BUILD_INFO_H\n\ -#define BUILD_INFO_H\n\ -\n\ -#define BUILD_NUMBER ${COUNT}\n\ -#define BUILD_COMMIT \"${HEAD}\"\n\ -\n\ -#endif // BUILD_INFO_H\n\ -") +# Only write the header if it's changed to prevent unnecessary recompilation +if(EXISTS ${HEADER_FILE}) + file(STRINGS ${HEADER_FILE} CONTENTS REGEX "BUILD_COMMIT \"([^\"]*)\"") + list(GET CONTENTS 0 EXISTING) + if(NOT EXISTING STREQUAL "#define BUILD_COMMIT \"${BUILD_COMMIT}\"") + configure_file(${TEMPLATE_FILE} ${HEADER_FILE}) + endif() +else() + configure_file(${TEMPLATE_FILE} ${HEADER_FILE}) +endif() diff --git a/scripts/build-info.sh b/scripts/build-info.sh index d6083ffb4..507d7e153 100755 --- a/scripts/build-info.sh +++ b/scripts/build-info.sh @@ -3,12 +3,12 @@ BUILD_NUMBER="0" BUILD_COMMIT="unknown" -REV_LIST=$(git rev-list HEAD --count) +REV_LIST=$(git rev-list --count HEAD) if [ $? -eq 0 ]; then BUILD_NUMBER=$REV_LIST fi -REV_PARSE=$(git rev-parse HEAD) +REV_PARSE=$(git rev-parse --short HEAD) if [ $? -eq 0 ]; then BUILD_COMMIT=$REV_PARSE fi