blob: 2f89e817f3af69799247145c5b1b216c552d65c9 [file] [log] [blame] [view]
Mark Cogan0abda9652020-04-15 11:22:071# Working With Files
2
3Adding, removing, and renaming files in iOS Chromium needs to follow a specific
4procedure that will be unfamiliar to engineers coming from other iOS projects.
5Conceptually, every file is recorded in _four_ locations: the local filesystem,
6git, the `BUILD.gn` files, and the XCode projects. Of these, the XCode project
7is wholly generated from the others.
8
9[TOC]
10
11## Overview
12
13**Do not use XCode to manipulate files.** The XCode project used for iOS
14Chromium is _generated_; it's functionally a build artifact. The various
15`BUILD.gn` files in Chromium define structure of the XCode project file. Running
16`gclient runhooks` causes the project files to be regenerated.
17
18Individual files can have their contents edited within XCode, and all of the
19regular testing and debugging activities can be done within XCode. It just can't
20be used to create files, rename files, delete files, or manipulate the project
21group structure in any way. To do these things, follow the procedures below.
22
23## Adding files
24
25To add any files (new headers, `.mm` or `.cc` implementation files, asset files
26of any kind), the following general steps need to happen:
27
281. The file needs to exist in the correct directory of the file system for your
29 Chromium checkout. New files need to be created, or assets need to be
30 copied to the right location.
31
321. The new files need to be added to git.
33
341. The new files need to be added to a target in a `BUILD.gn` file (usually in
35 the same directory as the newly added file).
36
371. The XCode project needs to be regenerated.
38
39For adding new header or implementation files, the following procedure is
40recommended:
41
Tommy Martinoe8e980f2021-10-14 15:19:48421. Generate the new files using `tools/boilerplate.py`. This will generate
43 header guard macros and include the copyright boilerplate. Make sure to run
44 this from root (`src/`) so the header guards include the correct, full
45 path.
Mark Cogan0abda9652020-04-15 11:22:0746
472. Add the newly created files using `git add`.
48
493. Edit the `BUILD.gn` file for the directory where the files were added. For
50 each file, add it to the `sources` list for the correct `source_set` in the
51 `BUILD.gn` file. Note that `gn format` (which is run as part of `git cl
52 format`) will take care of alphabetizing the lists along with other
53 formatting, so there's no need to manually do these things. (`BUILD.gn`
54 files cand be edited directly in XCode, or in another editor such as `vi`).
55
564. Once all of the files have been created, `add`ed and all `BUILD.gn` files
57 have been updated, run `gclient runhooks` to regenerate all XCode projects.
58
595. If XCode is open, it may prompt to "Autocreate Schemes". If so, click on the
60 highlighted "Automatically Create Schemes" button.
61
62In the shell, this procedure would look like this:
63```bash
64// Step 1 -- generate new files.
65$ tools/boilerplate.py ios/chrome/browser/some_feature/feature_class.h
66$ tools/boilerplate.py ios/chrome/browser/some_feature/feature_class.mm
67$ tools/boilerplate.py ios/chrome/browser/some_feature/feature_class_unittest.mm
68// Step 2 -- add the new files.
69$ git add ios/chrome/browser/some_feature/feature_class*
70// Step 3 -- edit the BUILD.gn file in the editor of your choice
71$ vi ios/chrome/browser/some_feature/BUILD.gn
72// Step 4 -- regenerate the XCode Projects
73$ gclient runhooks
74```
75
76To add asset files, follow this procedure:
77
781. Copy the asset files to the correct directory, with the correct names
79 (including `@2x` and `@3x` suffixes) Note that images are stored in
80 `.imageset` directories, conventionally inside `resources` directories for a
81 given UI feature. New directories, if needed, are created in the usual way
82 (`mkdir`). Note that there is no equivalent of `boilerplate.py` for images
83 or other asset files.
84
851. Create or copy `Contents.json` files for each new `.imageset` directory,
86 with the appropriate contents.
87
881. Add all image and `Contents.json` files using `git add`.
89
901. Edit the `BUILD.gn` file in the containing `resources` directory, adding
91 `imageset` entries for each added `.imageset` directory, and then grouping
92 all assets into a new or existing `group()` declaration with a `public_deps`
93 list containing all of the `imageset` targets.
94
951. Regenerate the XCode project with `gclient runhooks`.
96
97To add Markdown documentation files, the procedure is much simpler. These files
98are automatically added to the XCode project without `BUILD.gn` entries, and
99they have no required boilerplate. So adding new docs is as simple as:
100
1011. Create a new `.md` file in the appropriate directory (`docs/ios`, for
102 example).
103
1041. `git add` the file.
105
106The newly added file will be visible in XCode after the next `gclient runhooks`.
107
108## Moving and renaming files.
109
110Renaming a file involves updating the filename in all of the places where it
111exists: the file names in the filesystem, the file names in git, header guards
112in files, import declarations in files, listings in BUILD.gn files, and
113internally in the XCode project. As with adding a file, different tools are used
114for each of these. Unlike creating a file, which starts with actually adding a
115file to the filesystem, a rename starts with updating git (via `git mv`), then
Caleb Raittod6bba3d2020-10-29 14:58:32116using the `mass-rename` tool to update file contents.
Mark Cogan0abda9652020-04-15 11:22:07117
Caleb Raittod6bba3d2020-10-29 14:58:32118`tools/git/mass-rename.py` works by looking at _uncommitted_ file moves in git,
Mark Cogan0abda9652020-04-15 11:22:07119and then updating all includes, header guards, and BUILD.gn entries to use the
120new name. It doesn't update some other files, such as `Contents.json` files for
121image assets. It also doesn't change any symbols in code, so class and variable
122names won't be changed.
123
124For many file moves, it will be simpler to use another tool,
Caleb Raittod6bba3d2020-10-29 14:58:32125`tools/git/move_source_file.py`, which combines `git mv` and `mass-rename` in a
Mark Cogan0abda9652020-04-15 11:22:07126single action. For example, renaming `feature_class` to `renamed_class` would be
127done like this:
128```bash
129 $ tools/git/move_source_file.py ios/chrome/browser/some_feature/feature_class.h \
130 ios/chrome/browser/some_feature/renamed_class.h
131 $ tools/git/move_source_file.py ios/chrome/browser/some_feature/feature_class.mm \
132 ios/chrome/browser/some_feature/renamed_class.mm
133```
134
135The step-by-step procedure for a rename is:
136
1371. If there are other uncommitted changes before the move, it's usually
138 cleanest to commit before starting the move.
139
1401. `move_source_file` each file that needs to be renamed. This renames the file
141 in both the file system and in git, and in most places where it's used in
142 code.
143
1441. Run `gclient runhooks` to update the XCode project. Check that all of the
145 needed name changes have been made (for example, by building all targets).
146 Make any other needed fixes.
147
1481. If any classes or other symbols need to be renamed (remember that the name
149 of the primary interface in each file must match the file name), make those
150 changes. Find-and-replace tools like `tools/git/mffr.py` or XCode's
151 Find/Replace can help here, but there are no compiler-aware tools that can
152 do a "smart" rename.
153
1541. Commit all changes (`git commit -a -m <your comment>`).
155
156A move—where a file is moved to a different directory—is in most respects
Caleb Raittod6bba3d2020-10-29 14:58:32157performed using the same steps as a rename. However, while `mass-rename.py` (and
Mark Cogan0abda9652020-04-15 11:22:07158thus `move_source_file.py`) will update existing file names in `BUILD.gn` files,
159it won't move entries from one `BUILD.gn` file to another. To move files to a
160different directory, the preceding procedure is used, but between steps 2 and 3
161(after moving the files, but before regenerating the XCode project), the old
162filenames will need to be removed from the `BUILD.gn` files in the old
163directories and added to the `BUILD.gn` files in the new directories.
164
165Also note that while `move_source_file` must be used separately for each file
166being renamed within a directory, it (just like `git mv`) can move multiple
167files without renaming to a new directory in a single command:
168
169```bash
Caleb Raittod6bba3d2020-10-29 14:58:32170$ tools/git/mass-rename.py ios/chrome/browser/some_feature/feature_class.* \
Mark Cogan0abda9652020-04-15 11:22:07171 ios/chrome/browser/some_feature/feature_class_unittest.mm \
172 ios/chrome/browser/other_feature/
173```
174
175## Deleting files.
176
177Deleting files follows the same patterns as adding and moving files. As with a
178file move, it's best to begin with deleting the files from git.
179
180Typically, before actually removing a file, first all usage of the interface(s)
181in the file(s) will be removed, and the file will no longer be `#imported`
182anywhere.
183
184Step-by step:
185
1861. `git rm` the files you want to remove. This will also remove the files
187 from the filesystem.
188
1891. Manually remove the `BUILD.gn` entries for the files.
190
1911. Regenerate the XCode project (with `gclient runhooks`) to remove the files
192 from XCode.
193
194## Finally.
195
196It's easy to miss some uses of a file that was renamed or deleted, and fixing
197compilation errors discovered in the commit queue means another
198commit-upload-dry run cycle (at least). To minimize this, after any change that
199adds, renames, moves, or deletes files, be sure to take the following steps:
200
2011. `git cl format` to update the formatting of all files.
202
2031. `gn check` to make sure that any new or moved files follow the dependency
204 rules (for example: `gn check -C out/Debug-iphonesimulator/`).
205
2061. Build all targets, to make sure that everything has been added, changed, or
207 removed correctly. This can be done by selecting the "All" target in XCode
208 and building (`⌘-B`), or from the command line (for example, `autoninja -C
209 out/Debug-iphonesimulator/`).
210
211Changes that involve adding or deleting more than a few files, and most renames
212of any size, should be in a single CL with no other changes, for ease of
213reviewing and (if necessary) reverting or cherry-picking.
214
215## Recovering from accidental XCode Project usage.
216
217If files are accidentally added, renamed, or moved through XCode, other settings
218in the XCode project may be changed that will introduce strange local build
219failures. In this case, take the following steps to recover.
220
2211. Quit XCode.
222
2231. Delete all generated XCode projects and associated files: `rm -rf out/build`.
224
2251. Regenerate all XCode projects: `gclient runhooks`.