214 lines
6.6 KiB
Markdown
214 lines
6.6 KiB
Markdown
|
# Hacking on PJProject
|
||
|
|
||
|
## Intro
|
||
|
There are times when you need to troubleshoot issues with bundled pjproject
|
||
|
or add new features that need to be pushed upstream but...
|
||
|
|
||
|
* The source directory created by extracting the pjproject tarball is not
|
||
|
scanned for code changes so you have to keep forcing rebuilds.
|
||
|
* The source directory isn't a git repo so you can't easily create patches,
|
||
|
do git bisects, etc.
|
||
|
* Accidentally doing a make distclean will ruin your day by wiping out the
|
||
|
source directory, and your changes.
|
||
|
* etc.
|
||
|
|
||
|
Well No More!
|
||
|
|
||
|
You can now replace the `source` directory that's normally created
|
||
|
by the Makefile extracting the tarball, with a symlink to a "real" pjproject
|
||
|
git clone. The Makefile will now detect that `source` is a real pjproject
|
||
|
repo and enable some advanced behaviors (and disable others).
|
||
|
|
||
|
## Setup
|
||
|
|
||
|
Let's assume you have an Asterisk development environment like so:
|
||
|
|
||
|
```plain
|
||
|
~/dev/asterisk/
|
||
|
asterisk/
|
||
|
.git/
|
||
|
addons/
|
||
|
...
|
||
|
third-party/
|
||
|
jansson/
|
||
|
pjproject/
|
||
|
```
|
||
|
|
||
|
### Cloning pjproject
|
||
|
|
||
|
Start by cloning a pjproject repository next to your asterisk repository.
|
||
|
The source of the clone depends on whether you anticipate pushing changes
|
||
|
back upstream or not. If you already have a good pjproject repository clone,
|
||
|
read this section anyway but you probably won't have to do anything.
|
||
|
|
||
|
* For pushing upstream: (Community Contributors)
|
||
|
* Make sure you have the proper ssh keys added to your github account
|
||
|
so you can push changes.
|
||
|
* Navigate to https://github.com/pjsip/pjproject
|
||
|
* Click the "Fork" button to create a fork under your own username.
|
||
|
|
||
|
Back on your own machine...
|
||
|
|
||
|
```plain
|
||
|
$ cd ~/dev/asterisk
|
||
|
$ git clone git@github.com:<yourusername>/pjproject
|
||
|
```
|
||
|
|
||
|
* For pushing upstream: (Asterisk Core Team Developers)
|
||
|
Asterisk Core Team Developers should clone the fork we have in our own
|
||
|
Asterisk github organization.
|
||
|
|
||
|
```plain
|
||
|
$ cd ~/dev/asterisk
|
||
|
$ git clone git@github.com:asterisk/pjproject
|
||
|
```
|
||
|
|
||
|
Regardless of how you got your repo, you'll need to create an "upstream"
|
||
|
remote that points to the original pjproject repo.
|
||
|
|
||
|
```plain
|
||
|
$ cd pjproject
|
||
|
$ git remote add upstream https://github.com/pjsip/pjproject
|
||
|
```
|
||
|
|
||
|
If you're just troubleshooting and don't plan on pushing changes upstream,
|
||
|
you can just clone directly from the upstream pjproject repo.
|
||
|
|
||
|
```plain
|
||
|
$ cd ~/dev/asterisk
|
||
|
$ git clone https://github.com/pjsip/pjproject
|
||
|
```
|
||
|
|
||
|
Your directory structure should now look something like:
|
||
|
|
||
|
```plain
|
||
|
~/dev/asterisk/
|
||
|
asterisk/
|
||
|
.git/
|
||
|
addons/
|
||
|
...
|
||
|
third-party/
|
||
|
jansson/
|
||
|
pjproject/
|
||
|
pjproject/
|
||
|
.git
|
||
|
pjlib/
|
||
|
...
|
||
|
```
|
||
|
|
||
|
### Adjusting Asterisk
|
||
|
Start with a "distcleaned" asterisk work tree then in the
|
||
|
asterisk/third-party/pjproject directory, create a symlink to the pjproject
|
||
|
clone you just created.
|
||
|
|
||
|
```plain
|
||
|
$ cd ~/dev/asterisk/asterisk/
|
||
|
$ make distclean
|
||
|
$ cd third-party/pjproject
|
||
|
$ ln -s ../../../pjproject source
|
||
|
```
|
||
|
The "source" directory is now a relative symlink to your pjproject
|
||
|
clone so your directory structure should now look something like:
|
||
|
|
||
|
```plain
|
||
|
~/dev/asterisk/
|
||
|
asterisk/
|
||
|
.git/
|
||
|
addons/
|
||
|
...
|
||
|
third-party/
|
||
|
jansson/
|
||
|
pjproject/
|
||
|
source -> ../../../pjproject
|
||
|
pjproject/
|
||
|
.git
|
||
|
pjlib/
|
||
|
...
|
||
|
```
|
||
|
|
||
|
### Adjust pjproject git ignores.
|
||
|
One final step is required to keep your pjproject repo from being dirtied
|
||
|
by the build process. Add the following lines to your pjproject (not asterisk)
|
||
|
repo's .git/info/exclude file...
|
||
|
|
||
|
```plain
|
||
|
**/*.astdep
|
||
|
**/*asterisk_malloc_debug*
|
||
|
**/_pjsua.o
|
||
|
**/_pjsua.so
|
||
|
```
|
||
|
Don't add these to the top-level .gitignore file! If you do, they'll become
|
||
|
part of any change you submit upstream.
|
||
|
|
||
|
## Usage
|
||
|
|
||
|
Just run `./configure` and `make` as you would for any other asterisk build.
|
||
|
When you make changes to pjproject source files, they'll be automatically
|
||
|
recompiled the next time you build asterisk.
|
||
|
|
||
|
You can do git operations in the pjproject repo while it's still symlinked
|
||
|
into the asterisk source. Assuming you made the proper changes to
|
||
|
pjproject's .git/info/exclude file, a commit in the pjproject repo _should_ contain
|
||
|
only the changes you made.
|
||
|
|
||
|
You can run `make` commands directly in third-party/pjproject The only
|
||
|
requirement is that an asterisk top-level `configure` had to have been
|
||
|
run at least once.
|
||
|
|
||
|
You can always revert to standard bundled pjproject by running an asterisk
|
||
|
top-level `make distclean`, removing the third-party/pjproject/source
|
||
|
symlink, and re-running a top-level `configure`. That will download and
|
||
|
extract the pjproject tarball to the `third-party/pjproject/source`
|
||
|
directory as usual.
|
||
|
|
||
|
### Notes
|
||
|
|
||
|
While your pjproject repo is symlinked into the asterisk source tree,
|
||
|
you should not run `configure` directly in the pjproject repo. You won't get
|
||
|
the proper options applied to be compatible with Asterisk. You can run
|
||
|
`make` though.
|
||
|
|
||
|
Although asterisk_malloc_debug and site_config.h are applied to the pjproject
|
||
|
repo, No patches from the `third-party/pjproject/patches` directory are
|
||
|
applied. Since you're probably working off the pjproject master branch,
|
||
|
the patches aren't needed. Also, applying the patches would contaminate
|
||
|
the pjproject repo and you wouldn't be able to do a clean commit there.
|
||
|
|
||
|
You'll see compile and/or link warnings you wouldn't see with a normal
|
||
|
bundled build.
|
||
|
|
||
|
|
||
|
## How it works
|
||
|
|
||
|
When an asterisk top-level `configure` is run, `third-party/pjproject/configure.m4 `
|
||
|
checks whether `third-party/pjproject/source` is a symlink or is a git
|
||
|
repository. If neither are true, the build isn't considered "out-of-tree"
|
||
|
and the normal pjproject bundled process occurs.
|
||
|
If either is true, it sets `PJPROJECT_BUNDLED_OOT=yes` for the Makefiles.
|
||
|
|
||
|
When a `make` is done, either from top-level asterisk or from the
|
||
|
third-party/pjproject directory, it checks `PJPROJECT_BUNDLED_OOT`
|
||
|
and if set to yes it...
|
||
|
|
||
|
* Alters the behavior of `clean` and `distclean` to just run
|
||
|
pjproject's `clean` or `distclean` targets and to NOT remove the
|
||
|
`source` directory or symlink as it would normally do.
|
||
|
|
||
|
* Generates `astdep` dependency files in the pjproject source tree
|
||
|
if they don't already exist. These are git-ignored by the edit
|
||
|
to pjproject's `.git/info/exclude` done above. You'll
|
||
|
see new progress messages during the make as the astdep files are
|
||
|
built.
|
||
|
|
||
|
* Copies asterisk_malloc_debug.c, asterisk_malloc_debug.h and
|
||
|
config_site.h from the patches directory into the pjproject source
|
||
|
tree. These are also git-ignored by the edit to pjproject's
|
||
|
`.git/info/exclude` file.
|
||
|
|
||
|
* Compiles only the out-of-date source files into their respective
|
||
|
libpj libraries. That in turn triggers the asterisk top-level
|
||
|
make to re-link main/libasteriskpj.so.
|
||
|
|
||
|
|
||
|
|