Skip to content

improve: allow pkgconfig fallback on Linux#1670

Open
grepwood wants to merge 2 commits intoopentibiabr:mainfrom
grepwood:GITHUB-1543-allow-pkgconfig-fallback-on-linux
Open

improve: allow pkgconfig fallback on Linux#1670
grepwood wants to merge 2 commits intoopentibiabr:mainfrom
grepwood:GITHUB-1543-allow-pkgconfig-fallback-on-linux

Conversation

@grepwood
Copy link
Copy Markdown
Contributor

@grepwood grepwood commented Mar 22, 2026

Description

Summary:
This PR concerns the consumption of the following libraries:

  • INIReader (provided by inih as C++ bindings)
  • VorbisFile (provided by Vorbis)
  • Vorbis
  • OGG
  • GLEW

On most Linux distributions these libraries are provided without CMake package configuration files, which means that on Linux, projects normally consume them via pkgconfig. vcpkg is the only package manager I know that provides CMake package configuration files for these libraries and with OTClient's extensive reliance on vcpkg we can now see why OTClient is written with the assumption that these files exist. This assumption falls apart on pretty much every Linux distribution when vcpkg is not used.

This PR introduces detection of vcpkg triplets in places where these libraries are loaded by CMake. The proposed changes accomodate both scenarios: when vcpkg is present, and when it isn't. That way we should not encounter a situation like in #1508 where CICD passes the build, but the build fails on a user's machine.

Issues fixed:

Motivation:
I want to package OTClient for Gentoo in my overlay: https://github.com/grepwood/timberlay

Context:
I can provide ebuilds for dependencies that are missing from Gentoo's main repository. But changes in affected libraries (dev-libs/inih, media-libs/libvorbis, media-libs/libogg, media-libs/glew) that would render this PR unnecessary are not welcome by maintainers of Gentoo Linux. The general argument was that CMake is not used to build them, but upon inspection I found out more substantial reasons to support that decision:

  • CMake configuration files for these packages are out of date, they fall apart with CMake 4.1.4
  • those files don't fall apart with CMake included with MSVC 2019, which probably means those files are only there to allow vcpkg to package them for Windows

Dependencies:
On systems with vcpkg, nothing changes.
On systems without vcpkg, these libraries need to be installed through the system's package manager. Here is an example:

Distro Package names
Gentoo - dev-libs/inih
- media-libs/libvorbis
- media-libs/libogg
- media-libs/glew
Debian - libinih-dev
- libvorbis-dev
- libogg-dev
- libglew-dev
RHEL - inih-devel
- libvorbis-devel
- libogg-devel
- glew-devel

Behavior

Actual

OTClient's CMake setup expects that these libraries always ship CMake package configuration files which is not true on Linux distributions in general. This will happen on a system without vcpkg:

-- The C compiler identification is GNU 15.2.1
-- The CXX compiler identification is GNU 15.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Enabled: ipo
-- Found Protobuf: /usr/lib64/libprotobuf.so (found version "6.31.1")
-- Found Threads: TRUE
-- Found Protobuf Compiler: /usr/bin/protoc
-- Build type: 
-- Build commit: 
-- Build revision: 
-- Found ZLIB: /usr/lib64/libz.so (found version "1.3.1")
-- Looking for C++ include parallel_hashmap/phmap.h
-- Looking for C++ include parallel_hashmap/phmap.h - found
-- Looking for C++ include parallel_hashmap/btree.h
-- Looking for C++ include parallel_hashmap/btree.h - found
-- Looking for lzma_auto_decoder in /usr/lib64/liblzma.so
-- Looking for lzma_auto_decoder in /usr/lib64/liblzma.so - found
-- Looking for lzma_easy_encoder in /usr/lib64/liblzma.so
-- Looking for lzma_easy_encoder in /usr/lib64/liblzma.so - found
-- Looking for lzma_lzma_preset in /usr/lib64/liblzma.so
-- Looking for lzma_lzma_preset in /usr/lib64/liblzma.so - found
-- Found LibLZMA: /usr/lib64/liblzma.so (found version "5.8.2")
-- Found nlohmann_json: /usr/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake (found version "3.12.0")
-- Found asio: /usr/include
-- Found OpenSSL: /usr/lib64/libcrypto.so (found suitable version "3.5.5", minimum required is "3.0.0") found components: Crypto SSL
-- Found httplib: /usr/lib64/libcpp-httplib.so.0.26.0 (found version "0.26.0")
CMake Error at src/CMakeLists.txt:146 (find_package):
  Could not find a package configuration file provided by "unofficial-inih"
  with any of the following names:

    unofficial-inihConfig.cmake
    unofficial-inih-config.cmake

  Add the installation prefix of "unofficial-inih" to CMAKE_PREFIX_PATH or
  set "unofficial-inih_DIR" to a directory containing one of the above files.
  If "unofficial-inih" provides a separate development package or SDK, be
  sure it has been installed.


