Permalink
Browse files

Install pkg-config files (#343)

* Install pkg-config files

pkg-config is an amazing tool for locating installed libraries and
generating linkage information. It makes it trivial to link any
program to a library. In the simplest case of a C program building
with make one just adds these lines to their Makefile:

    CFLAGS += $(pkg-config --cflags libthemis)
    LDFLAGS += $(pkg-config --libs libthemis)

And it just works. No need for CMake to probe for libraries, etc.

pkg-config is also able to generate correct flags for static linkage.
Static linkage is not trivial because of transitive dependencies.
For example, when linking to Themis dynamically it is sufficient
to add just `-lthemis` to linker's command line. However, for static
linkage one needs to tell `-static -lthemis -lsoter -lcrypto`,
explicitly including Soter (dependency of Themis) and SomethingSSL
(dependency of Soter) into the command line. pkg-config tracks
library dependencies and outputs correct flags as necessary.

Output of pkg-config is pretty straighforward so it may be used
not only via directly embedding into makefiles for C programs,
but by other ecosystems as well. It provides a consistent way
to locate native libraries, portable across all major operating
systems (yes, pkg-config is available on Windows as well).

Therefore it would be nice for Themis to include *.pc files for
its libraries. Each library binary should have its own pkg-config
file. These files are usually installed into "pkgconfig" directory
under the "lib" directory with library binaries. System directories
like /usr/lib/pkgconfig and /usr/local/lib/pkgconfig are usually
in the default search path of pkg-config.

The *.pc files are installed during "make install" phase and are
included into DEB and RPM packages.

We generate *.pc files during the build to include the PREFIX value
and version information there. For Soter we also include the exact
library set that's used by the selected cryptographic engine. It's
different for OpenSSL/LibreSSL and BoringSSL.

Note that for OpenSSL we could have used `Requires` directive as
OpenSSL is usually available via pkg-config as "libcrypto". However,
Themis build system does not use pkg-config to locate OpenSSL so
we do not rely on pkg-config for resolving dependencies. This is
actually important for builds on macOS with Homebrew which should
ensure that Homebrew's OpenSSL is used which is not present in the
default search path of pkg-config.

Also note that we do not include CFLAGS for Soter. That's because
Soter public header files do *not* expose the dependency on OpenSSL
which is really good design and separation of concerns, promoting
stability of Soter's ABI.

We use sed to perform template substitution. It's good enough (until
someone tries using exclamation marks `!` in their paths, but let's
not think about those weirdos). Note that we use shell pipes, not
`-i` flag of sed. That's because `-i` is actually GNU sed specific,
BSD systems usually do not have it.

* Make sure the output directory exists

BIN_PATH is normally created when building object files (grep "$(@d)"
in Makefiles), but *.pc files do not have any dependencies and thus
make decides to build these targets early. Well, create the output
directories early then.
  • Loading branch information...
ilammy authored and vixentael committed Nov 26, 2018
1 parent 0761eb4 commit bbfa9f40990a2a8e315c4ca7fef356ed4f7a330d
Showing with 62 additions and 12 deletions.
  1. +14 −5 Makefile
  2. +6 −3 src/soter/boringssl/soter.mk
  3. +11 −0 src/soter/libsoter.pc.in
  4. +6 −3 src/soter/openssl/soter.mk
  5. +8 −1 src/soter/soter.mk
  6. +11 −0 src/themis/libthemis.pc.in
  7. +6 −0 src/themis/themis.mk
