In this note I will use pkg-config in cmake to discover PJSIP libraries. Cmake script can be used without changes for linux and windows, but for windows it is necessary to do some hand-work (hand work can be automated).
There is three sections in this note:
- Installing pkg-config executable
- Installing right libpjrpoject.pc
- Discover PJSIP in cmake
Installing pkg-config executable
Pkg-config on Linux
pkg-config has native support in linux.
For ubuntu you can install it with
sudo apt-get install pkg-config
Pkg-config on Windows
There is also pkg-config
binaries for Windows. You can download pkg-config with all dependencies from this answer on stackoverflow. Or you can simply download pkg-config-lite which is just single executable without any dependency.
Make sure that directory with pkg-config binaries is stored in PATH
environment variable. You also need set PKG_CONFIG_PATH
to directory which contains *.pc
files with libraries metadata.
Install right libpjrpoject.pc
It is necessary to put libpjproject.pc to pkg-config search path. In Linux it can be done very simple due to autoconf tools. In Windows it can be done by do some hand-work.
Install PJSIP in Linux with apt-get
When you install PJSIP with
sudo apt-get install pjproject
you get right libpjproject.pc
file in pkg-config search path.
Install PJSIP in Linux from sources
You can also install PJSIP from sources with commands
# install srtp prereqisite
sudo apt-get install libsrtp0 libsrtp0-dev
# get sources
wget http://www.pjsip.org/release/2.3/pjproject-2.3.tar.bz2
tar jxf pjproject-2.3.tar.bz2
# configure, make, install
pushd pjproject-2.3
./configure
make dep
make clean
make
sudo make install
popd
In this case sudo make install
will put libpjproject.pc
to pkg-config search path.
Install PJSIP from sources on Windows
Windows is differ from linux in way you build software. Several CRT (C Runtime Library) versions must be supported: Static/Dynamic linkage, Debug/Release configurations, x86/x64 cpu target, Win8/WinXP toolset. pkg-config package file can contain only one such library.
So, it is convenient on Windows to represent library in terms of Visual Studio Macros, like:
libpjproject-$(Platform)-$(PlatformToolset)-$(Configuration)-Dynamic.lib
for Dynamic CRTlibpjproject-$(Platform)-$(PlatformToolset)-$(Configuration)-Static.lib
for Static CRT
The Visual Studio Macros used here is (I use Visual Studio 2013 Express): - $(Platform)
- values Win32
or x64
depends on current build platform selected - $(PlatformTooslet)
- platform toolset used in build: value v120
is default in Visual Studio 2013, v120_xp
is for Windows XP compatible builds - $(Configuration)
- usually Debug
or Release
values (cmake extends this list with RelWithDebInfo
and MinSizeRel
values)
You can use unofficial fork of PJSIP which prepared to generate binaries in that way when building in Visual Studio.
There is no prepared libpjproject.pc
files exists for Windows, but you can write your own:
[email protected][email protected]
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/pjlib/include;${prefix}/pjlib-util/include;${prefix}/pjmedia/include;${prefix}/pjnath/include;${prefix}/pjsip/include
Name: libpjproject
Description: Multimedia communication library
URL: http://www.pjsip.org
Version: 2.3.0
Libs: -L${libdir} -llibpjproject-$$(Platform)-$$(PlatformToolset)-$$(Configuration)-Dynamic.lib
Libs.private: -lWs2_32.lib
Cflags: -I${includedir}
Note that you need specify directory to PJSIP sources instead @[email protected]
.
So, if you put this lipjproject.pc
to pkg-config search path, pkg-config will be able to discover PJSIP binaries in Windows.
Discover PJSIP in cmake
When you have pkg-config tool and you have libpjproject.pc
in pkg-config search path, you can discover PJSIP with command:
pkg-config --cflags libpjproject
pkg-config --libs --msvc-syntax libpjproject
Default way to discover libraries in cmake is to consume Find*.cmake
module and find_package()
function. In this example I just highlight some details. Full implementation you can find in FindPJSIP.cmake.
To find pkg-config executable in cmake
# find pkg-config executable, define pkg_check_modules() macro
find_package(PkgConfig REQUIRED)
if (NOT PKG_CONFIG_FOUND)
message(SEND_ERROR "PkgConfig not found")
return()
endif()
If pkg-config executable found, FindPkgConfig.cmake module will define macro pkg_check_modules()
.
With this macro you can specify
- find exact version of library:
pkg_check_modules(PJSIP libpjproject=2.3 REQUIRED)
- find least version supported
pkg_check_modules(PJSIP libpjproject>=2.3 REQUIRED)
- find any version
pkg_check_modules(PJSIP libpjproject REQUIRED)
If library is found, pkg_check_modules()
macro will
- set variable
PJSIP_FOUND=1
- set variable
PJSIP_INCLUDE_DIRS=$(pkg-config --cflags libpjproject)
- set variable
PJSIP_LIBRARY_DIRS
,PJSIP_STATIC_LIBRARY_DIRS
andPJSIP_LIBRARIES
by parsing output of$(pkg-config --libs libpjproject)
and$(pkg-config --libs --static libpjproject)
commands.
Conclusion
This method is good enough to discover dependent libraries in cmake "in a portable way" (one cmake-script for linux and windows). For windows there is some hand-work to be done (this work can be automated in some way).
Comments