Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.2
0.1.3
8 changes: 4 additions & 4 deletions cmake/libe3.pc.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
prefix=@CMAKE_INSTALL_PREFIX@
prefix=@LIBE3_PC_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
datarootdir=${prefix}/@CMAKE_INSTALL_DATADIR@
libdir=@LIBE3_PC_LIBDIR@
includedir=@LIBE3_PC_INCLUDEDIR@
datarootdir=@LIBE3_PC_DATAROOTDIR@
# Root of the installed service-model definitions; each SM lives in its own
# subdir, e.g. ${smdir}/sm_simple/e3sm_simple.asn (ASN.1) and .../e3sm_simple.proto
# (Protobuf) — both are installed. Query with: pkg-config --variable=smdir libe3
Expand Down
56 changes: 56 additions & 0 deletions cmake/libe3Install.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,66 @@ if(LIBE3_PUBLIC_DEFS)
"libe3: PUBLIC compile definition '${_def}' is a generator "
"expression and cannot be exported through libe3.pc")
endif()
if(_def MATCHES "\"")
# pkg-config's Cflags tokenizer strips unescaped quotes, so a string
# macro exported this way reaches the compiler as a bare token and
# fails to lex. Escaping as \\" survives pkg-config and works for
# CMake consumers, but then breaks `cc $(pkg-config --cflags libe3)`
# with an unterminated string -- no single form is safe for both
# consumption styles. Keep string-valued macros PRIVATE and give the
# header an #ifndef fallback instead (see LATREC_DEFAULT_DIR).
message(FATAL_ERROR
"libe3: PUBLIC compile definition '${_def}' has a quoted value "
"and cannot be exported through libe3.pc -- make it PRIVATE")
endif()
string(APPEND LIBE3_PC_CFLAGS " -D${_def}")
endforeach()
endif()

# Make libe3.pc relocatable. CMAKE_INSTALL_PREFIX is a configure-time value, so
# baking it in makes the file describe where the build *expected* to be installed
# rather than where it ended up: `cmake --install --prefix <other>`, and any
# packaging step that stages into a different root, moves every file but cannot
# rewrite the .pc. The result points a consumer's -I/-L and `smdir` at a prefix
# that may contain no libe3 at all -- and pkg-config reports success while doing
# it, so the failure surfaces later as a missing header. pkg-config expands
# ${pcfiledir} to the directory holding the .pc, so deriving the prefix from that
# describes wherever the file actually is. The CMake package config is already
# relocatable through @PACKAGE_INIT@; this makes the pkg-config path agree.
#
# GNUInstallDirs allows any component directory to be absolute, in which case it
# is not under the prefix and there is nothing relative to derive -- those keep
# their absolute value, and an absolute libdir also leaves the prefix itself with
# no relative form, since that is where the .pc lands.
if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
set(LIBE3_PC_PREFIX "${CMAKE_INSTALL_PREFIX}")
else()
file(RELATIVE_PATH _libe3_pc_to_prefix
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig"
"${CMAKE_INSTALL_PREFIX}")
string(REGEX REPLACE "/+$" "" _libe3_pc_to_prefix "${_libe3_pc_to_prefix}")
if(_libe3_pc_to_prefix STREQUAL "")
set(LIBE3_PC_PREFIX "\${pcfiledir}")
else()
set(LIBE3_PC_PREFIX "\${pcfiledir}/${_libe3_pc_to_prefix}")
endif()
endif()

# CMAKE_INSTALL_DATADIR is empty in the cache until GNUInstallDirs derives it
# from DATAROOTDIR, so read the derived value rather than the cache entry.
foreach(_pair "LIBDIR:${CMAKE_INSTALL_LIBDIR}"
"INCLUDEDIR:${CMAKE_INSTALL_INCLUDEDIR}"
"DATAROOTDIR:${CMAKE_INSTALL_DATAROOTDIR}")
string(REPLACE ":" ";" _pair "${_pair}")
list(GET _pair 0 _name)
list(GET _pair 1 _dir)
if(IS_ABSOLUTE "${_dir}")
set(LIBE3_PC_${_name} "${_dir}")
else()
set(LIBE3_PC_${_name} "\${prefix}/${_dir}")
endif()
endforeach()

configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/libe3.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/libe3.pc"
Expand Down
14 changes: 12 additions & 2 deletions cmake/libe3Targets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,17 @@ if(LIBE3_ENABLE_LATREC)
# registry compiled in, or vice versa.
target_compile_definitions(libe3 PUBLIC LIBE3_ENABLE_LATREC)
if(LATREC_DEFAULT_DIR)
# PRIVATE, unlike the flag above. latrec_open_in() applies this fallback
# from src/core/latrec.c -- libe3's own translation unit -- so every
# caller of latrec_tls_open_as() inherits it without needing the macro
# itself. Exporting it would put a quoted string macro in libe3.pc,
# where pkg-config's tokenizer strips the quotes and the bare path then
# fails to lex ("expected expression before '/'"). Escaping as \\" keeps
# CMake consumers working but breaks `cc $(pkg-config --cflags libe3)`
# with an unterminated string, so there is no form that is safe for
# both. It is also a build-tree path, meaningless once installed.
target_compile_definitions(libe3
PUBLIC LATREC_DEFAULT_DIR=\"${LATREC_DEFAULT_DIR}\")
PRIVATE LATREC_DEFAULT_DIR=\"${LATREC_DEFAULT_DIR}\")
endif()
endif()

Expand Down Expand Up @@ -152,8 +161,9 @@ endif()
if(LIBE3_ENABLE_LATREC)
target_compile_definitions(libe3_shared PUBLIC LIBE3_ENABLE_LATREC)
if(LATREC_DEFAULT_DIR)
# PRIVATE for the same reason as the static target above.
target_compile_definitions(libe3_shared
PUBLIC LATREC_DEFAULT_DIR=\"${LATREC_DEFAULT_DIR}\")
PRIVATE LATREC_DEFAULT_DIR=\"${LATREC_DEFAULT_DIR}\")
endif()
endif()

Expand Down