summaryrefslogtreecommitdiff
path: root/src/Make.pkg
blob: 59ce56ac0d9166610657813d0043ce3f96b3c849 (plain)
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

all: package
package: _obj/$(TARG).a
testpackage: _test/$(TARG).a

include $(QUOTED_GOROOT)/src/Make.common

# The quietgcc wrapper is for our own source code
# while building the libraries, not arbitrary source code
# as encountered by cgo.
ifeq ($(HOST_CC),quietgcc)
HOST_CC:=gcc
endif
ifeq ($(HOST_LD),quietgcc)
HOST_LD:=gcc
endif

# GNU Make 3.80 has a bug in lastword
# elem=$(lastword $(subst /, ,$(TARG)))
TARG_words=$(subst /, ,$(TARG))
elem=$(word $(words $(TARG_words)),$(TARG_words))

ifeq ($(elem),$(TARG))
dir=
else
dir=$(patsubst %/$(elem),%,$(TARG))
endif

pkgdir=$(QUOTED_GOROOT)/pkg/$(GOOS)_$(GOARCH)

INSTALLFILES+=$(pkgdir)/$(TARG).a

# The rest of the cgo rules are below, but these variable updates
# must be done here so they apply to the main rules.
ifdef CGOFILES
GOFILES+=$(patsubst %.go,_obj/%.cgo1.go,$(CGOFILES)) _obj/_cgo_gotypes.go
CGO_OFILES+=$(patsubst %.go,%.cgo2.o,$(CGOFILES)) _cgo_export.o
OFILES+=_cgo_defun.$O _cgo_import.$O $(CGO_OFILES)
endif

ifdef SWIGFILES
GOFILES+=$(patsubst %.swig,_obj/%.go,$(patsubst %.swigcxx,%.swig,$(SWIGFILES)))
OFILES+=$(patsubst %.swig,_obj/%_gc.$O,$(patsubst %.swigcxx,%.swig,$(SWIGFILES)))
SWIG_PREFIX=$(subst /,-,$(TARG))
SWIG_SOS+=$(patsubst %.swig,_obj/$(SWIG_PREFIX)-%.so,$(patsubst %.swigcxx,%.swig,$(SWIGFILES)))
INSTALLFILES+=$(patsubst %.swig,$(pkgdir)/swig/$(SWIG_PREFIX)-%.so,$(patsubst %.swigcxx,%.swig,$(SWIGFILES)))
endif

PREREQ+=$(patsubst %,%.make,$(DEPS))

coverage:
	gotest
	6cov -g $(shell pwd) $O.out | grep -v '_test\.go:'

CLEANFILES+=*.so _obj _test _testmain.go *.exe _cgo* *.cgo[12].* test.out build.out

test:
	gotest

testshort:
	gotest -test.short -test.timeout=120

bench:
	gotest -test.bench=. -test.run="Do not run tests"

nuke: clean
	rm -f $(pkgdir)/$(TARG).a

testpackage-clean:
	rm -f _test/$(TARG).a

install: $(INSTALLFILES)

$(pkgdir)/$(TARG).a: _obj/$(TARG).a
	@test -d $(QUOTED_GOROOT)/pkg && mkdir -p $(pkgdir)/$(dir)
	cp _obj/$(TARG).a "$@"

_go_.$O: $(GOFILES) $(PREREQ)
	$(GC) -o $@ $(GOFILES)

_gotest_.$O: $(GOFILES) $(GOTESTFILES) $(PREREQ)
	$(GC) -o $@ $(GOFILES) $(GOTESTFILES)

_obj/$(TARG).a: _go_.$O $(OFILES)
	@mkdir -p _obj/$(dir)
	rm -f _obj/$(TARG).a
	gopack grc $@ _go_.$O $(OFILES)

_test/$(TARG).a: _gotest_.$O $(OFILES)
	@mkdir -p _test/$(dir)
	rm -f _test/$(TARG).a
	gopack grc $@ _gotest_.$O $(OFILES)

importpath:
	@echo $(TARG)

dir:
	@echo $(dir)

# To use cgo in a Go package, add a line
#
#	CGOFILES=x.go y.go
#
# to the main Makefile.  This signals that cgo should process x.go
# and y.go when building the package.
# There are three optional variables to set, CGO_CFLAGS, CGO_LDFLAGS,
# and CGO_DEPS, which specify compiler flags, linker flags, and linker
# dependencies to use when compiling (using gcc) the C support for
# x.go and y.go.

# Cgo translates each x.go file listed in $(CGOFILES) into a basic
# translation of x.go, called _obj/x.cgo1.go. Additionally, three other
# files are created:
#
#	_obj/_cgo_gotypes.go	- declarations needed for all .go files in the package; imports "unsafe"
#	_obj/_cgo_defun.c	- C trampoline code to be compiled with 6c and linked into the package
#	_obj/x.cgo2.c	- C implementations compiled with gcc to create a dynamic library
#

ifdef CGOFILES
_obj/_cgo_run: $(CGOFILES)
	@mkdir -p _obj
	CGOPKGPATH=$(dir) cgo -- $(CGO_CFLAGS) $(CGOFILES)
	touch _obj/_cgo_run

# _CGO_CFLAGS and _CGO_LDFLAGS are defined via the evaluation of _cgo_flags.
# The include happens before the commands in the recipe run,
# so it cannot be done in the same recipe that runs cgo.
_obj/_load_cgo_flags: _obj/_cgo_run
	$(eval include _obj/_cgo_flags)