-- Configuring incomplete, errors occurred!

The same problem occurs with vorbis, vorbisfile, ogg and glew.

Expected

After applying this patch, source configuration should go down like this:

-- The C compiler identification is GNU 15.2.1
-- The CXX compiler identification is GNU 15.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Enabled: ipo
-- Found Protobuf: /usr/lib64/libprotobuf.so (found version "6.31.1")
-- Found Threads: TRUE
-- Found Protobuf Compiler: /usr/bin/protoc
-- Build type: 
-- Build commit: 
-- Build revision: 
-- Found ZLIB: /usr/lib64/libz.so (found version "1.3.1")
-- Looking for C++ include parallel_hashmap/phmap.h
-- Looking for C++ include parallel_hashmap/phmap.h - found
-- Looking for C++ include parallel_hashmap/btree.h
-- Looking for C++ include parallel_hashmap/btree.h - found
-- Looking for lzma_auto_decoder in /usr/lib64/liblzma.so
-- Looking for lzma_auto_decoder in /usr/lib64/liblzma.so - found
-- Looking for lzma_easy_encoder in /usr/lib64/liblzma.so
-- Looking for lzma_easy_encoder in /usr/lib64/liblzma.so - found
-- Looking for lzma_lzma_preset in /usr/lib64/liblzma.so
-- Looking for lzma_lzma_preset in /usr/lib64/liblzma.so - found
-- Found LibLZMA: /usr/lib64/liblzma.so (found version "5.8.2")
-- Found nlohmann_json: /usr/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake (found version "3.12.0")
-- Found asio: /usr/include
-- Found OpenSSL: /usr/lib64/libcrypto.so (found suitable version "3.5.5", minimum required is "3.0.0") found components: Crypto SSL
-- Found httplib: /usr/lib64/libcpp-httplib.so.0.26.0 (found version "0.26.0")
-- Checking for module 'INIReader'
--   Found INIReader, version 62
-- Found Freetype: /usr/lib64/libfreetype.so (found version "2.14.1")
-- Found X11: /usr/include
-- Looking for XOpenDisplay in /usr/lib64/libX11.so;/usr/lib64/libXext.so
-- Looking for XOpenDisplay in /usr/lib64/libX11.so;/usr/lib64/libXext.so - found
-- Looking for gethostbyname
-- Looking for gethostbyname - found
-- Looking for connect
-- Looking for connect - found
-- Looking for remove
-- Looking for remove - found
-- Looking for shmat
-- Looking for shmat - found
-- Looking for IceConnectionNumber in ICE
-- Looking for IceConnectionNumber in ICE - found
-- Disabled: Discord Rich Presence
-- Checking for module 'vorbisfile'
--   Found vorbisfile, version 1.3.7
-- Checking for module 'vorbis'
--   Found vorbis, version 1.3.7
-- Checking for module 'ogg'
--   Found ogg, version 1.3.6
CMake Warning (dev) at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:430 (message):
  The package name passed to find_package_handle_standard_args() (X11) does
  not match the name of the calling package (OpenGL).  This can lead to
  problems in calling code that expects find_package() result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  /usr/share/cmake/Modules/FindX11.cmake:684 (find_package_handle_standard_args)
  cmake/FindOpenGL.cmake:128 (INCLUDE)
  src/CMakeLists.txt:221 (find_package)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Checking for module 'glew'
--   Found glew, version 2.2.0
-- Found LuaJIT: /usr/lib64/libluajit-5.1.so
-- Use precompiled header: ON
-- Enabled: Build unity for speed up compilation
-- Disabled: asan
-- Disabled: DEBUG LOG
-- Disabled: Build tests
-- Configuring done (5.8s)
-- Generating done (0.1s)
-- Build files have been written to: /home/mdec/git/grepwood/otclient/build

