### Makefile for loading and using custom extensions Source: https://context7.com/git/make/llms.txt This Makefile demonstrates how to load a shared library extension using the 'load' directive. It shows both direct loading and loading with an explicit setup function. Custom functions defined in the extension are then used to manipulate strings and generate rules dynamically. ```makefile # Load the extension (assumes myextension.so is in current directory) load myextension.so # Or with explicit setup function name load myextension.so(myextension_gmk_setup) # Use custom functions TEXT := hello world REVERSED := $(reverse $(TEXT)) UPPER := $(uppercase $(TEXT)) # Generate rules dynamically $(gen-rule myprogram) # Conditional load (only if extension exists) -load optional_extension.so all: @echo "Original: $(TEXT)" @echo "Reversed: $(REVERSED)" @echo "Uppercase: $(UPPER)" ``` -------------------------------- ### Makefile examples using special built-in variables Source: https://context7.com/git/make/llms.txt This Makefile demonstrates the usage of various special built-in variables in GNU Make. These variables provide information about the Make environment, defined variables, features, include paths, and control Make's behavior like the default goal and recipe prefix. ```makefile # .VARIABLES - All defined variable names $(info Defined variables: $(.VARIABLES)) # .FEATURES - Available features in this version $(info Features: $(.FEATURES)) # May include: archives, check-symlink, else-if, extra-prereqs, # grouped-target, guile, jobserver, load, notintermediate, # oneshell, order-only, output-sync, second-expansion, # shell-export, shortest-stem, target-specific, undefine # .INCLUDE_DIRS - Directories searched for included makefiles $(info Include dirs: $(.INCLUDE_DIRS)) # .DEFAULT_GOAL - The default target .DEFAULT_GOAL := all # .RECIPEPREFIX - Change recipe prefix character (default is TAB) .RECIPEPREFIX := > target: > echo "Using > instead of TAB" # MAKEFILE_LIST - All makefiles read so far THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) # MAKE_VERSION - GNU Make version $(info Using GNU Make $(MAKE_VERSION)) # MAKE_HOST - Host architecture $(info Host: $(MAKE_HOST)) # MAKELEVEL - Recursion depth $(info Recursion level: $(MAKELEVEL)) # MAKEFLAGS - Current command-line options $(info Flags: $(MAKEFLAGS)) # CURDIR - Current working directory $(info Working directory: $(CURDIR)) # .SHELLSTATUS - Exit status of last $(shell) call FILES := $(shell ls *.c 2>/dev/null) $(if $(filter-out 0,$(.SHELLSTATUS)),$(warning ls failed)) ``` -------------------------------- ### Grouped Targets with Single Recipe in Make Source: https://context7.com/git/make/llms.txt This example shows how multiple targets can be updated by a single recipe. The '&' symbol indicates that all listed targets depend on the prerequisites and will be built by the same command. ```makefile # Grouped targets (all updated by single recipe) foo.tab.c foo.tab.h &: foo.y bison -d $< ``` -------------------------------- ### C code for a GNU Make Loadable Extension Source: https://context7.com/git/make/llms.txt This C code defines custom functions (reverse, uppercase, gen-rule) and registers them with GNU Make. It includes a setup function for ABI version checking and function registration. Ensure the 'gnumake.h' header is available during compilation. ```c /* myextension.c - Custom GNU Make extension */ #include #include #include "gnumake.h" /* Required for GPL compatibility check */ int plugin_is_GPL_compatible; /* Custom function: reverse a string */ static char *func_reverse(const char *name, unsigned int argc, char **argv) { (void)name; (void)argc; size_t len = strlen(argv[0]); char *result = gmk_alloc(len + 1); for (size_t i = 0; i < len; i++) { result[i] = argv[0][len - 1 - i]; } result[len] = '\0'; return result; } /* Custom function: uppercase a string */ static char *func_uppercase(const char *name, unsigned int argc, char **argv) { (void)name; (void)argc; size_t len = strlen(argv[0]); char *result = gmk_alloc(len + 1); for (size_t i = 0; i < len; i++) { result[i] = (argv[0][i] >= 'a' && argv[0][i] <= 'z') ? argv[0][i] - 32 : argv[0][i]; } result[len] = '\0'; return result; } /* Custom function: generate makefile rules dynamically */ static char *func_gen_rule(const char *name, unsigned int argc, char **argv) { (void)name; (void)argc; char buffer[1024]; snprintf(buffer, sizeof(buffer), "%s: %s.c\n\t$$(CC) $$(CFLAGS) -o $@ $<" argv[0], argv[0]); gmk_eval(buffer, NULL); return NULL; /* Return NULL for empty expansion */ } /* Setup function called when the object is loaded The function name must be: _gmk_setup */ int myextension_gmk_setup(unsigned int abi_version, const gmk_floc *floc) { (void)floc; /* Check ABI version compatibility */ if (abi_version != GMK_ABI_VERSION) { fprintf(stderr, "ABI version mismatch: expected %d, got %u\n", GMK_ABI_VERSION, abi_version); return 0; /* Failure */ } /* Register custom functions */ gmk_add_function("reverse", func_reverse, 1, 1, GMK_FUNC_DEFAULT); gmk_add_function("uppercase", func_uppercase, 1, 1, GMK_FUNC_DEFAULT); gmk_add_function("gen-rule", func_gen_rule, 1, 1, GMK_FUNC_DEFAULT); return 1; /* Success */ } /* Optional: cleanup function called when object is unloaded */ void myextension_gmk_unload(void) { /* Perform any necessary cleanup */ } ``` -------------------------------- ### Dry Run and Debugging Source: https://context7.com/git/make/llms.txt Preview build commands and inspect internal database or trace execution flow. ```bash # Show commands that would be executed without running them make -n # Print the database of rules and variables make -p # Enable debugging output make -d # Trace target rebuilds with reasons make --trace # Print debug info for specific areas make --debug=verbose,why # Print all targets defined in the makefile make --print-targets ``` -------------------------------- ### Basic Makefile Rules Source: https://context7.com/git/make/llms.txt Define targets, prerequisites, and recipes. Recipes must be indented with a TAB character. ```makefile # Basic rule syntax # target: prerequisites # recipe (must be indented with TAB) program: main.o utils.o gcc -o program main.o utils.o main.o: main.c utils.h gcc -c main.c utils.o: utils.c utils.h gcc -c utils.c # Clean target (phony - not a real file) .PHONY: clean clean: rm -f program *.o ``` -------------------------------- ### Makefile Selection and Directory Source: https://context7.com/git/make/llms.txt Specify custom makefiles or change the working directory before execution. ```bash # Use a specific makefile make -f custom.mk # Change to directory before reading makefiles make -C src/ # Chain directory changes make -C /project -C build # Search for included makefiles in additional directories make -I /usr/local/include/makefiles ``` -------------------------------- ### Basic CLI Invocation Source: https://context7.com/git/make/llms.txt Execute make to build targets defined in the Makefile. ```bash # Build the default target make # Build a specific target make clean # Build multiple targets make all test install ``` -------------------------------- ### Include Directive Source: https://context7.com/git/make/llms.txt Modularize Makefiles by including external configuration files. ```makefile # Include another makefile (error if not found) include config.mk ``` -------------------------------- ### Bash commands to build a shared library extension Source: https://context7.com/git/make/llms.txt These commands show how to compile a C source file into a shared library (.so) compatible with GNU Make extensions on different platforms (Linux, macOS). Adjust the include path if 'gnumake.h' is not in the default system include directories. ```bash # Linux gcc -shared -fPIC -o myextension.so myextension.c # macOS gcc -shared -fPIC -undefined dynamic_lookup -o myextension.so myextension.c # With include path to gnumake.h gcc -shared -fPIC -I/usr/include/gnumake -o myextension.so myextension.c ``` -------------------------------- ### GNU Make Extension API (gnumake.h) Source: https://context7.com/git/make/llms.txt The gnumake.h header defines the interface for dynamic objects, including memory management, evaluation, and custom function registration. ```APIDOC ## C API: gnumake.h ### Description The gnumake.h header provides the necessary structures and function exports to create loadable extensions for GNU Make, enabling custom functions and dynamic behavior. ### Key Structures - **gmk_floc** (struct) - Contains file name and line number for error reporting. ### Functions - **gmk_free(char *str)** - Frees memory allocated by the API. - **gmk_alloc(unsigned int len)** - Allocates memory for use within the make environment. - **gmk_eval(const char *buffer, const gmk_floc *floc)** - Evaluates a string as makefile syntax. - **gmk_expand(const char *str)** - Expands a make variable or function reference. - **gmk_add_function(const char *name, gmk_func_ptr func, unsigned int min_args, unsigned int max_args, unsigned int flags)** - Registers a new custom make function. ### Constants - **GMK_ABI_VERSION** - Current ABI version. - **GMK_FUNC_DEFAULT** - Normal expansion behavior for custom functions. - **GMK_FUNC_NOEXPAND** - Prevents argument expansion before calling the custom function. ``` -------------------------------- ### GNU Make Loadable Object API Header Source: https://context7.com/git/make/llms.txt The gnumake.h header defines the C API for creating loadable extensions for GNU Make. It includes structures for error reporting, function pointers, memory management, and functions for evaluating make syntax and expanding variables. ```c /* gnumake.h - External interfaces for dynamic objects loaded into GNU Make */ #define GMK_ABI_VERSION 1 /* Location information for error reporting */ typedef struct { const char *filenm; unsigned long lineno; } gmk_floc; /* Function pointer type for custom make functions */ typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char **argv); /* Memory management */ GMK_EXPORT void gmk_free(char *str); GMK_EXPORT char *gmk_alloc(unsigned int len); /* Evaluate makefile syntax */ GMK_EXPORT void gmk_eval(const char *buffer, const gmk_floc *floc); /* Expand a make variable/function reference */ GMK_EXPORT char *gmk_expand(const char *str); /* Register a new make function */ GMK_EXPORT void gmk_add_function(const char *name, gmk_func_ptr func, unsigned int min_args, unsigned int max_args, unsigned int flags); #define GMK_FUNC_DEFAULT 0x00 /* Normal expansion behavior */ #define GMK_FUNC_NOEXPAND 0x01 /* Don't expand arguments before calling */ ``` -------------------------------- ### Makefile Variables Source: https://context7.com/git/make/llms.txt Assign values using different expansion rules and shell command execution. ```makefile # Simple assignment (expanded immediately) CC := gcc CFLAGS := -Wall -O2 # Recursive assignment (expanded when used) OBJS = main.o utils.o # Conditional assignment (only if not already set) PREFIX ?= /usr/local # Append to existing variable CFLAGS += -g # Shell assignment (execute shell command) VERSION != git describe --tags 2>/dev/null || echo "unknown" # Use variables with $() or ${} program: $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) ``` -------------------------------- ### Parallel Build Execution Source: https://context7.com/git/make/llms.txt Use the -j flag to run multiple jobs simultaneously, optionally constrained by system load. ```bash # Run 4 jobs in parallel make -j4 # Run jobs based on system load average (start new job only if load < 2.5) make -j8 -l 2.5 # Unlimited parallel jobs (use with caution) make -j # Group output by target during parallel builds make -j4 --output-sync=target ``` -------------------------------- ### Include Directives Source: https://context7.com/git/make/llms.txt Directives for including external files with optional error handling and wildcard expansion. ```makefile # Include if exists (no error if missing) -include local.mk # Include with variable expansion include $(wildcard *.d) ``` -------------------------------- ### Shell and File I/O Functions Source: https://context7.com/git/make/llms.txt Functions for executing shell commands and performing file read/write operations. ```makefile # $(shell command) - Execute shell command GIT_HASH := $(shell git rev-parse --short HEAD) FILE_COUNT := $(shell ls -1 *.c 2>/dev/null | wc -l) # Shell assignment operator (alternative syntax) HOSTNAME != hostname DATE != date +%Y-%m-%d # $(file op filename,text) - Read/write files # Write to file (> creates/truncates, >> appends) $(file >build.log,Build started at $(shell date)) $(file >>build.log,Building $(TARGET)) # Read from file CONFIG := $(file build.log,text)`). ``` -------------------------------- ### Variable Override Source: https://context7.com/git/make/llms.txt Override Makefile variables or set environment behavior via the command line. ```bash # Set variable on command line (overrides makefile value) make CC=clang CFLAGS="-O2 -Wall" # Evaluate makefile syntax before reading makefiles make --eval='EXTRA_CFLAGS := -g' # Give environment variables precedence over makefile make -e ``` -------------------------------- ### Print Warning Message in Make Source: https://context7.com/git/make/llms.txt Use the $(warning text) directive to print a warning message during make execution. This does not abort the build process. ```makefile # $(warning text) - Print warning message $(warning CC is set to $(CC)) ``` -------------------------------- ### Text Manipulation Functions Source: https://context7.com/git/make/llms.txt Functions for string replacement, filtering, sorting, and word counting. ```makefile # $(subst from,to,text) - Replace all occurrences FILES := foo.c bar.c OBJS := $(subst .c,.o,$(FILES)) # Result: foo.o bar.o # $(patsubst pattern,replacement,text) - Pattern substitution SOURCES := src/foo.c src/bar.c OBJECTS := $(patsubst src/%.c,obj/%.o,$(SOURCES)) # Result: obj/foo.o obj/bar.o # $(strip text) - Remove leading/trailing whitespace CLEAN := $(strip hello world ) # Result: hello world # $(findstring find,text) - Find substring HAS_DEBUG := $(findstring -g,$(CFLAGS)) # $(filter pattern,text) - Keep matching words SOURCES := main.c test.h utils.c config.h C_FILES := $(filter %.c,$(SOURCES)) # Result: main.c utils.c # $(filter-out pattern,text) - Remove matching words NON_HEADERS := $(filter-out %.h,$(SOURCES)) # Result: main.c utils.c # $(sort list) - Sort and remove duplicates SORTED := $(sort foo bar baz foo) # Result: bar baz foo # $(word n,text) - Get nth word (1-indexed) THIRD := $(word 3,one two three four) # Result: three # $(wordlist start,end,text) - Get range of words MIDDLE := $(wordlist 2,4,one two three four five) # Result: two three four # $(words text) - Count words COUNT := $(words one two three) # Result: 3 # $(firstword text) / $(lastword text) FIRST := $(firstword one two three) # one LAST := $(lastword one two three) # three ``` -------------------------------- ### Conditional and Loop Functions Source: https://context7.com/git/make/llms.txt Functions for implementing logic, loops, and user-defined function calls. ```APIDOC ## Conditional and Loop Functions ### Description Functions for conditional logic, iteration over lists, and calling user-defined functions. ### Examples - `$(if condition,then-part,else-part)`: Conditional logic. - `$(foreach var,list,text)`: Loop over list. - `$(call function,arg1,arg2,...)`: Call user-defined function. ``` -------------------------------- ### Dynamically Generate Makefile Content with $(eval) Source: https://context7.com/git/make/llms.txt The $(eval text) directive evaluates its argument as makefile syntax, allowing for dynamic generation of rules and variables. This is useful for creating repetitive build rules based on templates. ```makefile # $(eval text) - Evaluate text as makefile syntax define PROGRAM_template $(1): $$($(1)_OBJS) $$(CC) -o $$@ $$^ $(1)_clean: rm -f $(1) $$($(1)_OBJS) endef # Generate rules for each program PROGRAMS := app1 app2 app1_OBJS := main1.o utils.o app2_OBJS := main2.o lib.o $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog)))) ``` -------------------------------- ### Synchronization Point in Make Prerequisites Source: https://context7.com/git/make/llms.txt The .WAIT directive acts as a synchronization point in the prerequisite list, ensuring that all preceding targets are completed before proceeding. This is used to control parallel execution order. ```makefile # .WAIT - Synchronization point in prerequisites all: step1 .WAIT step2 .WAIT step3 ``` -------------------------------- ### Default Recipe for Undefined Targets in Make Source: https://context7.com/git/make/llms.txt The .DEFAULT special target defines the recipe to be used for any target that does not have an explicit rule. It typically echoes the target name. ```makefile # .DEFAULT - Recipe for targets with no rules .DEFAULT: @echo "No rule for target '$@'" ``` -------------------------------- ### Run Prerequisites Serially in Make Source: https://context7.com/git/make/llms.txt Use the .NOTPARALLEL directive to specify that a target and its prerequisites should be built serially, even in a parallel build environment. This is crucial for targets that cannot be safely built concurrently. ```makefile # .NOTPARALLEL - Run prerequisites serially .NOTPARALLEL: database-setup # Alternative: specific target runs serially .NOTPARALLEL: critical-section ``` -------------------------------- ### Conditional Logic Functions Source: https://context7.com/git/make/llms.txt Functions for implementing branching logic and evaluating conditions during variable expansion. ```makefile # $(if condition,then-part,else-part) RESULT := $(if $(DEBUG),Debug mode,Release mode) # $(or condition1,condition2,...) - Return first non-empty COMPILER := $(or $(CC),$(GCC),gcc) # $(and condition1,condition2,...) - Return last if all non-empty VALID := $(and $(CC),$(CFLAGS),$(LDFLAGS)) # $(intcmp lhs,rhs,lt-part,eq-part,gt-part) - Integer comparison STATUS := $(intcmp $(JOBS),4,few,normal,many) ``` -------------------------------- ### Text Manipulation Functions Source: https://context7.com/git/make/llms.txt Functions for string replacement, pattern matching, sorting, and word manipulation. ```APIDOC ## Text Functions ### Description Functions to manipulate text strings, perform pattern substitution, and manage word lists. ### Examples - `$(subst from,to,text)`: Replace all occurrences. - `$(patsubst pattern,replacement,text)`: Pattern substitution. - `$(strip text)`: Remove leading/trailing whitespace. - `$(filter pattern,text)`: Keep matching words. - `$(sort list)`: Sort and remove duplicates. - `$(words text)`: Count words. ``` -------------------------------- ### Makefile Conditionals Source: https://context7.com/git/make/llms.txt Control build logic based on variable definitions or equality checks. ```makefile # Check if variable is defined ifdef DEBUG CFLAGS += -g -DDEBUG else CFLAGS += -O2 endif # Check if variables are equal ifeq ($(CC),gcc) CFLAGS += -Wextra endif # Check if variables are not equal ifneq ($(OS),Windows_NT) LDFLAGS += -lpthread endif # Using conditionals with $(if) RESULT := $(if $(DEBUG),debug build,release build) ``` -------------------------------- ### Declare Non-File Targets in Make Source: https://context7.com/git/make/llms.txt Use the .PHONY directive to declare targets that do not represent actual files. This prevents make from being confused if a file with the same name exists. ```makefile # .PHONY - Declare targets that aren't files .PHONY: all clean install test ``` -------------------------------- ### Print Error and Abort in Make Source: https://context7.com/git/make/llms.txt Use the $(error text) directive to print an error message and abort the make process. This is typically used for undefined variables or critical configuration issues. ```makefile # $(error text) - Print error and abort ifndef REQUIRED_VAR $(error REQUIRED_VAR must be defined) endif ``` -------------------------------- ### Mark Targets as Intermediate in Make Source: https://context7.com/git/make/llms.txt Use the .INTERMEDIATE directive to mark targets that should be deleted after they are successfully built. This helps manage disk space by removing files that are not final outputs. ```makefile # .INTERMEDIATE - Delete after build completes .INTERMEDIATE: parser.c ``` -------------------------------- ### Ignore Recipe Errors in Make Source: https://context7.com/git/make/llms.txt The .IGNORE directive tells make to ignore errors from recipes. If a command fails, make will continue as if it succeeded, which can be useful for optional steps. ```makefile # .IGNORE - Ignore recipe errors .IGNORE: clean ``` -------------------------------- ### Suppress Recipe Echoing in Make Source: https://context7.com/git/make/llms.txt Use the .SILENT directive to prevent make from echoing the commands (recipes) before they are executed. This results in a cleaner output, showing only the actual command output. ```makefile # .SILENT - Don't echo recipes .SILENT: install ``` -------------------------------- ### Enable POSIX Compliance in Make Source: https://context7.com/git/make/llms.txt The .POSIX directive enables POSIX-compliant behavior for make. This affects how the shell is invoked and other aspects of make's operation to adhere to POSIX standards. ```makefile # Enable POSIX mode .POSIX: # After .POSIX, shell invoked with -e flag # and other POSIX-compliant behaviors are enabled ``` -------------------------------- ### Delete Target on Recipe Error in Make Source: https://context7.com/git/make/llms.txt The .DELETE_ON_ERROR directive ensures that if a recipe fails, the target file is deleted. This prevents make from attempting to use a partially built or corrupted file in subsequent steps. ```makefile # .DELETE_ON_ERROR - Delete target if recipe fails .DELETE_ON_ERROR: ``` -------------------------------- ### Mark Targets as Secondary in Make Source: https://context7.com/git/make/llms.txt The .SECONDARY directive marks targets that should not be deleted after use, but can still be treated as intermediate files if necessary. This offers a balance between .PRECIOUS and .INTERMEDIATE. ```makefile # .SECONDARY - Don't delete, but can be intermediate .SECONDARY: generated.h ``` -------------------------------- ### Define Suffix List for Old-Style Rules in Make Source: https://context7.com/git/make/llms.txt The .SUFFIXES directive is used to define or clear the list of known file suffixes for old-style pattern rules. Providing an empty list clears all known suffixes. ```makefile # .SUFFIXES - Define/clear suffix list for old-style rules .SUFFIXES # Clear all suffixes .SUFFIXES: .c .o .h # Define new suffixes ``` -------------------------------- ### Preserve Intermediate Files in Make Source: https://context7.com/git/make/llms.txt The .PRECIOUS special target prevents make from deleting intermediate files, even if the build is interrupted or encounters an error. This is useful for object files (.o) that might be needed later. ```makefile # .PRECIOUS - Don't delete on interrupt or error .PRECIOUS: %.o ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.