Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: site/user/sample/building.md

Issue 834353003: Adding user doc section and core files for new site (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: One more fix to android.md Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « site/user/quick/windows.md ('k') | site/user/sample/hello.md » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 Building with Skia Tutorial
2 ===========================
3
4 dsinclair@chromium.org
5
6
7 This document describes the steps used to create an application that uses Skia. The assumptions are that you're using:
8
9 * [git](http://git-scm.com)
10 * [gclient](https://code.google.com/p/gclient/)
11 * [gyp](https://code.google.com/p/gyp/)
12 * [ninja](http://martine.github.io/ninja/)
13
14 I'm going to describe up to the point where we can build a simple application th at prints out an SkPaint.
15
16 Overview
17 --------
18
19 1. Create remote repository.
20 1. Configure and sync using gclient.
21 1. Create DEPS file to pull in third party repositories.
22 1. Setup gitignore for directories pulled in from DEPS.
23 1. Configure GYP.
24 1. Setup GYP auto-run when gclient sync is executed.
25
26 gclient setup
27 -------------
28 The first step is to setup a remote git repo, take your pick of provider. In
29 my case, the repo is called UsingSkia and lives on
30 [bitbucket](https://bitbucket.org).
31
32 With the remote repo created, we create a .gclient configuration file. The
33 gclient config command will write the file for us:
34
35 $ gclient config --name=src https://bitbucket.org/dj2/usingskia.git
36
37 This will create the following:
38
39 solutions = [
40 { "name" : "src",
41 "url" : "https://bitbucket.org/dj2/usingskia.git",
42 "deps_file" : "DEPS",
43 "managed" : True,
44 "custom_deps" : {
45 },
46 "safesync_url": "",
47 },
48 ]
49 cache_dir = None
50
51 The name that we configured is the directory in which the repo will be checked
52 out. This is done by running gclient sync. There is a bit of magic that
53 gclient does around the url to determine if the repo is SVN or GIT. I've found
54 the use of ssh:// and the .git on the end seem to work to get the right SCM
55 type.
56
57 $ gclient sync
58
59 This should execute a bunch of commands (and, in this case, may end with an
60 error because the repo was empty. That seems to be fine.) When finished, you
61 should have a src directory with your git repository checked out.
62
63 DEPS
64 ----
65
66 With the repo created we can go ahead and create our src/DEPS file. The DEPS
67 file is used by gclient to checkout the dependent repositories of our
68 application. In this case, the Skia repository.
69
70 Create a src/DEPS file with the following:
71
72 ~~~~
73
74 vars = {
75 "skia_revision": "a6a8f00a3977e71dbce9da50a32c5e9a51c49285",
76 }
77
78 deps = {
79 "src/third_party/skia/":
80 "http://skia.googlecode.com/skia.git@" + Var("skia_revision"),
81 }
82
83 ~~~~
84
85 There are two sections to the `DEPS` file at the moment, `vars` and `deps`.
86 The `vars` sections defines variables we can use later in the file with the
87 `Var()` accessor. In this case, we define our root directory, a shorter name
88 for any googlecode repositories and a specific revision of Skia that we're
89 going to use. I've pinned to a specific version to insulate the application
90 from changes in the Skia tree. This lets us know that when someone checks out
91 the repo they'll be using the same version of Skia that we've built and tested
92 against.
93
94 The `deps` section defines our dependencies. Currently we have one dependency
95 which we're going to checkout into the `src/third_party/skia` directory.
96
97 Once the deps file is created, commit and push it to the remote repository.
98 Once done, we can use gclient to checkout our dependencies.
99
100 $ gclient sync
101
102 This should output a whole bunch of lines about files that are being added to
103 your project. This may also be a good time to create a `.gitignore` file. You
104 don't want to check the `third_party/skia directory` into your repository as
105 it's being managed by gclient.
106
107 Now, we've run into a problem. Skia itself has a `DEPS` file which defines the
108 `third_party` libraries it needs to build. None of those dependencies are being
109 checked out so Skia will fail to build.
110
111 The way I found around that is to add a second solution to the `.gclient`
112 file. This solution tells gclient about Skia and will pull in the needed
113 dependencies. I edited my `.gclient` file (created by the `gclient config`
114 command above) to look as follows:
115
116 solutions = [
117 { "name" : "src",
118 "url" : "https://bitbucket.org/dj2/usingskia.git",
119 "deps_file" : "DEPS",
120 "managed" : True,
121 "custom_deps" : {
122 },
123 "safesync_url": "",
124 },
125 { "name" : "src/third_party/skia",
126 "url" : "http://skia.googlecode.com/skia.git@a6a8f00a3977e71dbce 9da50a32c5e9a51c49285",
127 "deps_file" : "DEPS",
128 "managed" : True,
129 "custom_deps" : {
130 },
131 "safesync_url": "",
132 },
133 ]
134 cache_dir = None
135
136 This is a little annoying at the moment since I've duplicated the repository
137 revision number in the `.gclient` file. I'm hoping to find a way to do this
138 through the `DEPS` file, but until then, this seems to work.
139
140 With that done, re-run `gclient sync` and you should see a whole lot more
141 repositories being checked out. The
142 `src/third_party/skia/third_party/externals` directory should now be
143 populated.
144
145 GYP
146 ---
147
148 The final piece of infrastructure we need to set up is GYP. GYP is a build
149 system generator, in this project we're going to have it build ninja
150 configuration files.
151
152 First, we need to add GYP to our project. We'll do that by adding a new entry
153 to the deps section of the `DEPS` file.
154
155 "src/tools/gyp":
156 (Var("googlecode_url") % "gyp") + "/trunk@1700",
157
158 As you can see, I'm going to put the library into `src/tools/gyp` and checkout
159 revision 1700 (note, the revision used here, 1700, was the head revision at
160 the time the `DEPS` file was written. You're probably safe to use the
161 tip-of-tree revision in your `DEPS` file). A quick `gclient sync` and we
162 should have everything checked out.
163
164 In order to run GYP we'll create a wrapper script. I've called this
165 `src/build/gyp_using_skia`.
166
167 ~~~~
168 #!/usr/bin/python
169 import os
170 import sys
171
172 script_dir = os.path.dirname(__file__)
173 using_skia_src = os.path.abspath(os.path.join(script_dir, os.pardir))
174
175 sys.path.insert(0, os.path.join(using_skia_src, 'tools', 'gyp', 'pylib'))
176 import gyp
177
178 if __name__ == '__main__':
179 args = sys.argv[1:]
180
181 if not os.environ.get('GYP_GENERATORS'):
182 os.environ['GYP_GENERATORS'] = 'ninja'
183
184 args.append('--check')
185 args.append('-I%s/third_party/skia/gyp/common.gypi' % using_skia_src)
186
187 args.append(os.path.join(script_dir, '..', 'using_skia.gyp'))
188
189 print 'Updating projects from gyp files...'
190 sys.stdout.flush()
191
192 sys.exit(gyp.main(args))
193 ~~~~
194
195 Most of this is just setup code. The two interesting bits are:
196
197 1. `args.append('-I%s/third_party/skia/gyp/common.gypi' % using_skia_src)`
198 1. `args.append(os.path.join(script_dir, '..', 'using_skia.gyp'))`
199
200 In the case of 1, we're telling GYP to include (-I) the
201 `src/third_party/skia/gyp/common.gypi` file which will define necessary
202 variables for Skia to compile. In the case of 2, we're telling GYP that the
203 main configuration file for our application is `src/using_skia.gyp`.
204
205 The `src/using_skia.gyp` file is as follows:
206
207 ~~~~
208 {
209 'targets': [
210 {
211 'configurations': {
212 'Debug': { },
213 'Release': { }
214 },
215 'target_name': 'using_skia',
216 'type': 'executable',
217 'dependencies': [
218 'third_party/skia/gyp/skia_lib.gyp:skia_lib'
219 ],
220 'include_dirs': [
221 'third_party/skia/include/config',
222 'third_party/skia/include/core',
223 ],
224 'sources': [
225 'app/main.cpp'
226 ],
227 'ldflags': [
228 '-lskia', '-stdlib=libc++', '-std=c++11'
229 ],
230 'cflags': [
231 '-Werror', '-W', '-Wall', '-Wextra', '-Wno-unused-parameter', '-g', '-O0 '
232 ]
233 }
234 ]
235 }
236 ~~~~
237
238 There is a lot going on in there, I'll touch on some of the highlights. The
239 `configurations` section allows us to have different build flags for our `Debug`
240 and `Release` build (in this case they're the same, but I wanted to define
241 them.) The `target_name` defines the name of the build target which we'll
242 provide to ninja. It will also be the name of the executable that we build.
243
244 The dependencies section lists our build dependencies. These will be built
245 before our sources are built. In this case, we depend on the `skia_lib` target
246 inside `third_party/skia/gyp/skia_lib.gyp`.
247
248 The include_dirs will be added to the include path when our files are built.
249 We need to reference code in the config and core directories of Skia.
250
251 `sources`, `ldflags` and `cflags` should be obvious.
252
253 Our application is defined in `src/app/main.cpp` as:
254
255 ~~~~
256 #include "SkPaint.h"
257 #include "SkString.h"
258
259 int main(int argc, char** argv) {
260 SkPaint paint;
261 paint.setColor(SK_ColorRED);
262
263 SkString* str = new SkString();
264 paint.toString(str);
265
266 fprintf(stdout, "%s\n", str->c_str());
267
268 return 0;
269 }
270 ~~~~
271
272 We're just printing out an SkPaint to show that everything is linking correctly.
273
274 Now, we can run:
275
276 $ ./build/gyp_using_skia
277
278 And, we get an error. Turns out, Skia is looking for a `find\_mac\_sdk.py` file in
279 a relative tools directory which doesn't exist. Luckily, that's easy to fix
280 with another entry in our DEPS file.
281
282 "src/tools/":
283 File((Var("googlecode_url") % "skia") + "/trunk/tools/find_mac_sdk.py@" +
284 Var("skia_revision")),
285
286 Here we using the `File()` function of `gclient` to specify that we're checking
287 out an individual file. Running `gclient sync` should pull the necessary file
288 into `src/tools`.
289
290 With that, running `build/gyp\_using\_skia` should complete successfully. You
291 should now have an `out/` directory with a `Debug/` and `Release/` directory ins ide.
292 These correspond to the configurations we specified in `using\_skia.gyp`.
293
294 With all that out of the way, if you run:
295
296 $ ninja -C out/Debug using_skia
297
298 The build should execute and you'll end up with an `out/Debug/using\_skia` which
299 when executed, prints out our SkPaint entry.
300
301 Autorun GYP
302 -----------
303
304 One last thing, having to run `build/gyp\_using\_skia` after each sync is a bit of
305 a pain. We can fix that by adding a `hooks` section to our `DEPS` file. The `hoo ks`
306 section lets you list a set of hooks to execute after `gclient` has finished the
307 sync.
308
309 hooks = [
310 {
311 # A change to a .gyp, .gypi or to GYP itself should run the generator.
312 "name": "gyp",
313 "pattern": ".",
314 "action": ["python", "src/build/gyp_using_skia"]
315 }
316 ]
317
318 Adding the above to the end of DEPS and running gclient sync should show the
319 GYP files being updated at the end of the sync procedure.
320
OLDNEW
« no previous file with comments | « site/user/quick/windows.md ('k') | site/user/sample/hello.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698