Fixes

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [?] This change requires a documentation update

Documentation update - not sure. This change is intended to accomodate package maintainers, which should rely on the distro's package manager instead of vcpkg. These changes do not break the intended way of compiling with vcpkg, but they do offer ways to compile without it as a fallback.

If documentation change is deemed necessary, then the list of packages from the example should be resolved per supported distro and included in the docs. Ubuntu should have the same packages as Debian.

How Has This Been Tested

In grepwood/timberlay@58d26bd I have added OTClient 4.0 with a similar patch grepwood/timberlay@58d26bd#diff-45871ba1da40e367a7028597e8c71485b94db0041b10bc69542667a6286d7239 that just isn't up to date as per the master branch of OTClient, due to OTClient now pulling in FreeType. Building the package passes - but the src_install phase will differ in the future, because OTClient requires more for running than just the binary.

Test Configuration:

  • Server Version: None tried
  • Client: 4.0
  • Operating System: Gentoo Linux

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I checked the PR checks reports
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works

Summary by CodeRabbit

  • Chores
    • Improved build configuration to better handle different dependency providers and package managers, enabling conditional resolution of media and graphics libraries and the INI reader. This increases compatibility and robustness across platforms (including non-WASM/non-Android builds), reducing manual setup and improving build success in diverse development environments.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 72d5bb3f-905e-436a-a7b8-cc2af1ce691c

📥 Commits

Reviewing files that changed from the base of the PR and between 58818e1 and 3c4b030.

📒 Files selected for processing (1)
  • src/CMakeLists.txt
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/CMakeLists.txt

📝 Walkthrough

Walkthrough

CMakeLists.txt now conditionally resolves dependencies based on VCPKG_TARGET_TRIPLET: when defined it uses find_package(), otherwise it requires PkgConfig and uses pkg_check_modules() to discover inih, Vorbis/Ogg, and GLEW, creating alias/imported targets to expose unified targets.

Changes

Cohort / File(s) Summary
Build Configuration Refactoring
src/CMakeLists.txt
Added conditional dependency resolution based on VCPKG_TARGET_TRIPLET. When absent, requires PkgConfig and uses pkg_check_modules() to find INIReader (alias unofficial::inih::inireader), Vorbis/Ogg (Vorbis::vorbisfile, Vorbis::vorbis, Ogg::ogg), and glew (alias GLEW::GLEW). Sets GLEW_LIBRARY from GLEW_LIBRARIES if needed and centralizes target usage.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through CMake's tangled wood,
Found vcpkg trails and pkg-config good,
Aliases stitched, imports in a row,
Builds now know which path to go! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'improve: allow pkgconfig fallback on Linux' directly summarizes the main change: adding pkg-config fallback support when vcpkg is not available, which is the primary objective of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/CMakeLists.txt (1)

190-207: Consider using IMPORTED_TARGET for consistency with the INIReader pattern.

The INIReader fallback (line 149) uses IMPORTED_TARGET and then creates an alias, which is cleaner. The same pattern could be applied here for consistency and to reduce boilerplate.

