Skip to content

Conversation

@ev3nvy
Copy link

@ev3nvy ev3nvy commented Oct 14, 2025

This PR implements proper CMake find_package support and improves behavior when added via
add_subdirectory.

First, a disclaimer:

I am no CMake expert, but I do understand how the code works. Code was written with the help of Modern CMake Packaging Guide, CMake documentation and various real-world examples (namely, JSON for Modern C++, tl::expected, simdjson and the extended project of the Modern CMake Guide). No AI was used in the making of this PR.

Reviewing

Because I've rewritten most of the CMake configuration, reviewing the diff is probably annoying. I considered making multiple smaller commits, but I couldn't think of a good way to make changes smaller and make them still make sense.
Apologies in advance.

I tried to preserve as many things as possible. That includes compiler flags, cpp standard used, etc., although some things (such as cpp standard) are now set per-target instead.

Things of note/remaining questions

  • How to name things (the age-old question)?

    I picked libsgp4 as the namespace1, SGP4 as project name (the same as it was) and import path, and changed targets2. Import path was chosen for compatibility with the Conan package (never tested, going off of website information) 3.

  • Installation path

    CMakeLists.txt previously included the following:

    if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
        set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "..." FORCE)
    endif()

    I can revert this change if you wish.

  • Source file names

    I changed the extension for source files (from cc to cpp) mainly because I've seen the latter used more often. I can revert these back to cc.

  • GitHub Actions

    GitHub actions workflow might need adjustments. Unsure.

  • pkg-config

    Using SGP4 via pkg-config in CMake is not great. Considering this, I wouldn't be opposed to removing pkg-config support (in exchange for slightly less complex build system).

  • Test README examples

    As noted in the related commit, I haven't tested those examples. This is mostly a reminder for me, or if someone somehow beats me to it.

  • Package Manager integration

    I'll likely upstream a vcpkg package if this PR gets accepted and I might also update the library over at nixpkgs (although, no promises for either). I have no plans for other package managers.

Testing

Test repo available here. I also verified configuring, building and installing works with the minimum CMake version 3.16 (specifically 3.16.9) on my Windows machine. I haven't tested if CMake 4.0 works.

My Windows 11 environment
  • Operating system: Microsoft Windows 11 Home (version 10.0.26100 Build 26100)
  • Visual Studio Installer version: 3.14.2086.54749
  • Visual Studio Community 2022 version: 17.14.16
  • Visual Studio Community 2022 components:
    • C++ core desktop features
    • MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest)
    • C++ Build Insights
    • Just-In-Time debugger
    • C++ profiling tools
    • C++ CMake tools for Windows
    • C++ AddressSanitizer
    • Windows 11 SDK (10.0.26100.4654)
    • C++ Clang tools for Windows (19.1.5 - x64/x86)
$ cmake --version
cmake version 3.31.6-msvc6

CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ ninja --version
1.12.1
$ clang --version
clang version 19.1.5
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin

Configure command:

cmake -S . -B build -GNinja

Build command:

cmake --build build
My Ubuntu 22.04.5 LTS environment

Prerequisites:

sudo apt install build-essential cmake ninja-build git
$ cmake --version
cmake version 3.22.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ ninja --version
1.10.1
$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Configure command:

cmake -S . -B build -GNinja

Build command:

cmake --build build