@@ -247,7 +247,7 @@ JSTHEMIS_PACKAGE_VERSION=$(shell cat src/wrappers/themis/jsthemis/package.json \
| sed 's/[",]//g' \
| tr -d '[[:space:]]')
all: err themis_static themis_shared
all: err themis_static themis_shared themis_pkgconfig soter_pkgconfig
@echo $(VERSION)
soter_static: CMD = $(AR) rcs $(BIN_PATH)/lib$(SOTER_BIN).a $(SOTER_OBJ)
@@ -327,7 +327,7 @@ clean: CMD = rm -rf $(BIN_PATH)
clean: nist_rng_test_suite_clean
@$(BUILD_CMD)
make_install_dirs: CMD = mkdir -p $(PREFIX)/include/themis $(PREFIX)/include/soter $(PREFIX)/lib
make_install_dirs: CMD = mkdir -p $(PREFIX)/include/themis $(PREFIX)/include/soter $(PREFIX)/lib $(PREFIX)/lib/pkgconfig
make_install_dirs:
@echo -n "making dirs for install "
@@ -357,7 +357,13 @@ install_shared_libs: err all make_install_dirs
@echo -n "install shared libraries "
@$(BUILD_CMD_)
install: install_soter_headers install_themis_headers install_static_libs install_shared_libs
install_pkgconfig: CMD = install $(BIN_PATH)/*.pc $(PREFIX)/lib/pkgconfig
install_pkgconfig: err all make_install_dirs
@echo -n "install pkg-config files "
@$(BUILD_CMD_)
install: install_soter_headers install_themis_headers install_static_libs install_shared_libs install_pkgconfig
ifdef IS_LINUX
@ldconfig
endif
@@ -409,7 +415,7 @@ ifdef NPM_VERSION
@$(BUILD_CMD_)
endif
uninstall: CMD = rm -rf $(PREFIX)/include/themis && rm -rf $(PREFIX)/include/soter && rm -f $(PREFIX)/lib/libsoter.a && rm -f $(PREFIX)/lib/libthemis.a && rm -f $(PREFIX)/lib/libsoter.$(SHARED_EXT) && rm -f $(PREFIX)/lib/libthemis.$(SHARED_EXT)
uninstall: CMD = rm -rf $(PREFIX)/include/themis && rm -rf $(PREFIX)/include/soter && rm -f $(PREFIX)/lib/libsoter.a && rm -f $(PREFIX)/lib/libthemis.a && rm -f $(PREFIX)/lib/libsoter.$(SHARED_EXT) && rm -f $(PREFIX)/lib/libthemis.$(SHARED_EXT) && rm -f $(PREFIX)/lib/pkgconfig/libsoter.pc && rm -f $(PREFIX)/lib/pkgconfig/libthemis.pc
uninstall: phpthemis_uninstall rubythemis_uninstall themispp_uninstall jsthemis_uninstall
@echo -n "themis uninstall "
@@ -543,7 +549,10 @@ STATIC_BINARY_LIBRARY_MAP = $(foreach file,$(STATIC_LIBRARY_FILES),$(strip $(BIN
SHARED_LIBRARY_FILES = $(shell ls $(BIN_PATH)/ | egrep *\.$(SHARED_EXT)$$)
SHARED_BINARY_LIBRARY_MAP = $(foreach file,$(SHARED_LIBRARY_FILES),$(strip $(BIN_PATH)/$(file).$(LIBRARY_SO_VERSION)=$(PREFIX)/lib/$(file).$(LIBRARY_SO_VERSION) $(BIN_PATH)/$(file)=$(PREFIX)/lib/$(file)))
BINARY_LIBRARY_MAP = $(strip $(STATIC_BINARY_LIBRARY_MAP) $(SHARED_BINARY_LIBRARY_MAP))
PKGCONFIG_FILES = $(shell ls $(BIN_PATH)/ | egrep *\.pc$$)
PKGCONFIG_MAP = $(foreach file,$(PKGCONFIG_FILES),$(strip $(BIN_PATH)/$(file)=$(PREFIX)/lib/pkgconfig/$(file)))
BINARY_LIBRARY_MAP = $(strip $(STATIC_BINARY_LIBRARY_MAP) $(SHARED_BINARY_LIBRARY_MAP) $(PKGCONFIG_MAP))
POST_INSTALL_SCRIPT := $(BIN_PATH)/post_install.sh
POST_UNINSTALL_SCRIPT := $(BIN_PATH)/post_uninstall.sh
@@ -20,9 +20,12 @@ SOTER_SRC += $(wildcard $(CRYPTO_ENGINE)/*.c)
OPENSSL_DIR = libs/librebin
ifneq ($(CRYPTO_ENGINE_INCLUDE_PATH),)
CFLAGS += -I$(CRYPTO_ENGINE_INCLUDE_PATH)
CRYPTO_ENGINE_CFLAGS += -I$(CRYPTO_ENGINE_INCLUDE_PATH)
endif
ifneq ($(CRYPTO_ENGINE_LIB_PATH),)
LDFLAGS += -L$(CRYPTO_ENGINE_LIB_PATH)
CRYPTO_ENGINE_LDFLAGS += -L$(CRYPTO_ENGINE_LIB_PATH)
endif
LDFLAGS += -lcrypto -ldecrepit -lpthread
CRYPTO_ENGINE_LDFLAGS += -lcrypto -ldecrepit -lpthread
CFLAGS += $(CRYPTO_ENGINE_CFLAGS)
LDFLAGS += $(CRYPTO_ENGINE_LDFLAGS)
@@ -0,0 +1,11 @@
prefix=%prefix%
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: Soter
Description: Cryptographic primitives for Themis
Version: %version%
Cflags: -I${includedir}
Libs: -L${libdir} -lsoter
Libs.private: %crypto-libs%
@@ -21,9 +21,12 @@ SOTER_AUD_SRC += $(wildcard $(CRYPTO_ENGINE)/*.h)
OPENSSL_DIR = libs/librebin
ifneq ($(CRYPTO_ENGINE_INCLUDE_PATH),)
CFLAGS += -I$(CRYPTO_ENGINE_INCLUDE_PATH)
CRYPTO_ENGINE_CFLAGS += -I$(CRYPTO_ENGINE_INCLUDE_PATH)
endif
ifneq ($(CRYPTO_ENGINE_LIB_PATH),)
LDFLAGS += -L$(CRYPTO_ENGINE_LIB_PATH)
CRYPTO_ENGINE_LDFLAGS += -L$(CRYPTO_ENGINE_LIB_PATH)
endif
LDFLAGS += -lcrypto
CRYPTO_ENGINE_LDFLAGS += -lcrypto
CFLAGS += $(CRYPTO_ENGINE_CFLAGS)
LDFLAGS += $(CRYPTO_ENGINE_LDFLAGS)
@@ -28,4 +28,11 @@ SOTER_OBJ = $(patsubst $(SRC_PATH)/%.c,$(OBJ_PATH)/%.o, $(SOTER_SRC))
SOTER_AUD = $(patsubst $(SRC_PATH)/%,$(AUD_PATH)/%, $(SOTER_AUD_SRC))
SOTER_BIN = soter
SOTER_BIN = soter
soter_pkgconfig:
@mkdir -p $(BIN_PATH)
@sed -e "s!%prefix%!$(PREFIX)!" \
-e "s!%version%!$(VERSION)!" \
-e "s!%crypto-libs%!$(CRYPTO_ENGINE_LDFLAGS)!" \
$(SRC_PATH)/soter/libsoter.pc.in > $(BIN_PATH)/libsoter.pc
@@ -0,0 +1,11 @@
prefix=%prefix%
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: Themis
Description: High-level cryptographic services
Version: %version%
Requires.private: libsoter
Cflags: -I${includedir}
Libs: -L${libdir} -lthemis
@@ -23,3 +23,9 @@ THEMIS_OBJ = $(patsubst $(SRC_PATH)/%.c,$(OBJ_PATH)/%.o, $(THEMIS_SRC))
THEMIS_AUD = $(patsubst $(SRC_PATH)/%,$(AUD_PATH)/%, $(THEMIS_AUD_SRC))
THEMIS_BIN = themis
themis_pkgconfig:
@mkdir -p $(BIN_PATH)
@sed -e "s!%prefix%!$(PREFIX)!" \
-e "s!%version%!$(VERSION)!" \
$(SRC_PATH)/themis/libthemis.pc.in > $(BIN_PATH)/libthemis.pc

0 comments on commit bbfa9f4

Please sign in to comment.