Skip to content

Commit

Permalink
Update documentation - closes #77
Browse files Browse the repository at this point in the history
  • Loading branch information
17451k committed Mar 22, 2019
1 parent f95f14b commit b712008
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 22 deletions.
97 changes: 76 additions & 21 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Build command intercepting
--------------------------


Clade implements several different methods to intercept build commands.
Clade implements several different methods of build commands intercepting.


Library injection
Expand Down Expand Up @@ -215,7 +215,33 @@ You can intercept build commands with wrappers from a python script:
Windows debugging API
~~~~~~~~~~~~~~~~~~~~~
To be written.
Wrappers and library injection works only on Linux and macOS.
To intercept build commands on Windows we have implemented another approach
that is based on the Windows debugging API.
The API provides the mechanism for the debugger to be notified of debug events
from the process being debugged and to pause the target process until the
event has been processed.
We have developed a simple debugger that can be used to debug the build
process.
It waits for the process start events, which corresponds to the execution of the build
command, pauses the build process and reads memory of the newly created process
to find and log its command line arguments, and then resumes the build process.
It can be used like this:
.. code-block:: bash
$ clade-intercept msbuild MyProject.sln
You can intercept build commands on Windows from a python script:
.. code-block:: python
from clade import Clade
c = Clade(cmds_file="cmds.txt")
c.intercept(command=["msbuild", "MyProject.sln])
Content of *cmds.txt* file
Expand Down Expand Up @@ -325,7 +351,7 @@ As a result, a working directory named *clade* will be created:
│   ├── cmds/
│   ├── deps/
│   ├── opts/
│   └── unparsed/
│   └── raw/
├── PidGraph/
└── Storage/
Expand All @@ -344,33 +370,57 @@ Let's look at the parsed command from the above example:
.. code-block:: json
{
"command":"gcc",
"cwd":"/work/simple_make",
"id":"3",
"in":[
"main.c"
],
"opts":[
"-O3"
],
"out":[
"main"
]
}
Its structure is quite simple: there is a list of input files,
a list of output files, a list of options, and some other info that is
self-explanatory.
a list of output files, unique identifier of the command, and
the directory where the command was executed.
Using the identifier of the command it is possible to get some additional information,
like its options.
Options of all parsed commands are located in the separated json files
inside *opts* folder.
Options of the command with *id="3"* are located in the *opts/3.json* file
and look like this:
.. code-block:: json
[
"-O3"
]
Raw unparsed commands are located in the *raw* folder.
Its structure resembles the structure of the *opts* folder, so the
raw command of the command with id = 3 is located in the "raw/3.json file
and look like this:
.. code-block:: json
[
"gcc",
"main.c",
"-o",
"main",
"-O3"
],
*CC* extension also identify *dependencies* of the main source file
for each compilation command.
Dependencies are the names of all included header files,
even ones included indirectly.
Clade stores them inside *deps* subfolder.
For example, dependencies of the parsed command with id="3" can be found
For example, dependencies of the parsed command with *id="3"* can be found
in *deps/3.json* file:
::
.. code-block:: json
[
"/usr/include/secure/_common.h",
Expand Down Expand Up @@ -410,7 +460,7 @@ in *deps/3.json* file:
Besides dependencies, all other parsed commands (ld, mv, and so on)
will also look this way: as a list of dictionaries representing each
parsed command, with "command", "id", "in", "opts" and "out" fields.
parsed command, with "id", "in", "out" and "cwd" fields.
All data generated by *CC* extension (and by all other extensions, of course)
can also be used through Python interface:
Expand All @@ -426,7 +476,11 @@ can also be used through Python interface:
# Get a list of all parsed commands
for cmd in c.get_all_cmds_by_type("CC"):
# Get a list of dependencies
deps = c.get_cc_deps(cmd["id"])
deps = c.get_cmd_deps(cmd["id"])
# Get options
opts = c.get_cmd_opts(cmd["id])
# Get raw unparsed command
raw = c.get_cmd_raw(cmd["id])
...
Pid graph
Expand Down Expand Up @@ -881,12 +935,13 @@ to parse. They have a list of predefined regular expressions that they try
to match with the *which* field of an intercepted command.
For example, *CC* extension have the following list:
.. code-block:: python
.. code-block:: json
which_list = [
r"^.*cc$",
r"^.*[mg]cc(-?\d+(\.\d+){0,2})?$",
r"^.*clang(-?\d+(\.\d+){0,2})?$"
[
"cc$",
"cc1$",
"[mg]cc(-?\\d+(\\.\\d+){0,2})?$",
"clang(-?\\d+(\\.\\d+){0,2})?$"
]
Obviously, execution of */usr/bin/gcc* will be matched, as well as
Expand Down Expand Up @@ -923,13 +978,13 @@ List of commands to parse
If you want to generate *command graph*, or *source graph*, or *call graph*,
then you need to specify which commands to parse via "CmdGraph.requires"
option. If you want to parse all commands that are supported now, then
the value of this option will be:
option. By default all commands that are supported now are parsed,
but you can reduce their number:
.. code-block:: json
{
"CmdGraph.requires": ["CC", "LD", "MV", "AR", "Objcopy"]
"CmdGraph.requires": ["CC", "LD""]
}
Presets
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def finalize_options(self):

setuptools.setup(
name="clade",
version="2.2.dev1",
version="3.0",
author="Ilya Shchepetkov",
author_email="shchepetkov@ispras.ru",
url="https://github.com/17451k/clade",
Expand Down

0 comments on commit b712008

Please sign in to comment.