Footnotes

  1. Modern CMake Packaging Guide links to
    the following discussion on Reddit

  2. Originally I kept target names the same, but I kept tripping over the fact that the sgp4 target was static and sgp4s was shared (which seems opposite of something like simdjson). I am still fine with changing back to previous behavior (preferably guarded by CMake option so consumers don't need to build both when using just one).

  3. Using libsgp4 as import path would be my second choice, because I feel like the following code wouldn't have been uncommon:

    CMakeLists.txt:

    # ...
    
    set(SGP4_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/thirdparty/sgp4/libsgp4")
    
    # ignore installs
    add_subdirectory(${SGP4_INCLUDE_DIR} EXCLUDE_FROM_ALL)
    
    # required for libsgp4 prefix in includes
    get_filename_component(SGP4_PARENT_INCLUDE_DIR ${SGP4_INCLUDE_DIR} DIRECTORY)
    
    # imports fail without this
    target_include_directories(sgp4 PUBLIC ${SGP4_PARENT_INCLUDE_DIR})
    target_include_directories(sgp4s PUBLIC ${SGP4_PARENT_INCLUDE_DIR})
    
    message(STATUS "SGP4 include directories: ${SGP4_PARENT_INCLUDE_DIR}")
    
    add_library(libsgp4::sgp4 ALIAS sgp4)
    add_library(libsgp4::sgp4s ALIAS sgp4s)
    
    target_link_libraries(example PRIVATE libsgp4::sgp4)
    
    # ...
    

    main.cpp:

    #include <libsgp4/Tle.h> // libsgp4 as import path instead
    
    // ...
    

@@ -1,39 +1,88 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.13.4)
PROJECT(SGP4)
cmake_minimum_required(VERSION 3.16...4.0)
Copy link
Author

Choose a reason for hiding this comment

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

I bumped this slightly. 3.16 is maximum supported by Ubuntu 20.04 and 3.18 for Debian 11.

Further bump to 3.23 would give us file sets

See: https://repology.org/project/cmake/versions

if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
project(SGP4
VERSION 1.1.0
Copy link
Author

Choose a reason for hiding this comment

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

I chose 1.1.0, because there already is a v1.0 git tag.

Comment on lines +57 to +63
# TODO: possibly replace with __declspec(dllexport) function annotations
WINDOWS_EXPORT_ALL_SYMBOLS ON
Copy link
Author

Choose a reason for hiding this comment

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

Not the biggest fan of this. I can look into migration towards GenerateExportHeader (if this is a blocker). Otherwise, anybody else reading this should feel free to tackle this.


RunTest(file_name);

return 1;
Copy link
Author

Choose a reason for hiding this comment

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

  1. I tried locally replicating what GitHub actions runner does, and the test just wasn't being ran (I can't see logs because they expired)
  2. After I got them running, they would always fail due to this return.

Am I missing something?

CMakeLists.txt Outdated
Comment on lines 21 to 24
option(SGP4_BUILD_STATIC_LIB "Build sgp4-static target along with sgp4." ${MAIN_PROJECT})
option(SGP4_INSTALL "Install CMake targets during install step." ${MAIN_PROJECT})
option(SGP4_BUILD_TESTS "Enable SGP4 tests." ${MAIN_PROJECT})
option(SGP4_BUILD_EXAMPLES "Enable SGP4 examples." ${MAIN_PROJECT})
Copy link
Author

Choose a reason for hiding this comment

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

What should the defaults for these be? Maybe default examples to OFF always and keep the rest as they are now?

@ev3nvy ev3nvy force-pushed the cmake-find-package-improvements branch from b891f3e to f3f9b31 Compare October 23, 2025 22:39
@ev3nvy
Copy link
Author

ev3nvy commented Oct 23, 2025

I took some time to test these changes on an actual project and discovered that linking a static library (e.g. sgp4-static) with a shared library (add_library(foo SHARED)) doesn't work properly. This is resolved by enabling position-independent code for static targets. For more information see spdlog discussion on the same topic.

I also made a few QOL changes (SGP4_BUILD_SHARED_LIBS, set some nice-to-have config variables, enable MSVC warnings).

Diff before and after force push available here.

@ev3nvy ev3nvy force-pushed the cmake-find-package-improvements branch from f3f9b31 to f1234b4 Compare October 28, 2025 15:50
@dnwrnr
Copy link
Owner

dnwrnr commented Oct 28, 2025

Give me sometime to look over this. Thanks!

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.

2 participants