# Include any previous flags in case cgo files are up to date.
-include _obj/_cgo_flags

# Ugly but necessary - cgo writes these files too.
_obj/_cgo_gotypes.go _obj/_cgo_export.c _obj/_cgo_export.h _obj/_cgo_main.c _obj/_cgo_defun.c: _obj/_load_cgo_flags
	@true

_obj/%.cgo1.go _obj/%.cgo2.c: _obj/_cgo_defun.c
	@true
endif

# Compile rules for gcc source files.
%.o: %.c
	$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $(_CGO_CFLAGS) $*.c

%.o: _obj/%.c
	$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -I . -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $(_CGO_CFLAGS) $^

# To find out which symbols are needed from external libraries
# and which libraries are needed, we build a simple a.out that
# links all the objects we just created and then use cgo -dynimport
# to inspect it.  That is, we make gcc tell us which dynamic symbols
# and libraries are involved, instead of duplicating gcc's logic ourselves.
# After main we have to define all the symbols that will be provided
# by Go code.  That's crosscall2 and any exported symbols.

_cgo1_.o: _cgo_main.o $(CGO_OFILES)
	$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ $^ $(CGO_LDFLAGS) $(_CGO_LDFLAGS)

_obj/_cgo_import.c: _cgo1_.o
	@mkdir -p _obj
	cgo -dynimport _cgo1_.o >$@_ && mv -f $@_ $@

# The rules above added x.cgo1.go and _cgo_gotypes.go to $(GOFILES),
# added _cgo_defun.$O to $OFILES, and added the installed copy of
# package_x.so (built from x.cgo2.c) to $(INSTALLFILES).

# Have to run gcc with the right size argument on hybrid 32/64 machines.
_CGO_CFLAGS_386=-m32
_CGO_CFLAGS_amd64=-m64
_CGO_LDFLAGS_freebsd=-shared -lpthread -lm
_CGO_LDFLAGS_linux=-shared -lpthread -lm
_CGO_LDFLAGS_darwin=-dynamiclib -Wl,-undefined,dynamic_lookup
_CGO_LDFLAGS_windows=-shared -lm -mthreads

# Have to compile the runtime header.
RUNTIME_CFLAGS=-I$(pkgdir)

# Compile _cgo_defun.c with 6c; needs access to the runtime headers.
_cgo_defun.$O: _obj/_cgo_defun.c
	$(CC) $(CFLAGS) $(RUNTIME_CFLAGS) -I . -o "$@" _obj/_cgo_defun.c

# To use swig in a Go package, add a line
#
#	SWIGFILES=x.swig
#
# to the main Makefile.  This signals that SWIG should process the
#.swig file when building the package.
#
# To wrap C code, use an extension of .swig.  To wrap C++ code, use an
# extension of .swigcxx.
#
#	SWIGFILES=myclib.swig mycxxlib.swigcxx

ifdef SWIGFILES
_obj/%._swig_run _obj/%.go _obj/%_gc.c _obj/%_wrap.c: %.swig
	@mkdir -p _obj
	swig -go -module $* -soname $(SWIG_PREFIX)-$*.so -o _obj/$*_wrap.c -outdir _obj $<

_obj/%._swig_run _obj/%.go _obj/%_gc.c _obj/%_wrap.cxx: %.swigcxx
	@mkdir -p _obj
	swig -go -c++ -module $* -soname $(SWIG_PREFIX)-$*.so -o _obj/$*_wrap.cxx -outdir _obj $<

_obj/%_gc.$O: _obj/%_gc.c
	$(CC) $(CFLAGS) -I . -I$(pkgdir) -o "$@" _obj/$*_gc.c

_obj/%_wrap.o: _obj/%_wrap.c
	$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -I . -g -fPIC -O2 -o $@ -c $^ $(SWIG_CFLAGS)

HOST_CXX=g++

_obj/%_wrapcxx.o: _obj/%_wrap.cxx
	$(HOST_CXX) $(_CGO_CFLAGS_$(GOARCH)) -I . -g -fPIC -O2 -o $@ -c $^ $(SWIG_CXXFLAGS)

_obj/$(SWIG_PREFIX)-%.so: _obj/%_wrap.o
	$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -o $@ $^ $(SWIG_LDFLAGS) $(_CGO_LDFLAGS_$(GOOS)) $(_SWIG_LDFLAGS_$(GOOS))

_obj/$(SWIG_PREFIX)-%.so: _obj/%_wrapcxx.o
	$(HOST_CXX) $(_CGO_CFLAGS_$(GOARCH)) -o $@ $^ $(SWIG_LDFLAGS) $(_CGO_LDFLAGS_$(GOOS)) $(_SWIG_LDFLAGS_$(GOOS))

$(pkgdir)/swig/$(SWIG_PREFIX)-%.so: _obj/$(SWIG_PREFIX)-%.so
	@test -d $(QUOTED_GOROOT)/pkg && mkdir -p $(pkgdir)/swig
	cp $< "$@"

all: $(SWIG_SOS)

SWIG_RPATH=-r $(pkgdir)/swig

endif

# Generic build rules.
# These come last so that the rules above can override them
# for more specific file names.
%.$O: %.c $(HFILES)
	$(CC) $(CFLAGS) -o "$@" $*.c

%.$O: _obj/%.c $(HFILES)
	$(CC) $(CFLAGS) -I . -o "$@" _obj/$*.c

%.$O: %.s
	$(AS) $*.s