mirror of http://gerrit.asterisk.org/asterisk
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. This commit makes that easier. See third-party/pjproject/README-hacking.md for the details. ASTERISK-29824 Change-Id: Idb1251040affdab31d27cd272dda68676da9b268changes/38/17838/1
parent
0d62735f99
commit
bc59b66de3
@ -0,0 +1,8 @@
|
|||||||
|
Subject: Core
|
||||||
|
|
||||||
|
Bundled PJProject Build
|
||||||
|
|
||||||
|
The build process has been updated to make pjproject troubleshooting
|
||||||
|
and development easier. See third-party/pjproject/README-hacking.md or
|
||||||
|
https://wiki.asterisk.org/wiki/display/AST/Bundled+PJProject
|
||||||
|
for more info.
|
||||||
@ -1,5 +1,6 @@
|
|||||||
source/
|
source
|
||||||
**.bz2
|
**.bz2
|
||||||
build.mak
|
build.mak
|
||||||
pjproject.symbols
|
pjproject.symbols
|
||||||
.rebuild_needed
|
.rebuild_needed
|
||||||
|
.makedeps
|
||||||
|
|||||||
@ -0,0 +1,213 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ "x${SED}" = "x" ] && SED=sed
|
||||||
|
[ "x${GREP}" = "x" ] && GREP=grep
|
||||||
|
[ "x${REALPATH}" = "x" ] && REALPATH=realpath
|
||||||
|
[ "x${DIRNAME}" = "x" ] && DIRNAME=dirname
|
||||||
|
[ "x${BASENAME}" = "x" ] && BASENAME=basename
|
||||||
|
[ "x${GREP}" = "x" ] && GREP=grep
|
||||||
|
if [ "x${TARGET_NAME}" = "x" ] ; then
|
||||||
|
if [ ! -f build.mak ] ; then
|
||||||
|
exit 0;
|
||||||
|
fi
|
||||||
|
TARGET_NAME=$(${SED} -n -r -e "s/export\s+TARGET_NAME\s*:=\s*(.*)/\1/gp" build.mak)
|
||||||
|
fi
|
||||||
|
|
||||||
|
getlibname() {
|
||||||
|
dep="$1"
|
||||||
|
libdir=$(${DIRNAME} $(${DIRNAME} "${dep}"))/lib
|
||||||
|
depname=$(${BASENAME} "${dep}")
|
||||||
|
depprefix="${depname%%-${TARGET_NAME}.depend}"
|
||||||
|
case ${depprefix} in
|
||||||
|
.pjlib)
|
||||||
|
libfile=libpj
|
||||||
|
;;
|
||||||
|
.pjsua-lib)
|
||||||
|
libfile=libpjsua
|
||||||
|
;;
|
||||||
|
.*)
|
||||||
|
libfile=lib${depprefix#.*}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "${libdir}/${libfile}-${TARGET_NAME}.a"
|
||||||
|
}
|
||||||
|
|
||||||
|
gendepfile() {
|
||||||
|
pjdf="$1"
|
||||||
|
astdf="${pjdf%*.depend}.astdep"
|
||||||
|
dirname=$(${DIRNAME} "${astdf}")
|
||||||
|
lines=$(grep -E -o -- "[.][.]/[^ ]+" "${pjdf}" | sort -u | wc -l)
|
||||||
|
libname=$(getlibname "${pjdf}")
|
||||||
|
backslash="\\"
|
||||||
|
echo "${libname}: ${backslash}" >"${astdf}"
|
||||||
|
for dep in $(grep -E -o -- "[.][.]/[^ ]+" "${pjdf}" | sort -u) ; do
|
||||||
|
( echo "${dep}" | grep -Eq "(test|/bin/)" ; ) && continue
|
||||||
|
newdep=$( cd "${dirname}" ; ${REALPATH} -L --relative-to=../../ "${dep}" ; )
|
||||||
|
lines=$(( ${lines} - 1 ))
|
||||||
|
if [ ${lines} -eq 0 ] ; then
|
||||||
|
echo "source/${newdep}" >>"${astdf}"
|
||||||
|
else
|
||||||
|
echo "source/${newdep} ${backslash}" >>"${astdf}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo >>"${astdf}"
|
||||||
|
}
|
||||||
|
|
||||||
|
getpjdepname () {
|
||||||
|
lib="$1"
|
||||||
|
builddir=$(${DIRNAME} $(${DIRNAME} "${lib}"))/build
|
||||||
|
libname=$(${BASENAME} "${lib}")
|
||||||
|
libprefix="${libname%%-${TARGET_NAME}.a}"
|
||||||
|
nolib=$(echo "${libprefix}" | ${SED} -r -e "s@^lib@@g")
|
||||||
|
case ${nolib} in
|
||||||
|
pj)
|
||||||
|
depfile=.pjlib
|
||||||
|
;;
|
||||||
|
pjsua)
|
||||||
|
depfile=.pjsua-lib
|
||||||
|
;;
|
||||||
|
resample)
|
||||||
|
depfile=resample/.libresample
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
depfile=.${nolib}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "${builddir}/${depfile}-${TARGET_NAME}.depend"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
getpjdepname)
|
||||||
|
shift
|
||||||
|
for lib in $@ ; do getpjdepname "${lib}" ; done
|
||||||
|
;;
|
||||||
|
gendepfile)
|
||||||
|
shift
|
||||||
|
for dep in $@ ; do gendepfile "${dep}" ; done
|
||||||
|
;;
|
||||||
|
getlibname)
|
||||||
|
shift
|
||||||
|
for dep in $@ ; do getlibname "${dep}" ; done
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo Invalid command
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Loading…
Reference in new issue