正在显示
14 个修改的文件
包含
1278 行增加
和
0 行删除
binding.gyp
0 → 100644
build/Makefile
0 → 100644
1 | +# We borrow heavily from the kernel build setup, though we are simpler since | ||
2 | +# we don't have Kconfig tweaking settings on us. | ||
3 | + | ||
4 | +# The implicit make rules have it looking for RCS files, among other things. | ||
5 | +# We instead explicitly write all the rules we care about. | ||
6 | +# It's even quicker (saves ~200ms) to pass -r on the command line. | ||
7 | +MAKEFLAGS=-r | ||
8 | + | ||
9 | +# The source directory tree. | ||
10 | +srcdir := .. | ||
11 | +abs_srcdir := $(abspath $(srcdir)) | ||
12 | + | ||
13 | +# The name of the builddir. | ||
14 | +builddir_name ?= . | ||
15 | + | ||
16 | +# The V=1 flag on command line makes us verbosely print command lines. | ||
17 | +ifdef V | ||
18 | + quiet= | ||
19 | +else | ||
20 | + quiet=quiet_ | ||
21 | +endif | ||
22 | + | ||
23 | +# Specify BUILDTYPE=Release on the command line for a release build. | ||
24 | +BUILDTYPE ?= Release | ||
25 | + | ||
26 | +# Directory all our build output goes into. | ||
27 | +# Note that this must be two directories beneath src/ for unit tests to pass, | ||
28 | +# as they reach into the src/ directory for data with relative paths. | ||
29 | +builddir ?= $(builddir_name)/$(BUILDTYPE) | ||
30 | +abs_builddir := $(abspath $(builddir)) | ||
31 | +depsdir := $(builddir)/.deps | ||
32 | + | ||
33 | +# Object output directory. | ||
34 | +obj := $(builddir)/obj | ||
35 | +abs_obj := $(abspath $(obj)) | ||
36 | + | ||
37 | +# We build up a list of every single one of the targets so we can slurp in the | ||
38 | +# generated dependency rule Makefiles in one pass. | ||
39 | +all_deps := | ||
40 | + | ||
41 | + | ||
42 | + | ||
43 | +CC.target ?= $(CC) | ||
44 | +CFLAGS.target ?= $(CPPFLAGS) $(CFLAGS) | ||
45 | +CXX.target ?= $(CXX) | ||
46 | +CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS) | ||
47 | +LINK.target ?= $(LINK) | ||
48 | +LDFLAGS.target ?= $(LDFLAGS) | ||
49 | +AR.target ?= $(AR) | ||
50 | + | ||
51 | +# C++ apps need to be linked with g++. | ||
52 | +LINK ?= $(CXX.target) | ||
53 | + | ||
54 | +# TODO(evan): move all cross-compilation logic to gyp-time so we don't need | ||
55 | +# to replicate this environment fallback in make as well. | ||
56 | +CC.host ?= gcc | ||
57 | +CFLAGS.host ?= $(CPPFLAGS_host) $(CFLAGS_host) | ||
58 | +CXX.host ?= g++ | ||
59 | +CXXFLAGS.host ?= $(CPPFLAGS_host) $(CXXFLAGS_host) | ||
60 | +LINK.host ?= $(CXX.host) | ||
61 | +LDFLAGS.host ?= | ||
62 | +AR.host ?= ar | ||
63 | + | ||
64 | +# Define a dir function that can handle spaces. | ||
65 | +# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions | ||
66 | +# "leading spaces cannot appear in the text of the first argument as written. | ||
67 | +# These characters can be put into the argument value by variable substitution." | ||
68 | +empty := | ||
69 | +space := $(empty) $(empty) | ||
70 | + | ||
71 | +# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces | ||
72 | +replace_spaces = $(subst $(space),?,$1) | ||
73 | +unreplace_spaces = $(subst ?,$(space),$1) | ||
74 | +dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) | ||
75 | + | ||
76 | +# Flags to make gcc output dependency info. Note that you need to be | ||
77 | +# careful here to use the flags that ccache and distcc can understand. | ||
78 | +# We write to a dep file on the side first and then rename at the end | ||
79 | +# so we can't end up with a broken dep file. | ||
80 | +depfile = $(depsdir)/$(call replace_spaces,$@).d | ||
81 | +DEPFLAGS = -MMD -MF $(depfile).raw | ||
82 | + | ||
83 | +# We have to fixup the deps output in a few ways. | ||
84 | +# (1) the file output should mention the proper .o file. | ||
85 | +# ccache or distcc lose the path to the target, so we convert a rule of | ||
86 | +# the form: | ||
87 | +# foobar.o: DEP1 DEP2 | ||
88 | +# into | ||
89 | +# path/to/foobar.o: DEP1 DEP2 | ||
90 | +# (2) we want missing files not to cause us to fail to build. | ||
91 | +# We want to rewrite | ||
92 | +# foobar.o: DEP1 DEP2 \ | ||
93 | +# DEP3 | ||
94 | +# to | ||
95 | +# DEP1: | ||
96 | +# DEP2: | ||
97 | +# DEP3: | ||
98 | +# so if the files are missing, they're just considered phony rules. | ||
99 | +# We have to do some pretty insane escaping to get those backslashes | ||
100 | +# and dollar signs past make, the shell, and sed at the same time. | ||
101 | +# Doesn't work with spaces, but that's fine: .d files have spaces in | ||
102 | +# their names replaced with other characters. | ||
103 | +define fixup_dep | ||
104 | +# The depfile may not exist if the input file didn't have any #includes. | ||
105 | +touch $(depfile).raw | ||
106 | +# Fixup path as in (1). | ||
107 | +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) | ||
108 | +# Add extra rules as in (2). | ||
109 | +# We remove slashes and replace spaces with new lines; | ||
110 | +# remove blank lines; | ||
111 | +# delete the first line and append a colon to the remaining lines. | ||
112 | +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ | ||
113 | + grep -v '^$$' |\ | ||
114 | + sed -e 1d -e 's|$$|:|' \ | ||
115 | + >> $(depfile) | ||
116 | +rm $(depfile).raw | ||
117 | +endef | ||
118 | + | ||
119 | +# Command definitions: | ||
120 | +# - cmd_foo is the actual command to run; | ||
121 | +# - quiet_cmd_foo is the brief-output summary of the command. | ||
122 | + | ||
123 | +quiet_cmd_cc = CC($(TOOLSET)) $@ | ||
124 | +cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< | ||
125 | + | ||
126 | +quiet_cmd_cxx = CXX($(TOOLSET)) $@ | ||
127 | +cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< | ||
128 | + | ||
129 | +quiet_cmd_objc = CXX($(TOOLSET)) $@ | ||
130 | +cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< | ||
131 | + | ||
132 | +quiet_cmd_objcxx = CXX($(TOOLSET)) $@ | ||
133 | +cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< | ||
134 | + | ||
135 | +# Commands for precompiled header files. | ||
136 | +quiet_cmd_pch_c = CXX($(TOOLSET)) $@ | ||
137 | +cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< | ||
138 | +quiet_cmd_pch_cc = CXX($(TOOLSET)) $@ | ||
139 | +cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< | ||
140 | +quiet_cmd_pch_m = CXX($(TOOLSET)) $@ | ||
141 | +cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< | ||
142 | +quiet_cmd_pch_mm = CXX($(TOOLSET)) $@ | ||
143 | +cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< | ||
144 | + | ||
145 | +# gyp-mac-tool is written next to the root Makefile by gyp. | ||
146 | +# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd | ||
147 | +# already. | ||
148 | +quiet_cmd_mac_tool = MACTOOL $(4) $< | ||
149 | +cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@" | ||
150 | + | ||
151 | +quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@ | ||
152 | +cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) | ||
153 | + | ||
154 | +quiet_cmd_infoplist = INFOPLIST $@ | ||
155 | +cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@" | ||
156 | + | ||
157 | +quiet_cmd_touch = TOUCH $@ | ||
158 | +cmd_touch = touch $@ | ||
159 | + | ||
160 | +quiet_cmd_copy = COPY $@ | ||
161 | +# send stderr to /dev/null to ignore messages when linking directories. | ||
162 | +cmd_copy = rm -rf "$@" && cp -af "$<" "$@" | ||
163 | + | ||
164 | +quiet_cmd_alink = LIBTOOL-STATIC $@ | ||
165 | +cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^) | ||
166 | + | ||
167 | +quiet_cmd_link = LINK($(TOOLSET)) $@ | ||
168 | +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) | ||
169 | + | ||
170 | +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ | ||
171 | +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) | ||
172 | + | ||
173 | +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ | ||
174 | +cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) | ||
175 | + | ||
176 | + | ||
177 | +# Define an escape_quotes function to escape single quotes. | ||
178 | +# This allows us to handle quotes properly as long as we always use | ||
179 | +# use single quotes and escape_quotes. | ||
180 | +escape_quotes = $(subst ','\'',$(1)) | ||
181 | +# This comment is here just to include a ' to unconfuse syntax highlighting. | ||
182 | +# Define an escape_vars function to escape '$' variable syntax. | ||
183 | +# This allows us to read/write command lines with shell variables (e.g. | ||
184 | +# $LD_LIBRARY_PATH), without triggering make substitution. | ||
185 | +escape_vars = $(subst $$,$$$$,$(1)) | ||
186 | +# Helper that expands to a shell command to echo a string exactly as it is in | ||
187 | +# make. This uses printf instead of echo because printf's behaviour with respect | ||
188 | +# to escape sequences is more portable than echo's across different shells | ||
189 | +# (e.g., dash, bash). | ||
190 | +exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' | ||
191 | + | ||
192 | +# Helper to compare the command we're about to run against the command | ||
193 | +# we logged the last time we ran the command. Produces an empty | ||
194 | +# string (false) when the commands match. | ||
195 | +# Tricky point: Make has no string-equality test function. | ||
196 | +# The kernel uses the following, but it seems like it would have false | ||
197 | +# positives, where one string reordered its arguments. | ||
198 | +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ | ||
199 | +# $(filter-out $(cmd_$@), $(cmd_$(1)))) | ||
200 | +# We instead substitute each for the empty string into the other, and | ||
201 | +# say they're equal if both substitutions produce the empty string. | ||
202 | +# .d files contain ? instead of spaces, take that into account. | ||
203 | +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ | ||
204 | + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) | ||
205 | + | ||
206 | +# Helper that is non-empty when a prerequisite changes. | ||
207 | +# Normally make does this implicitly, but we force rules to always run | ||
208 | +# so we can check their command lines. | ||
209 | +# $? -- new prerequisites | ||
210 | +# $| -- order-only dependencies | ||
211 | +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) | ||
212 | + | ||
213 | +# Helper that executes all postbuilds until one fails. | ||
214 | +define do_postbuilds | ||
215 | + @E=0;\ | ||
216 | + for p in $(POSTBUILDS); do\ | ||
217 | + eval $$p;\ | ||
218 | + E=$$?;\ | ||
219 | + if [ $$E -ne 0 ]; then\ | ||
220 | + break;\ | ||
221 | + fi;\ | ||
222 | + done;\ | ||
223 | + if [ $$E -ne 0 ]; then\ | ||
224 | + rm -rf "$@";\ | ||
225 | + exit $$E;\ | ||
226 | + fi | ||
227 | +endef | ||
228 | + | ||
229 | +# do_cmd: run a command via the above cmd_foo names, if necessary. | ||
230 | +# Should always run for a given target to handle command-line changes. | ||
231 | +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. | ||
232 | +# Third argument, if non-zero, makes it do POSTBUILDS processing. | ||
233 | +# Note: We intentionally do NOT call dirx for depfile, since it contains ? for | ||
234 | +# spaces already and dirx strips the ? characters. | ||
235 | +define do_cmd | ||
236 | +$(if $(or $(command_changed),$(prereq_changed)), | ||
237 | + @$(call exact_echo, $($(quiet)cmd_$(1))) | ||
238 | + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" | ||
239 | + $(if $(findstring flock,$(word 2,$(cmd_$1))), | ||
240 | + @$(cmd_$(1)) | ||
241 | + @echo " $(quiet_cmd_$(1)): Finished", | ||
242 | + @$(cmd_$(1)) | ||
243 | + ) | ||
244 | + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) | ||
245 | + @$(if $(2),$(fixup_dep)) | ||
246 | + $(if $(and $(3), $(POSTBUILDS)), | ||
247 | + $(call do_postbuilds) | ||
248 | + ) | ||
249 | +) | ||
250 | +endef | ||
251 | + | ||
252 | +# Declare the "all" target first so it is the default, | ||
253 | +# even though we don't have the deps yet. | ||
254 | +.PHONY: all | ||
255 | +all: | ||
256 | + | ||
257 | +# make looks for ways to re-generate included makefiles, but in our case, we | ||
258 | +# don't have a direct way. Explicitly telling make that it has nothing to do | ||
259 | +# for them makes it go faster. | ||
260 | +%.d: ; | ||
261 | + | ||
262 | +# Use FORCE_DO_CMD to force a target to run. Should be coupled with | ||
263 | +# do_cmd. | ||
264 | +.PHONY: FORCE_DO_CMD | ||
265 | +FORCE_DO_CMD: | ||
266 | + | ||
267 | +TOOLSET := target | ||
268 | +# Suffix rules, putting all outputs into $(obj). | ||
269 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD | ||
270 | + @$(call do_cmd,cc,1) | ||
271 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD | ||
272 | + @$(call do_cmd,cxx,1) | ||
273 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD | ||
274 | + @$(call do_cmd,cxx,1) | ||
275 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD | ||
276 | + @$(call do_cmd,cxx,1) | ||
277 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.m FORCE_DO_CMD | ||
278 | + @$(call do_cmd,objc,1) | ||
279 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.mm FORCE_DO_CMD | ||
280 | + @$(call do_cmd,objcxx,1) | ||
281 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD | ||
282 | + @$(call do_cmd,cc,1) | ||
283 | +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD | ||
284 | + @$(call do_cmd,cc,1) | ||
285 | + | ||
286 | +# Try building from generated source, too. | ||
287 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD | ||
288 | + @$(call do_cmd,cc,1) | ||
289 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD | ||
290 | + @$(call do_cmd,cxx,1) | ||
291 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD | ||
292 | + @$(call do_cmd,cxx,1) | ||
293 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD | ||
294 | + @$(call do_cmd,cxx,1) | ||
295 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.m FORCE_DO_CMD | ||
296 | + @$(call do_cmd,objc,1) | ||
297 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.mm FORCE_DO_CMD | ||
298 | + @$(call do_cmd,objcxx,1) | ||
299 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD | ||
300 | + @$(call do_cmd,cc,1) | ||
301 | +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD | ||
302 | + @$(call do_cmd,cc,1) | ||
303 | + | ||
304 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD | ||
305 | + @$(call do_cmd,cc,1) | ||
306 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD | ||
307 | + @$(call do_cmd,cxx,1) | ||
308 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD | ||
309 | + @$(call do_cmd,cxx,1) | ||
310 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD | ||
311 | + @$(call do_cmd,cxx,1) | ||
312 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.m FORCE_DO_CMD | ||
313 | + @$(call do_cmd,objc,1) | ||
314 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.mm FORCE_DO_CMD | ||
315 | + @$(call do_cmd,objcxx,1) | ||
316 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD | ||
317 | + @$(call do_cmd,cc,1) | ||
318 | +$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD | ||
319 | + @$(call do_cmd,cc,1) | ||
320 | + | ||
321 | + | ||
322 | +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ | ||
323 | + $(findstring $(join ^,$(prefix)),\ | ||
324 | + $(join ^,test.target.mk)))),) | ||
325 | + include test.target.mk | ||
326 | +endif | ||
327 | + | ||
328 | +quiet_cmd_regen_makefile = ACTION Regenerating $@ | ||
329 | +cmd_regen_makefile = cd $(srcdir); /usr/local/lib/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/Users/fzy/project/koa2_Sequelize_project/build/config.gypi -I/usr/local/lib/node_modules/node-gyp/addon.gypi -I/Users/fzy/.node-gyp/8.2.1/include/node/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/fzy/.node-gyp/8.2.1" "-Dnode_gyp_dir=/usr/local/lib/node_modules/node-gyp" "-Dnode_lib_file=/Users/fzy/.node-gyp/8.2.1/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/fzy/project/koa2_Sequelize_project" "-Dnode_engine=v8" binding.gyp | ||
330 | +Makefile: $(srcdir)/../../.node-gyp/8.2.1/include/node/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../usr/local/lib/node_modules/node-gyp/addon.gypi | ||
331 | + $(call do_cmd,regen_makefile) | ||
332 | + | ||
333 | +# "all" is a concatenation of the "all" targets from all the included | ||
334 | +# sub-makefiles. This is just here to clarify. | ||
335 | +all: | ||
336 | + | ||
337 | +# Add in dependency-tracking rules. $(all_deps) is the list of every single | ||
338 | +# target in our tree. Only consider the ones with .d (dependency) info: | ||
339 | +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) | ||
340 | +ifneq ($(d_files),) | ||
341 | + include $(d_files) | ||
342 | +endif |
1 | +cmd_Release/obj.target/test/test.o := c++ '-DNODE_GYP_MODULE_NAME=test' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/fzy/.node-gyp/8.2.1/include/node -I/Users/fzy/.node-gyp/8.2.1/src -I/Users/fzy/.node-gyp/8.2.1/deps/uv/include -I/Users/fzy/.node-gyp/8.2.1/deps/v8/include -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -stdlib=libc++ -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/test/test.o.d.raw -c -o Release/obj.target/test/test.o ../test.cc | ||
2 | +Release/obj.target/test/test.o: ../test.cc \ | ||
3 | + /Users/fzy/.node-gyp/8.2.1/include/node/node.h \ | ||
4 | + /Users/fzy/.node-gyp/8.2.1/include/node/v8.h \ | ||
5 | + /Users/fzy/.node-gyp/8.2.1/include/node/v8-version.h \ | ||
6 | + /Users/fzy/.node-gyp/8.2.1/include/node/v8config.h \ | ||
7 | + /Users/fzy/.node-gyp/8.2.1/include/node/node_version.h | ||
8 | +../test.cc: | ||
9 | +/Users/fzy/.node-gyp/8.2.1/include/node/node.h: | ||
10 | +/Users/fzy/.node-gyp/8.2.1/include/node/v8.h: | ||
11 | +/Users/fzy/.node-gyp/8.2.1/include/node/v8-version.h: | ||
12 | +/Users/fzy/.node-gyp/8.2.1/include/node/v8config.h: | ||
13 | +/Users/fzy/.node-gyp/8.2.1/include/node/node_version.h: |
build/Release/.deps/Release/test.node.d
0 → 100644
1 | +cmd_Release/test.node := c++ -bundle -undefined dynamic_lookup -Wl,-no_pie -Wl,-search_paths_first -mmacosx-version-min=10.7 -arch x86_64 -L./Release -stdlib=libc++ -o Release/test.node Release/obj.target/test/test.o |
build/Release/obj.target/test/test.o
0 → 100644
不能预览此文件类型
build/Release/test.node
0 → 100755
不能预览此文件类型
build/binding.Makefile
0 → 100644
build/config.gypi
0 → 100644
1 | +# Do not edit. File was generated by node-gyp's "configure" step | ||
2 | +{ | ||
3 | + "target_defaults": { | ||
4 | + "cflags": [], | ||
5 | + "default_configuration": "Release", | ||
6 | + "defines": [], | ||
7 | + "include_dirs": [], | ||
8 | + "libraries": [] | ||
9 | + }, | ||
10 | + "variables": { | ||
11 | + "asan": 0, | ||
12 | + "coverage": "false", | ||
13 | + "debug_devtools": "node", | ||
14 | + "force_dynamic_crt": 0, | ||
15 | + "host_arch": "x64", | ||
16 | + "icu_data_file": "icudt59l.dat", | ||
17 | + "icu_data_in": "../../deps/icu-small/source/data/in/icudt59l.dat", | ||
18 | + "icu_endianness": "l", | ||
19 | + "icu_gyp_path": "tools/icu/icu-generic.gyp", | ||
20 | + "icu_locales": "en,root", | ||
21 | + "icu_path": "deps/icu-small", | ||
22 | + "icu_small": "true", | ||
23 | + "icu_ver_major": "59", | ||
24 | + "llvm_version": 0, | ||
25 | + "node_byteorder": "little", | ||
26 | + "node_enable_d8": "false", | ||
27 | + "node_enable_v8_vtunejit": "false", | ||
28 | + "node_install_npm": "true", | ||
29 | + "node_module_version": 57, | ||
30 | + "node_no_browser_globals": "false", | ||
31 | + "node_prefix": "/", | ||
32 | + "node_release_urlbase": "https://nodejs.org/download/release/", | ||
33 | + "node_shared": "false", | ||
34 | + "node_shared_cares": "false", | ||
35 | + "node_shared_http_parser": "false", | ||
36 | + "node_shared_libuv": "false", | ||
37 | + "node_shared_openssl": "false", | ||
38 | + "node_shared_zlib": "false", | ||
39 | + "node_tag": "", | ||
40 | + "node_use_bundled_v8": "true", | ||
41 | + "node_use_dtrace": "true", | ||
42 | + "node_use_etw": "false", | ||
43 | + "node_use_lttng": "false", | ||
44 | + "node_use_openssl": "true", | ||
45 | + "node_use_perfctr": "false", | ||
46 | + "node_use_v8_platform": "true", | ||
47 | + "node_without_node_options": "false", | ||
48 | + "openssl_fips": "", | ||
49 | + "openssl_no_asm": 0, | ||
50 | + "shlib_suffix": "57.dylib", | ||
51 | + "target_arch": "x64", | ||
52 | + "uv_parent_path": "/deps/uv/", | ||
53 | + "uv_use_dtrace": "true", | ||
54 | + "v8_enable_gdbjit": 0, | ||
55 | + "v8_enable_i18n_support": 1, | ||
56 | + "v8_enable_inspector": 1, | ||
57 | + "v8_no_strict_aliasing": 1, | ||
58 | + "v8_optimized_debug": 0, | ||
59 | + "v8_promise_internal_field_count": 1, | ||
60 | + "v8_random_seed": 0, | ||
61 | + "v8_trace_maps": 0, | ||
62 | + "v8_use_snapshot": "false", | ||
63 | + "want_separate_host_toolset": 0, | ||
64 | + "want_separate_host_toolset_mkpeephole": 0, | ||
65 | + "xcode_version": "7.0", | ||
66 | + "nodedir": "/Users/fzy/.node-gyp/8.2.1", | ||
67 | + "standalone_static_library": 1 | ||
68 | + } | ||
69 | +} |
build/gyp-mac-tool
0 → 100755
1 | +#!/usr/bin/env python | ||
2 | +# Generated by gyp. Do not edit. | ||
3 | +# Copyright (c) 2012 Google Inc. All rights reserved. | ||
4 | +# Use of this source code is governed by a BSD-style license that can be | ||
5 | +# found in the LICENSE file. | ||
6 | + | ||
7 | +"""Utility functions to perform Xcode-style build steps. | ||
8 | + | ||
9 | +These functions are executed via gyp-mac-tool when using the Makefile generator. | ||
10 | +""" | ||
11 | + | ||
12 | +import fcntl | ||
13 | +import fnmatch | ||
14 | +import glob | ||
15 | +import json | ||
16 | +import os | ||
17 | +import plistlib | ||
18 | +import re | ||
19 | +import shutil | ||
20 | +import string | ||
21 | +import subprocess | ||
22 | +import sys | ||
23 | +import tempfile | ||
24 | + | ||
25 | + | ||
26 | +def main(args): | ||
27 | + executor = MacTool() | ||
28 | + exit_code = executor.Dispatch(args) | ||
29 | + if exit_code is not None: | ||
30 | + sys.exit(exit_code) | ||
31 | + | ||
32 | + | ||
33 | +class MacTool(object): | ||
34 | + """This class performs all the Mac tooling steps. The methods can either be | ||
35 | + executed directly, or dispatched from an argument list.""" | ||
36 | + | ||
37 | + def Dispatch(self, args): | ||
38 | + """Dispatches a string command to a method.""" | ||
39 | + if len(args) < 1: | ||
40 | + raise Exception("Not enough arguments") | ||
41 | + | ||
42 | + method = "Exec%s" % self._CommandifyName(args[0]) | ||
43 | + return getattr(self, method)(*args[1:]) | ||
44 | + | ||
45 | + def _CommandifyName(self, name_string): | ||
46 | + """Transforms a tool name like copy-info-plist to CopyInfoPlist""" | ||
47 | + return name_string.title().replace('-', '') | ||
48 | + | ||
49 | + def ExecCopyBundleResource(self, source, dest, convert_to_binary): | ||
50 | + """Copies a resource file to the bundle/Resources directory, performing any | ||
51 | + necessary compilation on each resource.""" | ||
52 | + extension = os.path.splitext(source)[1].lower() | ||
53 | + if os.path.isdir(source): | ||
54 | + # Copy tree. | ||
55 | + # TODO(thakis): This copies file attributes like mtime, while the | ||
56 | + # single-file branch below doesn't. This should probably be changed to | ||
57 | + # be consistent with the single-file branch. | ||
58 | + if os.path.exists(dest): | ||
59 | + shutil.rmtree(dest) | ||
60 | + shutil.copytree(source, dest) | ||
61 | + elif extension == '.xib': | ||
62 | + return self._CopyXIBFile(source, dest) | ||
63 | + elif extension == '.storyboard': | ||
64 | + return self._CopyXIBFile(source, dest) | ||
65 | + elif extension == '.strings': | ||
66 | + self._CopyStringsFile(source, dest, convert_to_binary) | ||
67 | + else: | ||
68 | + shutil.copy(source, dest) | ||
69 | + | ||
70 | + def _CopyXIBFile(self, source, dest): | ||
71 | + """Compiles a XIB file with ibtool into a binary plist in the bundle.""" | ||
72 | + | ||
73 | + # ibtool sometimes crashes with relative paths. See crbug.com/314728. | ||
74 | + base = os.path.dirname(os.path.realpath(__file__)) | ||
75 | + if os.path.relpath(source): | ||
76 | + source = os.path.join(base, source) | ||
77 | + if os.path.relpath(dest): | ||
78 | + dest = os.path.join(base, dest) | ||
79 | + | ||
80 | + args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices', | ||
81 | + '--output-format', 'human-readable-text', '--compile', dest, source] | ||
82 | + ibtool_section_re = re.compile(r'/\*.*\*/') | ||
83 | + ibtool_re = re.compile(r'.*note:.*is clipping its content') | ||
84 | + ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) | ||
85 | + current_section_header = None | ||
86 | + for line in ibtoolout.stdout: | ||
87 | + if ibtool_section_re.match(line): | ||
88 | + current_section_header = line | ||
89 | + elif not ibtool_re.match(line): | ||
90 | + if current_section_header: | ||
91 | + sys.stdout.write(current_section_header) | ||
92 | + current_section_header = None | ||
93 | + sys.stdout.write(line) | ||
94 | + return ibtoolout.returncode | ||
95 | + | ||
96 | + def _ConvertToBinary(self, dest): | ||
97 | + subprocess.check_call([ | ||
98 | + 'xcrun', 'plutil', '-convert', 'binary1', '-o', dest, dest]) | ||
99 | + | ||
100 | + def _CopyStringsFile(self, source, dest, convert_to_binary): | ||
101 | + """Copies a .strings file using iconv to reconvert the input into UTF-16.""" | ||
102 | + input_code = self._DetectInputEncoding(source) or "UTF-8" | ||
103 | + | ||
104 | + # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call | ||
105 | + # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints | ||
106 | + # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing | ||
107 | + # semicolon in dictionary. | ||
108 | + # on invalid files. Do the same kind of validation. | ||
109 | + import CoreFoundation | ||
110 | + s = open(source, 'rb').read() | ||
111 | + d = CoreFoundation.CFDataCreate(None, s, len(s)) | ||
112 | + _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None) | ||
113 | + if error: | ||
114 | + return | ||
115 | + | ||
116 | + fp = open(dest, 'wb') | ||
117 | + fp.write(s.decode(input_code).encode('UTF-16')) | ||
118 | + fp.close() | ||
119 | + | ||
120 | + if convert_to_binary == 'True': | ||
121 | + self._ConvertToBinary(dest) | ||
122 | + | ||
123 | + def _DetectInputEncoding(self, file_name): | ||
124 | + """Reads the first few bytes from file_name and tries to guess the text | ||
125 | + encoding. Returns None as a guess if it can't detect it.""" | ||
126 | + fp = open(file_name, 'rb') | ||
127 | + try: | ||
128 | + header = fp.read(3) | ||
129 | + except e: | ||
130 | + fp.close() | ||
131 | + return None | ||
132 | + fp.close() | ||
133 | + if header.startswith("\xFE\xFF"): | ||
134 | + return "UTF-16" | ||
135 | + elif header.startswith("\xFF\xFE"): | ||
136 | + return "UTF-16" | ||
137 | + elif header.startswith("\xEF\xBB\xBF"): | ||
138 | + return "UTF-8" | ||
139 | + else: | ||
140 | + return None | ||
141 | + | ||
142 | + def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys): | ||
143 | + """Copies the |source| Info.plist to the destination directory |dest|.""" | ||
144 | + # Read the source Info.plist into memory. | ||
145 | + fd = open(source, 'r') | ||
146 | + lines = fd.read() | ||
147 | + fd.close() | ||
148 | + | ||
149 | + # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). | ||
150 | + plist = plistlib.readPlistFromString(lines) | ||
151 | + if keys: | ||
152 | + plist = dict(plist.items() + json.loads(keys[0]).items()) | ||
153 | + lines = plistlib.writePlistToString(plist) | ||
154 | + | ||
155 | + # Go through all the environment variables and replace them as variables in | ||
156 | + # the file. | ||
157 | + IDENT_RE = re.compile(r'[/\s]') | ||
158 | + for key in os.environ: | ||
159 | + if key.startswith('_'): | ||
160 | + continue | ||
161 | + evar = '${%s}' % key | ||
162 | + evalue = os.environ[key] | ||
163 | + lines = string.replace(lines, evar, evalue) | ||
164 | + | ||
165 | + # Xcode supports various suffices on environment variables, which are | ||
166 | + # all undocumented. :rfc1034identifier is used in the standard project | ||
167 | + # template these days, and :identifier was used earlier. They are used to | ||
168 | + # convert non-url characters into things that look like valid urls -- | ||
169 | + # except that the replacement character for :identifier, '_' isn't valid | ||
170 | + # in a URL either -- oops, hence :rfc1034identifier was born. | ||
171 | + evar = '${%s:identifier}' % key | ||
172 | + evalue = IDENT_RE.sub('_', os.environ[key]) | ||
173 | + lines = string.replace(lines, evar, evalue) | ||
174 | + | ||
175 | + evar = '${%s:rfc1034identifier}' % key | ||
176 | + evalue = IDENT_RE.sub('-', os.environ[key]) | ||
177 | + lines = string.replace(lines, evar, evalue) | ||
178 | + | ||
179 | + # Remove any keys with values that haven't been replaced. | ||
180 | + lines = lines.split('\n') | ||
181 | + for i in range(len(lines)): | ||
182 | + if lines[i].strip().startswith("<string>${"): | ||
183 | + lines[i] = None | ||
184 | + lines[i - 1] = None | ||
185 | + lines = '\n'.join(filter(lambda x: x is not None, lines)) | ||
186 | + | ||
187 | + # Write out the file with variables replaced. | ||
188 | + fd = open(dest, 'w') | ||
189 | + fd.write(lines) | ||
190 | + fd.close() | ||
191 | + | ||
192 | + # Now write out PkgInfo file now that the Info.plist file has been | ||
193 | + # "compiled". | ||
194 | + self._WritePkgInfo(dest) | ||
195 | + | ||
196 | + if convert_to_binary == 'True': | ||
197 | + self._ConvertToBinary(dest) | ||
198 | + | ||
199 | + def _WritePkgInfo(self, info_plist): | ||
200 | + """This writes the PkgInfo file from the data stored in Info.plist.""" | ||
201 | + plist = plistlib.readPlist(info_plist) | ||
202 | + if not plist: | ||
203 | + return | ||
204 | + | ||
205 | + # Only create PkgInfo for executable types. | ||
206 | + package_type = plist['CFBundlePackageType'] | ||
207 | + if package_type != 'APPL': | ||
208 | + return | ||
209 | + | ||
210 | + # The format of PkgInfo is eight characters, representing the bundle type | ||
211 | + # and bundle signature, each four characters. If that is missing, four | ||
212 | + # '?' characters are used instead. | ||
213 | + signature_code = plist.get('CFBundleSignature', '????') | ||
214 | + if len(signature_code) != 4: # Wrong length resets everything, too. | ||
215 | + signature_code = '?' * 4 | ||
216 | + | ||
217 | + dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo') | ||
218 | + fp = open(dest, 'w') | ||
219 | + fp.write('%s%s' % (package_type, signature_code)) | ||
220 | + fp.close() | ||
221 | + | ||
222 | + def ExecFlock(self, lockfile, *cmd_list): | ||
223 | + """Emulates the most basic behavior of Linux's flock(1).""" | ||
224 | + # Rely on exception handling to report errors. | ||
225 | + fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666) | ||
226 | + fcntl.flock(fd, fcntl.LOCK_EX) | ||
227 | + return subprocess.call(cmd_list) | ||
228 | + | ||
229 | + def ExecFilterLibtool(self, *cmd_list): | ||
230 | + """Calls libtool and filters out '/path/to/libtool: file: foo.o has no | ||
231 | + symbols'.""" | ||
232 | + libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$') | ||
233 | + libtool_re5 = re.compile( | ||
234 | + r'^.*libtool: warning for library: ' + | ||
235 | + r'.* the table of contents is empty ' + | ||
236 | + r'\(no object file members in the library define global symbols\)$') | ||
237 | + env = os.environ.copy() | ||
238 | + # Ref: | ||
239 | + # http://www.opensource.apple.com/source/cctools/cctools-809/misc/libtool.c | ||
240 | + # The problem with this flag is that it resets the file mtime on the file to | ||
241 | + # epoch=0, e.g. 1970-1-1 or 1969-12-31 depending on timezone. | ||
242 | + env['ZERO_AR_DATE'] = '1' | ||
243 | + libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env) | ||
244 | + _, err = libtoolout.communicate() | ||
245 | + for line in err.splitlines(): | ||
246 | + if not libtool_re.match(line) and not libtool_re5.match(line): | ||
247 | + print >>sys.stderr, line | ||
248 | + # Unconditionally touch the output .a file on the command line if present | ||
249 | + # and the command succeeded. A bit hacky. | ||
250 | + if not libtoolout.returncode: | ||
251 | + for i in range(len(cmd_list) - 1): | ||
252 | + if cmd_list[i] == "-o" and cmd_list[i+1].endswith('.a'): | ||
253 | + os.utime(cmd_list[i+1], None) | ||
254 | + break | ||
255 | + return libtoolout.returncode | ||
256 | + | ||
257 | + def ExecPackageFramework(self, framework, version): | ||
258 | + """Takes a path to Something.framework and the Current version of that and | ||
259 | + sets up all the symlinks.""" | ||
260 | + # Find the name of the binary based on the part before the ".framework". | ||
261 | + binary = os.path.basename(framework).split('.')[0] | ||
262 | + | ||
263 | + CURRENT = 'Current' | ||
264 | + RESOURCES = 'Resources' | ||
265 | + VERSIONS = 'Versions' | ||
266 | + | ||
267 | + if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)): | ||
268 | + # Binary-less frameworks don't seem to contain symlinks (see e.g. | ||
269 | + # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle). | ||
270 | + return | ||
271 | + | ||
272 | + # Move into the framework directory to set the symlinks correctly. | ||
273 | + pwd = os.getcwd() | ||
274 | + os.chdir(framework) | ||
275 | + | ||
276 | + # Set up the Current version. | ||
277 | + self._Relink(version, os.path.join(VERSIONS, CURRENT)) | ||
278 | + | ||
279 | + # Set up the root symlinks. | ||
280 | + self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary) | ||
281 | + self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES) | ||
282 | + | ||
283 | + # Back to where we were before! | ||
284 | + os.chdir(pwd) | ||
285 | + | ||
286 | + def _Relink(self, dest, link): | ||
287 | + """Creates a symlink to |dest| named |link|. If |link| already exists, | ||
288 | + it is overwritten.""" | ||
289 | + if os.path.lexists(link): | ||
290 | + os.remove(link) | ||
291 | + os.symlink(dest, link) | ||
292 | + | ||
293 | + def ExecCompileXcassets(self, keys, *inputs): | ||
294 | + """Compiles multiple .xcassets files into a single .car file. | ||
295 | + | ||
296 | + This invokes 'actool' to compile all the inputs .xcassets files. The | ||
297 | + |keys| arguments is a json-encoded dictionary of extra arguments to | ||
298 | + pass to 'actool' when the asset catalogs contains an application icon | ||
299 | + or a launch image. | ||
300 | + | ||
301 | + Note that 'actool' does not create the Assets.car file if the asset | ||
302 | + catalogs does not contains imageset. | ||
303 | + """ | ||
304 | + command_line = [ | ||
305 | + 'xcrun', 'actool', '--output-format', 'human-readable-text', | ||
306 | + '--compress-pngs', '--notices', '--warnings', '--errors', | ||
307 | + ] | ||
308 | + is_iphone_target = 'IPHONEOS_DEPLOYMENT_TARGET' in os.environ | ||
309 | + if is_iphone_target: | ||
310 | + platform = os.environ['CONFIGURATION'].split('-')[-1] | ||
311 | + if platform not in ('iphoneos', 'iphonesimulator'): | ||
312 | + platform = 'iphonesimulator' | ||
313 | + command_line.extend([ | ||
314 | + '--platform', platform, '--target-device', 'iphone', | ||
315 | + '--target-device', 'ipad', '--minimum-deployment-target', | ||
316 | + os.environ['IPHONEOS_DEPLOYMENT_TARGET'], '--compile', | ||
317 | + os.path.abspath(os.environ['CONTENTS_FOLDER_PATH']), | ||
318 | + ]) | ||
319 | + else: | ||
320 | + command_line.extend([ | ||
321 | + '--platform', 'macosx', '--target-device', 'mac', | ||
322 | + '--minimum-deployment-target', os.environ['MACOSX_DEPLOYMENT_TARGET'], | ||
323 | + '--compile', | ||
324 | + os.path.abspath(os.environ['UNLOCALIZED_RESOURCES_FOLDER_PATH']), | ||
325 | + ]) | ||
326 | + if keys: | ||
327 | + keys = json.loads(keys) | ||
328 | + for key, value in keys.iteritems(): | ||
329 | + arg_name = '--' + key | ||
330 | + if isinstance(value, bool): | ||
331 | + if value: | ||
332 | + command_line.append(arg_name) | ||
333 | + elif isinstance(value, list): | ||
334 | + for v in value: | ||
335 | + command_line.append(arg_name) | ||
336 | + command_line.append(str(v)) | ||
337 | + else: | ||
338 | + command_line.append(arg_name) | ||
339 | + command_line.append(str(value)) | ||
340 | + # Note: actool crashes if inputs path are relative, so use os.path.abspath | ||
341 | + # to get absolute path name for inputs. | ||
342 | + command_line.extend(map(os.path.abspath, inputs)) | ||
343 | + subprocess.check_call(command_line) | ||
344 | + | ||
345 | + def ExecMergeInfoPlist(self, output, *inputs): | ||
346 | + """Merge multiple .plist files into a single .plist file.""" | ||
347 | + merged_plist = {} | ||
348 | + for path in inputs: | ||
349 | + plist = self._LoadPlistMaybeBinary(path) | ||
350 | + self._MergePlist(merged_plist, plist) | ||
351 | + plistlib.writePlist(merged_plist, output) | ||
352 | + | ||
353 | + def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning): | ||
354 | + """Code sign a bundle. | ||
355 | + | ||
356 | + This function tries to code sign an iOS bundle, following the same | ||
357 | + algorithm as Xcode: | ||
358 | + 1. copy ResourceRules.plist from the user or the SDK into the bundle, | ||
359 | + 2. pick the provisioning profile that best match the bundle identifier, | ||
360 | + and copy it into the bundle as embedded.mobileprovision, | ||
361 | + 3. copy Entitlements.plist from user or SDK next to the bundle, | ||
362 | + 4. code sign the bundle. | ||
363 | + """ | ||
364 | + resource_rules_path = self._InstallResourceRules(resource_rules) | ||
365 | + substitutions, overrides = self._InstallProvisioningProfile( | ||
366 | + provisioning, self._GetCFBundleIdentifier()) | ||
367 | + entitlements_path = self._InstallEntitlements( | ||
368 | + entitlements, substitutions, overrides) | ||
369 | + subprocess.check_call([ | ||
370 | + 'codesign', '--force', '--sign', key, '--resource-rules', | ||
371 | + resource_rules_path, '--entitlements', entitlements_path, | ||
372 | + os.path.join( | ||
373 | + os.environ['TARGET_BUILD_DIR'], | ||
374 | + os.environ['FULL_PRODUCT_NAME'])]) | ||
375 | + | ||
376 | + def _InstallResourceRules(self, resource_rules): | ||
377 | + """Installs ResourceRules.plist from user or SDK into the bundle. | ||
378 | + | ||
379 | + Args: | ||
380 | + resource_rules: string, optional, path to the ResourceRules.plist file | ||
381 | + to use, default to "${SDKROOT}/ResourceRules.plist" | ||
382 | + | ||
383 | + Returns: | ||
384 | + Path to the copy of ResourceRules.plist into the bundle. | ||
385 | + """ | ||
386 | + source_path = resource_rules | ||
387 | + target_path = os.path.join( | ||
388 | + os.environ['BUILT_PRODUCTS_DIR'], | ||
389 | + os.environ['CONTENTS_FOLDER_PATH'], | ||
390 | + 'ResourceRules.plist') | ||
391 | + if not source_path: | ||
392 | + source_path = os.path.join( | ||
393 | + os.environ['SDKROOT'], 'ResourceRules.plist') | ||
394 | + shutil.copy2(source_path, target_path) | ||
395 | + return target_path | ||
396 | + | ||
397 | + def _InstallProvisioningProfile(self, profile, bundle_identifier): | ||
398 | + """Installs embedded.mobileprovision into the bundle. | ||
399 | + | ||
400 | + Args: | ||
401 | + profile: string, optional, short name of the .mobileprovision file | ||
402 | + to use, if empty or the file is missing, the best file installed | ||
403 | + will be used | ||
404 | + bundle_identifier: string, value of CFBundleIdentifier from Info.plist | ||
405 | + | ||
406 | + Returns: | ||
407 | + A tuple containing two dictionary: variables substitutions and values | ||
408 | + to overrides when generating the entitlements file. | ||
409 | + """ | ||
410 | + source_path, provisioning_data, team_id = self._FindProvisioningProfile( | ||
411 | + profile, bundle_identifier) | ||
412 | + target_path = os.path.join( | ||
413 | + os.environ['BUILT_PRODUCTS_DIR'], | ||
414 | + os.environ['CONTENTS_FOLDER_PATH'], | ||
415 | + 'embedded.mobileprovision') | ||
416 | + shutil.copy2(source_path, target_path) | ||
417 | + substitutions = self._GetSubstitutions(bundle_identifier, team_id + '.') | ||
418 | + return substitutions, provisioning_data['Entitlements'] | ||
419 | + | ||
420 | + def _FindProvisioningProfile(self, profile, bundle_identifier): | ||
421 | + """Finds the .mobileprovision file to use for signing the bundle. | ||
422 | + | ||
423 | + Checks all the installed provisioning profiles (or if the user specified | ||
424 | + the PROVISIONING_PROFILE variable, only consult it) and select the most | ||
425 | + specific that correspond to the bundle identifier. | ||
426 | + | ||
427 | + Args: | ||
428 | + profile: string, optional, short name of the .mobileprovision file | ||
429 | + to use, if empty or the file is missing, the best file installed | ||
430 | + will be used | ||
431 | + bundle_identifier: string, value of CFBundleIdentifier from Info.plist | ||
432 | + | ||
433 | + Returns: | ||
434 | + A tuple of the path to the selected provisioning profile, the data of | ||
435 | + the embedded plist in the provisioning profile and the team identifier | ||
436 | + to use for code signing. | ||
437 | + | ||
438 | + Raises: | ||
439 | + SystemExit: if no .mobileprovision can be used to sign the bundle. | ||
440 | + """ | ||
441 | + profiles_dir = os.path.join( | ||
442 | + os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles') | ||
443 | + if not os.path.isdir(profiles_dir): | ||
444 | + print >>sys.stderr, ( | ||
445 | + 'cannot find mobile provisioning for %s' % bundle_identifier) | ||
446 | + sys.exit(1) | ||
447 | + provisioning_profiles = None | ||
448 | + if profile: | ||
449 | + profile_path = os.path.join(profiles_dir, profile + '.mobileprovision') | ||
450 | + if os.path.exists(profile_path): | ||
451 | + provisioning_profiles = [profile_path] | ||
452 | + if not provisioning_profiles: | ||
453 | + provisioning_profiles = glob.glob( | ||
454 | + os.path.join(profiles_dir, '*.mobileprovision')) | ||
455 | + valid_provisioning_profiles = {} | ||
456 | + for profile_path in provisioning_profiles: | ||
457 | + profile_data = self._LoadProvisioningProfile(profile_path) | ||
458 | + app_id_pattern = profile_data.get( | ||
459 | + 'Entitlements', {}).get('application-identifier', '') | ||
460 | + for team_identifier in profile_data.get('TeamIdentifier', []): | ||
461 | + app_id = '%s.%s' % (team_identifier, bundle_identifier) | ||
462 | + if fnmatch.fnmatch(app_id, app_id_pattern): | ||
463 | + valid_provisioning_profiles[app_id_pattern] = ( | ||
464 | + profile_path, profile_data, team_identifier) | ||
465 | + if not valid_provisioning_profiles: | ||
466 | + print >>sys.stderr, ( | ||
467 | + 'cannot find mobile provisioning for %s' % bundle_identifier) | ||
468 | + sys.exit(1) | ||
469 | + # If the user has multiple provisioning profiles installed that can be | ||
470 | + # used for ${bundle_identifier}, pick the most specific one (ie. the | ||
471 | + # provisioning profile whose pattern is the longest). | ||
472 | + selected_key = max(valid_provisioning_profiles, key=lambda v: len(v)) | ||
473 | + return valid_provisioning_profiles[selected_key] | ||
474 | + | ||
475 | + def _LoadProvisioningProfile(self, profile_path): | ||
476 | + """Extracts the plist embedded in a provisioning profile. | ||
477 | + | ||
478 | + Args: | ||
479 | + profile_path: string, path to the .mobileprovision file | ||
480 | + | ||
481 | + Returns: | ||
482 | + Content of the plist embedded in the provisioning profile as a dictionary. | ||
483 | + """ | ||
484 | + with tempfile.NamedTemporaryFile() as temp: | ||
485 | + subprocess.check_call([ | ||
486 | + 'security', 'cms', '-D', '-i', profile_path, '-o', temp.name]) | ||
487 | + return self._LoadPlistMaybeBinary(temp.name) | ||
488 | + | ||
489 | + def _MergePlist(self, merged_plist, plist): | ||
490 | + """Merge |plist| into |merged_plist|.""" | ||
491 | + for key, value in plist.iteritems(): | ||
492 | + if isinstance(value, dict): | ||
493 | + merged_value = merged_plist.get(key, {}) | ||
494 | + if isinstance(merged_value, dict): | ||
495 | + self._MergePlist(merged_value, value) | ||
496 | + merged_plist[key] = merged_value | ||
497 | + else: | ||
498 | + merged_plist[key] = value | ||
499 | + else: | ||
500 | + merged_plist[key] = value | ||
501 | + | ||
502 | + def _LoadPlistMaybeBinary(self, plist_path): | ||
503 | + """Loads into a memory a plist possibly encoded in binary format. | ||
504 | + | ||
505 | + This is a wrapper around plistlib.readPlist that tries to convert the | ||
506 | + plist to the XML format if it can't be parsed (assuming that it is in | ||
507 | + the binary format). | ||
508 | + | ||
509 | + Args: | ||
510 | + plist_path: string, path to a plist file, in XML or binary format | ||
511 | + | ||
512 | + Returns: | ||
513 | + Content of the plist as a dictionary. | ||
514 | + """ | ||
515 | + try: | ||
516 | + # First, try to read the file using plistlib that only supports XML, | ||
517 | + # and if an exception is raised, convert a temporary copy to XML and | ||
518 | + # load that copy. | ||
519 | + return plistlib.readPlist(plist_path) | ||
520 | + except: | ||
521 | + pass | ||
522 | + with tempfile.NamedTemporaryFile() as temp: | ||
523 | + shutil.copy2(plist_path, temp.name) | ||
524 | + subprocess.check_call(['plutil', '-convert', 'xml1', temp.name]) | ||
525 | + return plistlib.readPlist(temp.name) | ||
526 | + | ||
527 | + def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix): | ||
528 | + """Constructs a dictionary of variable substitutions for Entitlements.plist. | ||
529 | + | ||
530 | + Args: | ||
531 | + bundle_identifier: string, value of CFBundleIdentifier from Info.plist | ||
532 | + app_identifier_prefix: string, value for AppIdentifierPrefix | ||
533 | + | ||
534 | + Returns: | ||
535 | + Dictionary of substitutions to apply when generating Entitlements.plist. | ||
536 | + """ | ||
537 | + return { | ||
538 | + 'CFBundleIdentifier': bundle_identifier, | ||
539 | + 'AppIdentifierPrefix': app_identifier_prefix, | ||
540 | + } | ||
541 | + | ||
542 | + def _GetCFBundleIdentifier(self): | ||
543 | + """Extracts CFBundleIdentifier value from Info.plist in the bundle. | ||
544 | + | ||
545 | + Returns: | ||
546 | + Value of CFBundleIdentifier in the Info.plist located in the bundle. | ||
547 | + """ | ||
548 | + info_plist_path = os.path.join( | ||
549 | + os.environ['TARGET_BUILD_DIR'], | ||
550 | + os.environ['INFOPLIST_PATH']) | ||
551 | + info_plist_data = self._LoadPlistMaybeBinary(info_plist_path) | ||
552 | + return info_plist_data['CFBundleIdentifier'] | ||
553 | + | ||
554 | + def _InstallEntitlements(self, entitlements, substitutions, overrides): | ||
555 | + """Generates and install the ${BundleName}.xcent entitlements file. | ||
556 | + | ||
557 | + Expands variables "$(variable)" pattern in the source entitlements file, | ||
558 | + add extra entitlements defined in the .mobileprovision file and the copy | ||
559 | + the generated plist to "${BundlePath}.xcent". | ||
560 | + | ||
561 | + Args: | ||
562 | + entitlements: string, optional, path to the Entitlements.plist template | ||
563 | + to use, defaults to "${SDKROOT}/Entitlements.plist" | ||
564 | + substitutions: dictionary, variable substitutions | ||
565 | + overrides: dictionary, values to add to the entitlements | ||
566 | + | ||
567 | + Returns: | ||
568 | + Path to the generated entitlements file. | ||
569 | + """ | ||
570 | + source_path = entitlements | ||
571 | + target_path = os.path.join( | ||
572 | + os.environ['BUILT_PRODUCTS_DIR'], | ||
573 | + os.environ['PRODUCT_NAME'] + '.xcent') | ||
574 | + if not source_path: | ||
575 | + source_path = os.path.join( | ||
576 | + os.environ['SDKROOT'], | ||
577 | + 'Entitlements.plist') | ||
578 | + shutil.copy2(source_path, target_path) | ||
579 | + data = self._LoadPlistMaybeBinary(target_path) | ||
580 | + data = self._ExpandVariables(data, substitutions) | ||
581 | + if overrides: | ||
582 | + for key in overrides: | ||
583 | + if key not in data: | ||
584 | + data[key] = overrides[key] | ||
585 | + plistlib.writePlist(data, target_path) | ||
586 | + return target_path | ||
587 | + | ||
588 | + def _ExpandVariables(self, data, substitutions): | ||
589 | + """Expands variables "$(variable)" in data. | ||
590 | + | ||
591 | + Args: | ||
592 | + data: object, can be either string, list or dictionary | ||
593 | + substitutions: dictionary, variable substitutions to perform | ||
594 | + | ||
595 | + Returns: | ||
596 | + Copy of data where each references to "$(variable)" has been replaced | ||
597 | + by the corresponding value found in substitutions, or left intact if | ||
598 | + the key was not found. | ||
599 | + """ | ||
600 | + if isinstance(data, str): | ||
601 | + for key, value in substitutions.iteritems(): | ||
602 | + data = data.replace('$(%s)' % key, value) | ||
603 | + return data | ||
604 | + if isinstance(data, list): | ||
605 | + return [self._ExpandVariables(v, substitutions) for v in data] | ||
606 | + if isinstance(data, dict): | ||
607 | + return {k: self._ExpandVariables(data[k], substitutions) for k in data} | ||
608 | + return data | ||
609 | + | ||
610 | +if __name__ == '__main__': | ||
611 | + sys.exit(main(sys.argv[1:])) |
build/test.target.mk
0 → 100644
1 | +# This file is generated by gyp; do not edit. | ||
2 | + | ||
3 | +TOOLSET := target | ||
4 | +TARGET := test | ||
5 | +DEFS_Debug := \ | ||
6 | + '-DNODE_GYP_MODULE_NAME=test' \ | ||
7 | + '-DUSING_UV_SHARED=1' \ | ||
8 | + '-DUSING_V8_SHARED=1' \ | ||
9 | + '-DV8_DEPRECATION_WARNINGS=1' \ | ||
10 | + '-D_DARWIN_USE_64_BIT_INODE=1' \ | ||
11 | + '-D_LARGEFILE_SOURCE' \ | ||
12 | + '-D_FILE_OFFSET_BITS=64' \ | ||
13 | + '-DBUILDING_NODE_EXTENSION' \ | ||
14 | + '-DDEBUG' \ | ||
15 | + '-D_DEBUG' \ | ||
16 | + '-DV8_ENABLE_CHECKS' | ||
17 | + | ||
18 | +# Flags passed to all source files. | ||
19 | +CFLAGS_Debug := \ | ||
20 | + -O0 \ | ||
21 | + -gdwarf-2 \ | ||
22 | + -mmacosx-version-min=10.7 \ | ||
23 | + -arch x86_64 \ | ||
24 | + -Wall \ | ||
25 | + -Wendif-labels \ | ||
26 | + -W \ | ||
27 | + -Wno-unused-parameter | ||
28 | + | ||
29 | +# Flags passed to only C files. | ||
30 | +CFLAGS_C_Debug := \ | ||
31 | + -fno-strict-aliasing | ||
32 | + | ||
33 | +# Flags passed to only C++ files. | ||
34 | +CFLAGS_CC_Debug := \ | ||
35 | + -std=gnu++0x \ | ||
36 | + -stdlib=libc++ \ | ||
37 | + -fno-rtti \ | ||
38 | + -fno-exceptions \ | ||
39 | + -fno-threadsafe-statics \ | ||
40 | + -fno-strict-aliasing | ||
41 | + | ||
42 | +# Flags passed to only ObjC files. | ||
43 | +CFLAGS_OBJC_Debug := | ||
44 | + | ||
45 | +# Flags passed to only ObjC++ files. | ||
46 | +CFLAGS_OBJCC_Debug := | ||
47 | + | ||
48 | +INCS_Debug := \ | ||
49 | + -I/Users/fzy/.node-gyp/8.2.1/include/node \ | ||
50 | + -I/Users/fzy/.node-gyp/8.2.1/src \ | ||
51 | + -I/Users/fzy/.node-gyp/8.2.1/deps/uv/include \ | ||
52 | + -I/Users/fzy/.node-gyp/8.2.1/deps/v8/include | ||
53 | + | ||
54 | +DEFS_Release := \ | ||
55 | + '-DNODE_GYP_MODULE_NAME=test' \ | ||
56 | + '-DUSING_UV_SHARED=1' \ | ||
57 | + '-DUSING_V8_SHARED=1' \ | ||
58 | + '-DV8_DEPRECATION_WARNINGS=1' \ | ||
59 | + '-D_DARWIN_USE_64_BIT_INODE=1' \ | ||
60 | + '-D_LARGEFILE_SOURCE' \ | ||
61 | + '-D_FILE_OFFSET_BITS=64' \ | ||
62 | + '-DBUILDING_NODE_EXTENSION' | ||
63 | + | ||
64 | +# Flags passed to all source files. | ||
65 | +CFLAGS_Release := \ | ||
66 | + -Os \ | ||
67 | + -gdwarf-2 \ | ||
68 | + -mmacosx-version-min=10.7 \ | ||
69 | + -arch x86_64 \ | ||
70 | + -Wall \ | ||
71 | + -Wendif-labels \ | ||
72 | + -W \ | ||
73 | + -Wno-unused-parameter | ||
74 | + | ||
75 | +# Flags passed to only C files. | ||
76 | +CFLAGS_C_Release := \ | ||
77 | + -fno-strict-aliasing | ||
78 | + | ||
79 | +# Flags passed to only C++ files. | ||
80 | +CFLAGS_CC_Release := \ | ||
81 | + -std=gnu++0x \ | ||
82 | + -stdlib=libc++ \ | ||
83 | + -fno-rtti \ | ||
84 | + -fno-exceptions \ | ||
85 | + -fno-threadsafe-statics \ | ||
86 | + -fno-strict-aliasing | ||
87 | + | ||
88 | +# Flags passed to only ObjC files. | ||
89 | +CFLAGS_OBJC_Release := | ||
90 | + | ||
91 | +# Flags passed to only ObjC++ files. | ||
92 | +CFLAGS_OBJCC_Release := | ||
93 | + | ||
94 | +INCS_Release := \ | ||
95 | + -I/Users/fzy/.node-gyp/8.2.1/include/node \ | ||
96 | + -I/Users/fzy/.node-gyp/8.2.1/src \ | ||
97 | + -I/Users/fzy/.node-gyp/8.2.1/deps/uv/include \ | ||
98 | + -I/Users/fzy/.node-gyp/8.2.1/deps/v8/include | ||
99 | + | ||
100 | +OBJS := \ | ||
101 | + $(obj).target/$(TARGET)/test.o | ||
102 | + | ||
103 | +# Add to the list of files we specially track dependencies for. | ||
104 | +all_deps += $(OBJS) | ||
105 | + | ||
106 | +# CFLAGS et al overrides must be target-local. | ||
107 | +# See "Target-specific Variable Values" in the GNU Make manual. | ||
108 | +$(OBJS): TOOLSET := $(TOOLSET) | ||
109 | +$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) | ||
110 | +$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) | ||
111 | +$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE)) | ||
112 | +$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE)) | ||
113 | + | ||
114 | +# Suffix rules, putting all outputs into $(obj). | ||
115 | + | ||
116 | +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD | ||
117 | + @$(call do_cmd,cxx,1) | ||
118 | + | ||
119 | +# Try building from generated source, too. | ||
120 | + | ||
121 | +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD | ||
122 | + @$(call do_cmd,cxx,1) | ||
123 | + | ||
124 | +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD | ||
125 | + @$(call do_cmd,cxx,1) | ||
126 | + | ||
127 | +# End of this set of suffix rules | ||
128 | +### Rules for final target. | ||
129 | +LDFLAGS_Debug := \ | ||
130 | + -undefined dynamic_lookup \ | ||
131 | + -Wl,-no_pie \ | ||
132 | + -Wl,-search_paths_first \ | ||
133 | + -mmacosx-version-min=10.7 \ | ||
134 | + -arch x86_64 \ | ||
135 | + -L$(builddir) \ | ||
136 | + -stdlib=libc++ | ||
137 | + | ||
138 | +LIBTOOLFLAGS_Debug := \ | ||
139 | + -undefined dynamic_lookup \ | ||
140 | + -Wl,-no_pie \ | ||
141 | + -Wl,-search_paths_first | ||
142 | + | ||
143 | +LDFLAGS_Release := \ | ||
144 | + -undefined dynamic_lookup \ | ||
145 | + -Wl,-no_pie \ | ||
146 | + -Wl,-search_paths_first \ | ||
147 | + -mmacosx-version-min=10.7 \ | ||
148 | + -arch x86_64 \ | ||
149 | + -L$(builddir) \ | ||
150 | + -stdlib=libc++ | ||
151 | + | ||
152 | +LIBTOOLFLAGS_Release := \ | ||
153 | + -undefined dynamic_lookup \ | ||
154 | + -Wl,-no_pie \ | ||
155 | + -Wl,-search_paths_first | ||
156 | + | ||
157 | +LIBS := | ||
158 | + | ||
159 | +$(builddir)/test.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) | ||
160 | +$(builddir)/test.node: LIBS := $(LIBS) | ||
161 | +$(builddir)/test.node: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE)) | ||
162 | +$(builddir)/test.node: TOOLSET := $(TOOLSET) | ||
163 | +$(builddir)/test.node: $(OBJS) FORCE_DO_CMD | ||
164 | + $(call do_cmd,solink_module) | ||
165 | + | ||
166 | +all_deps += $(builddir)/test.node | ||
167 | +# Add target alias | ||
168 | +.PHONY: test | ||
169 | +test: $(builddir)/test.node | ||
170 | + | ||
171 | +# Short alias for building this executable. | ||
172 | +.PHONY: test.node | ||
173 | +test.node: $(builddir)/test.node | ||
174 | + | ||
175 | +# Add executable to "all" target. | ||
176 | +.PHONY: all | ||
177 | +all: $(builddir)/test.node | ||
178 | + |
demo/a.out
0 → 100755
不能预览此文件类型
demo/demo.cpp
0 → 100644
test.cc
0 → 100644
1 | +#include <node.h> | ||
2 | +#include <v8.h> | ||
3 | + | ||
4 | +using namespace v8; | ||
5 | + | ||
6 | +// 传入了两个参数,args[0] 字符串,args[1] 回调函数 | ||
7 | +void hello(const FunctionCallbackInfo<Value>& args) { | ||
8 | + // 使用 HandleScope 来管理生命周期 | ||
9 | + Isolate* isolate = Isolate::GetCurrent(); | ||
10 | + HandleScope scope(isolate); | ||
11 | + | ||
12 | + // 判断参数格式和格式 | ||
13 | + if (args.Length() < 2 || !args[0]->IsString()) { | ||
14 | + isolate->ThrowException(Exception::TypeError( | ||
15 | + String::NewFromUtf8(isolate, "Wrong arguments"))); | ||
16 | + return; | ||
17 | + } | ||
18 | + | ||
19 | + // callback, 使用Cast方法来转换 | ||
20 | + Local<Function> callback = Local<Function>::Cast(args[1]); | ||
21 | + Local<Value> argv[1] = { | ||
22 | + // 拼接String | ||
23 | + String::Concat(Local<String>::Cast(args[0]), String::NewFromUtf8(isolate, " world")) | ||
24 | + }; | ||
25 | + // 调用回调, 参数: 当前上下文,参数个数,参数列表 | ||
26 | + callback->Call(isolate->GetCurrentContext()->Global(), 1, argv); | ||
27 | +} | ||
28 | + | ||
29 | +// 相当于在 exports 对象中添加 { hello: hello } | ||
30 | +void init(Handle<Object> exports) { | ||
31 | + NODE_SET_METHOD(exports, "hello", hello); | ||
32 | +} | ||
33 | + | ||
34 | +// 将 export 对象暴露出去 | ||
35 | +// 原型 `NODE_MODULE(module_name, Initialize)` | ||
36 | +NODE_MODULE(test, init); | ||
37 | + |
test2c++.js
0 → 100644
-
请 注册 或 登录 后发表评论