asterisk/third-party/pjproject/README-hacking.md

6.6 KiB

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:

~/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...

$ 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.
$ 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.

$ 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.

$ cd ~/dev/asterisk
$ git clone https://github.com/pjsip/pjproject

Your directory structure should now look something like:

~/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.

$ 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:

~/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...

**/*.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.