Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7313346
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
21 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/docs/Install.osx b/docs/Install.osx
index 1c6db25a..59038188 100644
--- a/docs/Install.osx
+++ b/docs/Install.osx
@@ -1,237 +1,237 @@
Installation procedure for SIP SIMPLE client SDK on MacOSX
----------------------------------------------------------
Copyright (c) 2008-2010 AG Projects
http://ag-projects.com
Home page: http://sipsimpleclient.com
This document describes the installation procedure on MacOSX Leopard 10.5
and Snow Leopard 10.6.
The installation procedure consists of the steps described below:
Step 1. Prerequisites
Step 2. Install Dependencies
Step 2.1. Install Dependencies (Leopard only)
Step 2.2. Install Dependencies (Snow Leopard only)
Step 2.3. Install Common Dependencies
Step 3. Install SIP SIMPLE client SDK
Step 1. Prerequisites
---------------------
* MacOSX 10.5 (Leopard) or MacOSX 10.6 (Snow Leopard)
* Intel architecture
* Apple Developer tools (XCode)
* On Snow Leopard, the 10.4 SDK must be installed from XCode package
* darcs version control tool from http://www.darcs.net
The procedure below relies on the standard available Python interpreter that
comes with MacOSX (version 2.5 on Leopard and 2.6 on Snow Leopard). Make
sure that during the building process you are not involving external tools
or libraries like the ones provided by Fink or Darwin Ports distributions.
Step 2. Install Dependencies
----------------------------
* python-gnutls http://pypi.python.org/simple/python-gnutls >=1.1.9
* python-application http://pypi.python.org/simple/python-application >=1.1.5
* python-lxml http://codespeak.net/lxml >=2.1.2
* python-eventlet http://download.ag-projects.com/SipClient =0.8.11
* python-cjson http://pypi.python.org/pypi/python-cjson/ >=1.0.5
* cython http://www.cython.org >=0.11.3
* dnspython http://www.dnspython.org >=1.6.0
* twisted http://twistedmatrix.com/trac >=8.1.0
* eventlet http://pypi.python.org/pypi/eventlet/ =0.8.11
* greenlet http://pypi.python.org/pypi/greenlet/ >=0.2
* zope-interface http://www.zope.org >=3.3.1
* Python Imaging Library http://pypi.python.org/pypi/PIL/ >=1.1.6
Build and install C dependencies, the software will be installed under
/usr/local folder:
Step 2.1. Install Dependencies (MacOSX 10.5 Leopard only)
cd ~/work
# Install GNUTLS dependencies
# ===========================
curl -O ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.7.tar.bz2
tar -xjvf libgpg-error-1.7.tar.bz2
cd libgpg-error-1.7
CFLAGS="-arch i386" ./configure --prefix=/usr/local --disable-static --disable-dependency-tracking
make
sudo make install
cd ..
curl -O http://ftp.gnu.org/pub/gnu/gnutls/libtasn1-2.2.tar.gz
tar zxvf libtasn1-2.2.tar.gz
cd libtasn1-2.2
./configure
make
sudo make install
cd ..
curl -O ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.5.tar.bz2
tar -xjvf libgcrypt-1.4.5.tar.bz2
cd libgcrypt-1.4.5
CFLAGS="-arch i386" ./configure --prefix=/usr/local --with-gpg-error-prefix=/usr/local --disable-static --disable-dependency-tracking --disable-asm
make
sudo make install
cd ..
# Install GNUTLS
# ==============
curl -O http://ftp.gnu.org/pub/gnu/gnutls/gnutls-2.8.6.tar.bz2
tar -xjvf gnutls-2.8.6.tar.bz2
cd gnutls-2.8.6
CFLAGS="-arch i386" ./configure --prefix=/usr/local --with-libgcrypt-prefix=/usr/local --disable-static --disable-dependency-tracking
make
sudo make install
cd ..
# Install lxml python module
# ==========================
curl -O http://pypi.python.org/packages/source/l/lxml/lxml-2.2beta4.tar.gz
tar -xzvf lxml-2.2beta4.tar.gz
cd lxml-2.2beta4
sudo python setup.py install --static-deps
cd ..
Upgrade MacOSX python setup tools:
sudo easy_install --script-dir /usr/bin -U setuptools
Step 2.2. Install Dependencies (MacOSX 10.6 Snow Leopard only)
# Install GNUTLS dependencies
# ===========================
curl -O ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.7.tar.bz2
tar -xjvf libgpg-error-1.7.tar.bz2
cd libgpg-error-1.7
-CFLAGS="-arch x86_64" ./configure --prefix=/usr/local --disable-static --disable-dependency-tracking
+CFLAGS="-arch i386 -arch x86_64" ./configure --prefix=/usr/local --disable-static --disable-dependency-tracking
make
sudo make install
cd ..
curl -O http://ftp.gnu.org/pub/gnu/gnutls/libtasn1-2.2.tar.gz
tar zxvf libtasn1-2.2.tar.gz
cd libtasn1-2.2
-./configure
+CFLAGS="-arch i386 -arch x86_64" ./configure --disable-dependency-tracking
make
sudo make install
cd ..
curl -O ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.5.tar.bz2
tar -xjvf libgcrypt-1.4.5.tar.bz2
cd libgcrypt-1.4.5
-CFLAGS="-arch x86_64" ./configure --prefix=/usr/local --with-gpg-error-prefix=/usr/local --disable-static --disable-dependency-tracking --disable-asm
+CFLAGS="-arch i386 -arch x86_64" ./configure --prefix=/usr/local --with-gpg-error-prefix=/usr/local --disable-static --disable-dependency-tracking --disable-asm
make
sudo make install
cd ..
# Install GNUTLS
# ==============
curl -O http://ftp.gnu.org/pub/gnu/gnutls/gnutls-2.8.6.tar.bz2
tar -xjvf gnutls-2.8.6.tar.bz2
cd gnutls-2.8.6
-CFLAGS="-arch x86_64" ./configure --prefix=/usr/local --with-libgcrypt-prefix=/usr/local --disable-static --disable-dependency-tracking
+CFLAGS="-arch i386 -arch x86_64" ./configure --prefix=/usr/local --with-libgcrypt-prefix=/usr/local --disable-static --disable-dependency-tracking
make
sudo make install
cd ..
# Install lxml python module
# ==========================
STATIC_DEPS=true sudo easy_install lxml
Step 2.3. Install Common Dependencies
Install Python dependencies by using the easy_install tool. The software
will be installed in /Library/Python/2.5/site-packages on Leopard or
/Library/Python/2.6/site-packages on Snow Leopard:
sudo easy_install -U python-gnutls dnspython twisted greenlet \
python-application PIL cython
Step 3. Install SIP SIMPLE client SDK
-------------------------------------
The SDK consists of four parts:
1. Eventlet
2. XCAP library
3. MSRP library
4. SIP SIMPLE library
# Eventlet
if [ -d python-eventlet ]; then
cd python-eventlet
darcs pull -a
sudo python setup.py install
else
darcs get http://devel.ag-projects.com/repositories/python-eventlet
cd python-eventlet
sudo python setup.py install
fi
cd ..
# XCAP library
if [ -d python-xcaplib ]; then
cd python-xcaplib
darcs pull -a
sudo python setup.py install
else
darcs get http://devel.ag-projects.com/repositories/python-xcaplib
cd python-xcaplib
sudo python setup.py install
fi
cd ..
# MSRP library
if [ -d python-msrplib ]; then
cd python-msrplib
darcs pull -a
sudo python setup.py install
else
darcs get http://devel.ag-projects.com/repositories/python-msrplib
cd python-msrplib
sudo python setup.py install
fi
cd ..
# SIP SIMPLE library
if [ -d python-sipsimple ]; then
cd python-sipsimple
darcs pull -a
else
darcs get http://devel.ag-projects.com/repositories/python-sipsimple
fi
cd..
Build and install SIP SIMPLE library:
cd python-sipsimple
sudo python setup.py build_ext --pjsip-clean-compile
sudo python setup.py install
Additional, you can install the command line interface scripts that can be
used to test the SDK.
if [ -d sipclients ]; then
cd sipclients
darcs pull -a
else
darcs get http://devel.ag-projects.com/repositories/sipclients
fi
cd..
sudo python setup.py install
diff --git a/setup_pjsip.py b/setup_pjsip.py
index fd463901..b8f1ba7f 100644
--- a/setup_pjsip.py
+++ b/setup_pjsip.py
@@ -1,245 +1,245 @@
import subprocess
import re
import itertools
import sys
import os
import platform
from distutils.errors import DistutilsError
from distutils import log
from Cython.Distutils import build_ext
def get_make_cmd():
if sys.platform.startswith("freebsd"):
return "gmake"
else:
return "make"
def get_opts_from_string(line, prefix):
"""Returns all options that have a particular prefix on a commandline"""
return re.findall("%s(\S+)(?:\s|$)" % prefix, line)
def exec_process(cmdline, silent, input=None, **kwargs):
"""Execute a subprocess and returns the returncode, stdout buffer and stderr buffer.
Optionally prints stdout and stderr while running."""
sub = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
stdout, stderr = sub.communicate(input=input)
if not silent:
sys.stdout.write(stdout)
sys.stderr.write(stderr)
return sub.returncode, stdout, stderr
def distutils_exec_process(cmdline, silent, input=None, **kwargs):
try:
returncode, stdout, stderr = exec_process(cmdline, silent, input, **kwargs)
except OSError,e:
if e.errno == 2:
raise DistutilsError('"%s" is not present on this system' % cmdline[0])
else:
raise
if returncode != 0:
raise DistutilsError('Got return value %d while executing "%s", stderr output was:\n%s' % (returncode, " ".join(cmdline), stderr.rstrip("\n")))
return stdout
def get_makefile_variables(makefile):
"""Returns all variables in a makefile as a dict"""
stdout = distutils_exec_process([get_make_cmd(), "-f", makefile, "-pR", makefile], True)
return dict(tup for tup in re.findall("(^[a-zA-Z]\w+)\s*:?=\s*(.*)$", stdout, re.MULTILINE))
def get_svn_repo_url(svn_dir):
environment = dict((name, value) for name, value in os.environ.iteritems() if name!='LANG' and not name.startswith('LC_'))
environment['LC_ALL'] = 'C'
svn_info = distutils_exec_process(["svn", "info", svn_dir], True, env=environment)
return re.search("URL: (.*)", svn_info).group(1)
def get_svn_revision(svn_dir, max_revision=None):
environment = dict((name, value) for name, value in os.environ.iteritems() if name!='LANG' and not name.startswith('LC_'))
environment['LC_ALL'] = 'C'
if max_revision is None:
svn_info = distutils_exec_process(["svn", "info", svn_dir], True, env=environment)
else:
svn_info = distutils_exec_process(["svn", "-r", str(max_revision), "info", svn_dir], True, env=environment)
return int(re.search("Last Changed Rev: (\d+)", svn_info).group(1))
class PJSIP_build_ext(build_ext):
config_site = ["#define PJ_SCANNER_USE_BITWISE 0",
"#define PJSIP_SAFE_MODULE 0",
"#define PJSIP_MAX_PKT_LEN 65536",
"#define PJSIP_UNESCAPE_IN_PLACE 1",
"#define PJMEDIA_HAS_L16_CODEC 0",
"#define PJ_ICE_MAX_CHECKS 256",
"#define PJ_LOG_MAX_LEVEL 6"]
patch_files = ["patches/sdp_neg_cancel_remote_offer_r2669.patch",
"patches/pjsip-2371-sip_inv-on_rx_reinvite.patch",
"patches/pjsip-2553-sip_inv-cancel_sdp_neg_on_sending_negative_reply_to_reinvite.patch",
"patches/pjsip-2553-sip_inv-dont_disconnect_on_408_reply_to_reinvite.patch",
"patches/pjsip-2553-sip_inv-terminate-reinvite-tsx-on-cancel.patch",
"patches/pjsip-2553-sip_inv-improved_missing_ack_handling.patch",
"patches/pjsip-2425-sdp_media_line.patch",
"patches/pjsip-2394-sip_dialog-no_totag_check_on_dialog_state_update.patch",
"patches/pjsip-2832-sdp_ignore_missing_rtpmap_for_dynamic_pt.patch",
"patches/pjsip-2833-parse_pjsip_allow_events_hdr.patch",
"patches/pjsip-2830-runtime_device_change_detection.patch",
"patches/pjsip-2342-g722-14-bits-conversion.patch",
"patches/pjsip-2656-ip_selection_algorithm.patch",
"patches/pjsip-2830-allow_cancel_reinvite.patch",
"patches/pjsip-2830-ice_priority_calculation.patch",
"patches/pjsip-2830-ice_regular_nomination.patch",
"patches/pjsip-2830-dont_compile_pjsua.patch",
"patches/pjsip-2830-ice_choose_right_candidate.patch",
"patches/pjsip-2830-ice_avoid_crash_on_ice_completion_cb.patch",
"patches/pjsip-2830-ice_status_callbacks.patch",
"patches/pjsip-2830-add_mixer_port.patch",
"patches/pjsip-2830-ice_transport_info.patch",
"patches/pjsip-2830-fix_mixer_port.patch",
"patches/pjsip-2830-reuse-thread-desc-in-pa-port.patch",
"patches/pjsip-2830-fix_headphones_plug_crash.patch",
"patches/pjsip-2830-ice_keepalive_support.patch",
"patches/pjsip-2830-dont_accept_sdp_everywhere.patch",
"patches/pjsip-2830-allocate_thread_desc_from_pool.patch",
"patches/pjsip-2830-do_not_close_stream_too_fast.patch"]
pjsip_svn_repos = {"trunk": "http://svn.pjsip.org/repos/pjproject/trunk",
"1.0": "http://svn.pjsip.org/repos/pjproject/branches/1.0"}
portaudio_patch_files = ["patches/portaudio-1420-runtime_device_change_detection.patch",
"patches/portaudio-1420-compile_snow_leopard.patch",
"patches/portaudio-1420-pa_mac_core_x64_assert_fix.patch"]
trunk_overrides = []
user_options = build_ext.user_options
user_options.extend([
("pjsip-svn-revision=", None, "PJSIP SVN revision to fetch"),
("pjsip-clean-compile", None, "Clean PJSIP tree before compilation"),
("pjsip-disable-assertions", None, "Disable assertion checks within PJSIP, most will revert to exceptions instead")
])
boolean_options = build_ext.boolean_options
boolean_options.extend(["pjsip-clean-compile", "pjsip-disable-assertions"])
cython_version_required = (0, 11)
def initialize_options(self):
build_ext.initialize_options(self)
self.pjsip_clean_compile = 0
self.pjsip_disable_assertions = int(os.environ.get("PJSIP_NO_ASSERT", 0))
self.pjsip_svn_revision = os.environ.get("PJSIP_SVN_REVISION", "HEAD")
self.pjsip_build_dir = os.environ.get("PJSIP_BUILD_DIR", None)
self.pjsip_svn_repo = self.pjsip_svn_repos["1.0"]
def check_cython_version(self):
from Cython.Compiler.Version import version as cython_version
if tuple(int(x) for x in cython_version.split(".")) < self.cython_version_required:
raise DistutilsError("Cython version %s or higher needed" % ".".join(str(i) for i in self.cython_version_required))
def fetch_pjsip_from_svn(self):
self.svn_dir = os.path.join(self.pjsip_build_dir or self.build_temp, "pjsip")
if not os.path.exists(self.svn_dir):
log.info("Fetching PJSIP from SVN repository")
distutils_exec_process(["svn", "co", "-r", self.pjsip_svn_revision, self.pjsip_svn_repo, self.svn_dir], True, input='t\n')
new_svn_rev = get_svn_revision(self.svn_dir)
svn_updated = True
else:
try:
old_svn_rev = get_svn_revision(self.svn_dir)
except:
old_svn_rev = -1
local_svn_repo = get_svn_repo_url(self.svn_dir)
if local_svn_repo != self.pjsip_svn_repo:
raise DistutilsError("Local build dir PJSIP SVN repository (%s) does not not match the one provided (%s)" % (local_svn_repo, self.pjsip_svn_repo))
log.info("PJSIP SVN tree found, checking SVN repository for updates")
try:
new_svn_rev = get_svn_revision(local_svn_repo, self.pjsip_svn_revision)
except DistutilsError, e:
if self.pjsip_clean_compile:
raise
log.info("Could not contact SVN repository, continuing with existing tree:")
log.info(str(e))
new_svn_rev = old_svn_rev
svn_updated = False
else:
svn_updated = self.pjsip_clean_compile or new_svn_rev != old_svn_rev
if svn_updated:
log.info("Fetching updates from PJSIP SVN repository")
distutils_exec_process(["svn", "revert", "-R", self.svn_dir], True)
distutils_exec_process("svn status \"%s\" | grep ^\?| awk '{print $2}' | xargs -I '{}' rm '{}'" % (self.svn_dir,), True, shell=True)
distutils_exec_process(["svn", "up", "-r", self.pjsip_svn_revision, self.svn_dir], True, input='t\n')
if self.pjsip_svn_repo == self.pjsip_svn_repos["1.0"]:
for override_file, override_revision in self.trunk_overrides:
distutils_exec_process(["svn", "merge", "-r", "%d:%d" % (new_svn_rev, override_revision), "/".join([self.pjsip_svn_repos["trunk"], override_file]), os.path.join(self.svn_dir, override_file)], True)
else:
log.info("No updates in PJSIP SVN")
print "Using SVN revision %d" % new_svn_rev
return svn_updated
def patch_pjsip(self):
log.info("Patching PJSIP")
open(os.path.join(self.svn_dir, "pjlib", "include", "pj", "config_site.h"), "wb").write("\n".join(self.config_site+[""]))
for patch_file in self.patch_files:
distutils_exec_process(["patch", "--forward", "-d", self.svn_dir, "-p0", "-i", os.path.abspath(patch_file)], True)
log.info("Patching PortAudio")
self.portaudio_dir = os.path.join(self.svn_dir, "third_party", "portaudio");
distutils_exec_process(["svn", "revert", "-R", self.portaudio_dir], True)
for patch_file in self.portaudio_patch_files:
distutils_exec_process(["patch", "--forward", "-d", self.portaudio_dir, "-p0", "-i", os.path.abspath(patch_file)], True)
def configure_pjsip(self):
log.info("Configuring PJSIP")
cflags = "-O3 -fPIC"
if sys.platform == "darwin":
if platform.mac_ver()[0].startswith('10.6'):
- cflags += " -arch x86_64"
+ cflags += " -arch i386 -arch x86_64"
else:
cflags += " -arch ppc -arch i386"
if self.pjsip_disable_assertions:
cflags += " -DNDEBUG"
env = os.environ.copy()
env['CFLAGS'] = ' '.join(x for x in (cflags, env.get('CFLAGS', None)) if x)
distutils_exec_process(["./configure"], True, cwd=self.svn_dir, env=env)
if "#define PJSIP_HAS_TLS_TRANSPORT 1\n" not in open(os.path.join(self.svn_dir, "pjsip", "include", "pjsip", "sip_autoconf.h")).readlines():
os.remove(os.path.join(self.svn_dir, "build.mak"))
raise DistutilsError("PJSIP TLS support was disabled, OpenSSL development files probably not present on this system")
def clean_pjsip(self):
log.info("Cleaning PJSIP")
distutils_exec_process([get_make_cmd(), "realclean"], True, cwd=self.svn_dir)
def update_extension(self, extension):
build_mak_vars = get_makefile_variables(os.path.join(self.svn_dir, "build.mak"))
extension.include_dirs = get_opts_from_string(build_mak_vars["PJ_CFLAGS"], "-I")
extension.library_dirs = get_opts_from_string(build_mak_vars["PJ_LDFLAGS"], "-L")
extension.libraries = get_opts_from_string(build_mak_vars["PJ_LDLIBS"], "-l")
extension.define_macros = [tuple(define.split("=", 1)) for define in get_opts_from_string(build_mak_vars["PJ_CFLAGS"], "-D")]
extension.define_macros.append((("PJ_SVN_REVISION"), str(get_svn_revision(self.svn_dir))))
extension.extra_link_args = list(itertools.chain(*[["-framework", val] for val in get_opts_from_string(build_mak_vars["PJ_LDLIBS"], "-framework ")]))
extension.extra_compile_args = ["-Wno-unused-variable"]
extension.depends = build_mak_vars["PJ_LIB_FILES"].split()
self.libraries = extension.depends[:]
self.libraries.append(("%(PJ_DIR)s/pjmedia/lib/libpjsdp-%(LIB_SUFFIX)s" % build_mak_vars).replace("$(TARGET_NAME)", build_mak_vars["TARGET_NAME"]))
def remove_libs(self):
for lib in self.libraries:
try:
os.remove(lib)
except:
pass
def compile_pjsip(self):
log.info("Compiling PJSIP")
distutils_exec_process([get_make_cmd()], True, cwd=self.svn_dir)
def cython_sources(self, sources, extension):
if extension.name == "sipsimple.core._core":
self.check_cython_version()
svn_updated = self.fetch_pjsip_from_svn()
if svn_updated:
self.patch_pjsip()
compile_needed = svn_updated
if not os.path.exists(os.path.join(self.svn_dir, "build.mak")) or self.pjsip_clean_compile:
self.configure_pjsip()
compile_needed = True
self.pjsip_clean_compile = 1
if self.pjsip_clean_compile:
self.clean_pjsip()
self.update_extension(extension)
if compile_needed or not all(map(lambda x: os.path.exists(x), self.libraries)):
self.remove_libs()
self.compile_pjsip()
return build_ext.cython_sources(self, sources, extension)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Feb 1, 11:44 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489315
Default Alt Text
(21 KB)
Attached To
Mode
rPYNSIPSIMPLE python3-sipsimple
Attached
Detach File
Event Timeline
Log In to Comment