♻️ Suggested refactor using IMPORTED_TARGET
-    pkg_check_modules(VORBISFILE REQUIRED vorbisfile)
-    add_library(Vorbis::vorbisfile INTERFACE IMPORTED)
-    set_target_properties(Vorbis::vorbisfile PROPERTIES
-      INTERFACE_INCLUDE_DIRECTORIES "${VORBISFILE_INCLUDE_DIRS}"
-      INTERFACE_LINK_LIBRARIES "${VORBISFILE_LIBRARIES}"
-    )
-    pkg_check_modules(VORBIS REQUIRED vorbis)
-    add_library(Vorbis::vorbis INTERFACE IMPORTED)
-    set_target_properties(Vorbis::vorbis PROPERTIES
-      INTERFACE_INCLUDE_DIRECTORIES "${VORBIS_INCLUDE_DIRS}"
-      INTERFACE_LINK_LIBRARIES "${VORBIS_LIBRARIES}"
-    )
-    pkg_check_modules(OGG REQUIRED ogg)
-    add_library(Ogg::ogg INTERFACE IMPORTED)
-    set_target_properties(Ogg::ogg PROPERTIES
-      INTERFACE_INCLUDE_DIRECTORIES "${OGG_INCLUDE_DIRS}"
-      INTERFACE_LINK_LIBRARIES "${OGG_LIBRARIES}"
-    )
+    pkg_check_modules(VORBISFILE REQUIRED IMPORTED_TARGET vorbisfile)
+    add_library(Vorbis::vorbisfile ALIAS PkgConfig::VORBISFILE)
+    pkg_check_modules(VORBIS REQUIRED IMPORTED_TARGET vorbis)
+    add_library(Vorbis::vorbis ALIAS PkgConfig::VORBIS)
+    pkg_check_modules(OGG REQUIRED IMPORTED_TARGET ogg)
+    add_library(Ogg::ogg ALIAS PkgConfig::OGG)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CMakeLists.txt` around lines 190 - 207, Replace the direct
add_library(... INTERFACE IMPORTED) entries for Vorbis::vorbisfile,
Vorbis::vorbis and Ogg::ogg with the same IMPORTED_TARGET + alias pattern used
by INIReader: create a private IMPORTED target (e.g., vorbisfile::imported,
vorbis::imported, ogg::imported) via add_library(<name> IMPORTED GLOBAL), set
its INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_LINK_LIBRARIES with the
corresponding ${VORBISFILE_INCLUDE_DIRS}/${VORBISFILE_LIBRARIES},
${VORBIS_INCLUDE_DIRS}/${VORBIS_LIBRARIES},
${OGG_INCLUDE_DIRS}/${OGG_LIBRARIES}, then create the public alias targets
Vorbis::vorbisfile, Vorbis::vorbis and Ogg::ogg using
add_library(Vorbis::vorbisfile ALIAS vorbisfile::imported) (and likewise for the
others) to match the INIReader pattern and reduce boilerplate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/CMakeLists.txt`:
- Line 811: Remove the mistaken use of the CMake imported target name
"GLEW::GLEW" from the target_include_directories call;
target_include_directories expects directory paths, not target names, and GLEW's
INTERFACE_INCLUDE_DIRECTORIES are already propagated when you link to it with
target_link_libraries (the existing link to GLEW::GLEW). Locate the call to
target_include_directories that currently lists GLEW::GLEW and delete that entry
so only real directory paths remain (or remove the entire
target_include_directories call if it only contained GLEW::GLEW), leaving the
existing target_link_libraries invocation to provide the include paths.
- Around line 146-151: The CMake logic uses pkg_check_modules when
VCPKG_TARGET_TRIPLET is not defined but never ensures the PkgConfig module is
loaded; add a find_package(PkgConfig REQUIRED) call before invoking
pkg_check_modules (either immediately above the existing conditional or inside
the else branch) so that pkg_check_modules is available; update the block around
VCPKG_TARGET_TRIPLET / pkg_check_modules /
add_library(unofficial::inih::inireader ALIAS PkgConfig::INIReader) accordingly.

---

Nitpick comments:
In `@src/CMakeLists.txt`:
- Around line 190-207: Replace the direct add_library(... INTERFACE IMPORTED)
entries for Vorbis::vorbisfile, Vorbis::vorbis and Ogg::ogg with the same
IMPORTED_TARGET + alias pattern used by INIReader: create a private IMPORTED
target (e.g., vorbisfile::imported, vorbis::imported, ogg::imported) via
add_library(<name> IMPORTED GLOBAL), set its INTERFACE_INCLUDE_DIRECTORIES and
INTERFACE_LINK_LIBRARIES with the corresponding
${VORBISFILE_INCLUDE_DIRS}/${VORBISFILE_LIBRARIES},
${VORBIS_INCLUDE_DIRS}/${VORBIS_LIBRARIES},
${OGG_INCLUDE_DIRS}/${OGG_LIBRARIES}, then create the public alias targets
Vorbis::vorbisfile, Vorbis::vorbis and Ogg::ogg using
add_library(Vorbis::vorbisfile ALIAS vorbisfile::imported) (and likewise for the
others) to match the INIReader pattern and reduce boilerplate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f1315d63-f4db-4369-9a62-c6f131d1af52

📥 Commits

Reviewing files that changed from the base of the PR and between 294896c and 58818e1.

📒 Files selected for processing (1)
  • src/CMakeLists.txt

@majestyotbr majestyotbr changed the title Allow pkgconfig fallback on Linux improve: allow pkgconfig fallback on Linux Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant