File: Makefile.gnu

package info (click to toggle)
linksem 0.8%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 5,376 kB
  • sloc: asm: 9,188; ansic: 5,856; ml: 2,918; yacc: 1,310; lex: 721; sh: 119; makefile: 63
file content (113 lines) | stat: -rw-r--r-- 3,716 bytes parent folder | download | duplicates (2)
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
THIS_MAKEFILE = $(lastword $(MAKEFILE_LIST))
DIRNAME := $(realpath .)
BASENAME := $(shell basename "$(DIRNAME)" | sed 's/-.*//' )
# $(warning BASENAME is $(BASENAME))

OUTPUTS := $(BASENAME) $(BASENAME).map $(BASENAME).cmd $(BASENAME).repeat-cmd $(BASENAME).collect-cmd $(BASENAME).env

OBJECTS ?= $(BASENAME).o

default: $(OUTPUTS) repeat

LDFLAGS ?= -static

# Avoid LTO/plugin cruft in our link commands, for now.
LDFLAGS += -fno-lto

# Avoid relaxation, for now. ARGH: this seems not to prevent all instruction rewriting.
LDFLAGS += -Wl,--no-relax

# Cancel built-in rules -- why?
%: %.c
%: %.cc
%: %.o

.SECONDARY: $(OBJECTS)

# We scrape the actual link command, 
# then produce local copies of all the inputs
# and rewrite the command to use these copies.
$(BASENAME).cmd $(BASENAME).map $(BASENAME): build-$(BASENAME)

# Which compiler we need to use to drive the linker
# depends on the source binary.
ifeq ($(shell basename "$(DIRNAME)" | sed 's/.*c++.*/c++/'),c++)
COMPILER := $(CXX)
else
COMPILER := $(CC)
endif
$(warning COMPILER is $(COMPILER))

.PHONY: build-$(BASENAME)
build-$(BASENAME): $(OBJECTS)
	$(COMPILER) -save-temps         -o "$(BASENAME)" $+ -Wl,-Map=$(BASENAME).map $(LDFLAGS) $(LDLIBS)
	$(COMPILER) -save-temps -\#\#\# -o "$(BASENAME)" $+ -Wl,-Map=$(BASENAME).map $(LDFLAGS) $(LDLIBS) 2>&1 | tee $(BASENAME).cmd

$(BASENAME).env: $(BASENAME).cmd
	cat "$<" | grep '^[A-Z_]*=' | sed 's/^\([A-Z_]*=\)\(.*\)/\1"\2"/' > "$@"

$(BASENAME).collect-cmd: $(BASENAME).cmd
	cat "$<" | grep /collect > "$@"

ifeq ($(filter -static,$(LDFLAGS)),)
LIB_SUFFIXES := so a
else
LIB_SUFFIXES := a
endif

$(BASENAME).repeat-cmd: $(BASENAME).collect-cmd $(BASENAME).env
	unquote () { \
		eval echo "$$1"; \
	}; \
	lds_to_cmdline () { \
		sed 's/AS_NEEDED *(\([^)]*\))/--as-needed \1 --no-as-needed/g' | \
		sed 's/OUTPUT_FORMAT(\([^)]*\))//g' | \
		sed 's/GROUP *(\([^)]*\))/--start-group \1 --end-group/g' | \
		tr '\n' ' ' | sed 's^/\*.*\*/^^'; \
	}; \
	for arg in $$( cat "$<" ); do \
		unquoted_arg="$$( unquote "$$arg" )"; \
		case "$$unquoted_arg" in \
			(*/collect*) \
				echo "ld" ;; \
			(/*) cp "$$unquoted_arg" ./ && echo $$(basename "$$unquoted_arg" );; \
			(-l*) ( . ./$(BASENAME).env && \
					tmpfile=$$(mktemp) && \
					echo $$LIBRARY_PATH | tr ':' '\n' > $$tmpfile && \
					found="" && for suffix in $(LIB_SUFFIXES); do while read line ; do \
					search_fname_stem="$$line"/lib$$( echo "$$unquoted_arg" | sed 's/^-l//'); \
					if [ -e "$$search_fname_stem".$$suffix ]; then \
						echo -n "Found: " 1>&2; \
						cp "$$search_fname_stem".$$suffix ./ && \
						found="$$search_fname_stem".$$suffix && \
						(file "$$found" 2>&1 | grep ASCII >/dev/null && (for word in $$(cat "$$found" | lds_to_cmdline); do \
							case "$$word" in \
								(/*) cp "$$word" ./ && basename "$$word";; \
								(*) echo "$$word" ;; \
							esac; \
						    done) || \
						    echo $$(basename "$$search_fname_stem".$$suffix) ) | tee /dev/stderr; break 2; \
					else \
						echo "Did not find $$search_fname_stem.$$suffix; trying next in path" 1>&2; \
					fi; \
				done < "$$tmpfile"; \
				if [ -z "$$found" ]; then echo "Did not find $$unquoted_arg with suffix $$suffix" 1>&2; fi; done; \
				rm -f "$$tmpfile"; \
				) \
				;; \
			(-L*) ;; \
			(-f*) ;; \
			(-*) echo "$$unquoted_arg" ;; \
			(*) echo "$$unquoted_arg" ;; \
		esac; \
	done | tr '\n' ' ' > "$@"; echo >> "$@"

.PHONY: repeat
repeat: $(OBJECTS) $(BASENAME).repeat-cmd
	eval $$( cat $(BASENAME).repeat-cmd )

.PHONY: repeat
$(BASENAME).with-relocs: $(OBJECTS) $(BASENAME).repeat-cmd
	eval $$( cat $(BASENAME).repeat-cmd | sed 's/^ld/ld -q/' | sed 's#-o $(BASENAME)#-o $@#' )
clean:
	rm -f $(OUTPUTS) *.o *.a *.so *.so.*