Using PJSIP in CMake Projects
After cmake --install has placed PJSIP under a prefix (see
Build Instructions with CMake), a downstream CMake project can consume it
with a standard find_package call. This page covers the installed
package layout, the exported targets, and a minimal working example.
Minimal Example
Assuming PJSIP was installed under /usr/local (or the prefix is on
CMAKE_PREFIX_PATH):
cmake_minimum_required(VERSION 3.28)
project(myapp C)
find_package(Pj REQUIRED)
add_executable(myapp myapp.c)
target_link_libraries(myapp PRIVATE Pj::pjsua-lib)
myapp.c:
#include <pjsua-lib/pjsua.h>
#include <pj/log.h>
int main(void)
{
pjsua_create();
PJ_LOG(3, ("myapp.c", "Hello PJSIP! Bye PJSIP."));
pjsua_destroy();
return 0;
}
Configure and build:
$ cmake -S . -B build -DCMAKE_PREFIX_PATH=/usr/local
$ cmake --build build -j
find_package(Pj) transitively pulls in everything PJSIP was linked
against at install time (OpenSSL, SDL2, FFMPEG, ALSA, and so on). No
additional find_package calls are required in the consumer project
unless the application itself uses those libraries directly.
Exported Targets
All PJSIP libraries are exported under the Pj:: namespace. The
targets mirror the library layout described in Overview:
Target |
What it is |
|---|---|
|
Base framework: OS abstraction, data structures, pool allocator. |
|
Utilities: DNS, STUN, XML, JSON, WebSocket. |
|
NAT traversal: STUN, TURN, ICE. |
|
Core media framework: transports, streams, ports, sessions. |
|
Codec implementations and the codec manager. |
|
Audio device abstraction (ALSA, Core Audio, WASAPI, Oboe, …). |
|
Video device abstraction (V4L2, AVFoundation, DirectShow, …). |
|
SIP core: transactions, transport, parsing. |
|
SIP event/presence (SIMPLE) package. |
|
SIP UA layer: dialogs, calls, INVITE/REFER sessions. |
|
High-level PJSUA C API (the library most applications link). |
|
PJSUA2 C++ API. |
There is also one infrastructure target you normally do not link directly:
Pj::pjlib-ssl– anINTERFACEtarget that carries the selected SSL backend’s compile and link flags. It is pulled in automatically by any target that needs SSL.
The pjsua command-line application is installed as an executable
(<prefix>/bin/pjsua); it is not a library and should not be linked
into downstream code.
Selecting Components
Most applications only need Pj::pjsua-lib or Pj::pjsua2; the
other targets are brought in transitively. When you want a narrower
link set – for example, a tool that only does SIP parsing without a
full UA – link against the specific targets:
target_link_libraries(sip_tool PRIVATE Pj::pjsip Pj::pjlib-util Pj::pjlib)
CMake resolves the transitive dependencies between PJSIP libraries automatically.
Pointing CMake at the Install Prefix
If PJSIP is installed outside the default search path, tell the consumer project where to look via one of:
$ cmake -S . -B build -DCMAKE_PREFIX_PATH=/opt/pjsip
$ export CMAKE_PREFIX_PATH=/opt/pjsip
$ cmake -S . -B build
$ cmake -S . -B build -DPj_DIR=/opt/pjsip/lib/cmake/Pj
Pj_DIR is the most explicit form and bypasses the rest of CMake’s
search logic.
Version Requirements
find_package(Pj) supports the usual CMake version request:
find_package(Pj 2.17 REQUIRED)
The package is configured with COMPATIBILITY SameMajorVersion, so
a request for 2.16 is satisfied by any installed 2.x release
(x ≥ 16) but not by a future 3.x.
Embedding PJSIP via add_subdirectory
PJSIP can also be embedded into a super-project without a separate install step:
cmake_minimum_required(VERSION 3.28)
project(super C CXX)
set(PJ_SKIP_EXPERIMENTAL_NOTICE ON)
add_subdirectory(third_party/pjproject EXCLUDE_FROM_ALL)
add_executable(myapp myapp.c)
target_link_libraries(myapp PRIVATE pjsua-lib)
In this mode the targets exist without the Pj:: namespace prefix
(CMake’s ALIAS mechanism is set up by the export step, which is only
run on install). Use the bare target names — pjsua-lib,
pjsua2, pjsip, and so on — when linking.
The same PJ_DEP_* and PJMEDIA_WITH_* options can be set in
the super-project’s cache before add_subdirectory() to control
the embedded build.
Interaction with System Dependencies
When PJSIP was built with PJ_DEP_<NAME>=system (for example,
-DPJ_DEP_SRTP=system), the installed PjConfig.cmake records
this choice and calls find_dependency() on the same system
packages when you run find_package(Pj). You do not need to call
find_package(libsrtp) yourself; it is handled by the config
module.
For SSL, the backend chosen at build time is also recorded, so
consumers that call find_package(Pj) automatically get the right
OpenSSL / GnuTLS / MbedTLS dependency pulled in.