付智勇

no message

  1 +{
  2 + "targets": [
  3 + {
  4 + "target_name": "test",
  5 + "sources": [ "test.cc" ]
  6 + }
  7 + ]
  8 +}
  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:
  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
不能预览此文件类型
不能预览此文件类型
  1 +# This file is generated by gyp; do not edit.
  2 +
  3 +export builddir_name ?= ./build/.
  4 +.PHONY: all
  5 +all:
  6 + $(MAKE) test
  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 +}
  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:]))
  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 +
不能预览此文件类型
  1 +#include <iostream>
  2 +using namespace std;
  3 +
  4 +int main()
  5 +{
  6 + cout << "Hello World"; // 输出 Hello World
  7 +
  8 + return 0;
  9 +}
  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 +
  1 +var test = require('./build/Release/test');
  2 +test.hello('test', function(data) {
  3 + console.log(data);
  4 +});