Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cmake support #27

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Add cmake support #27

wants to merge 12 commits into from

Conversation

glebm
Copy link

@glebm glebm commented Nov 6, 2024

Adds modern CMake support, allowing SheenBidi to be used as a subproject from a CMake project (e.g. via FetchContent), with support for installation, the test suite, and a GitHub Actions workflow.

Fixes #26

Installation

Allows installing the library via CMake, which also installs CMake package definitions, enabling the use of find_package(SheenBidi):

cmake -S. -Bbuild-rel -DCMAKE_BUILD_TYPE=Release
cmake --build build-rel -j $(getconf _NPROCESSORS_ONLN)
sudo cmake --install build-rel
-- Install configuration: "Release"
-- Installing: /usr/local/lib/libsheenbidi.so
-- Installing: /usr/local/include/SheenBidi/SBAlgorithm.h
-- Installing: /usr/local/include/SheenBidi/SBBase.h
-- Installing: /usr/local/include/SheenBidi/SBBidiType.h
-- Installing: /usr/local/include/SheenBidi/SBCodepoint.h
-- Installing: /usr/local/include/SheenBidi/SBCodepointSequence.h
-- Installing: /usr/local/include/SheenBidi/SBGeneralCategory.h
-- Installing: /usr/local/include/SheenBidi/SBLine.h
-- Installing: /usr/local/include/SheenBidi/SBMirrorLocator.h
-- Installing: /usr/local/include/SheenBidi/SBParagraph.h
-- Installing: /usr/local/include/SheenBidi/SBRun.h
-- Installing: /usr/local/include/SheenBidi/SBScript.h
-- Installing: /usr/local/include/SheenBidi/SBScriptLocator.h
-- Installing: /usr/local/include/SheenBidi/SheenBidi.h
-- Installing: /usr/local/lib/cmake/SheenBidi/SheenBidiTargets.cmake
-- Installing: /usr/local/lib/cmake/SheenBidi/SheenBidiTargets-release.cmake
-- Installing: /usr/local/lib/cmake/SheenBidi/SheenBidiConfig.cmake
-- Installing: /usr/local/lib/cmake/SheenBidi/SheenBidiConfigVersion.cmake

Additionally, this also allows testing via CMake and adds a GitHub Actions workflow.

Testing

Enables sanitizers in Debug build by default. Sanitizers run in the test suite and can catch undefined behaviour and memory errors.

The test suite can be run via CTest (the CMake test runner):

cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j $(getconf _NPROCESSORS_ONLN)
ctest --test-dir build --output-on-failure -j $(getconf _NPROCESSORS_ONLN)
Internal ctest changing into directory: /home/gleb/SheenBidi/build
Test project /home/gleb/SheenBidi/build
    Start 1: tests
1/1 Test #1: tests ............................   Passed   17.07 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =  17.07 sec

GitHub Actions

A GitHub Action builds all targets and runs the tests on Linux and macOS.

/cc @BLooperZ @AJenbo

@glebm glebm mentioned this pull request Nov 6, 2024
@glebm glebm force-pushed the cmake branch 6 times, most recently from bfb659a to cc40d09 Compare November 6, 2024 23:34
Adds modern CMake support, allowing SheenBidi to be used as a subproject
from a CMake project (e.g. via `FetchContent`).
@mta452
Copy link
Member

mta452 commented Feb 1, 2025

Hey @glebm

Thanks for taking the time to write cmake scripts. I'm not very much familiar with build systems, so I have a couple of questions:

  • Is ENABLE_INSTALL a custom flag, or provided by cmake itself?
  • The library aims to be compatible with C89, can it be configured for cmake to catch issues while building?
  • Is it possible to use only a single target sheenbidi instead of differentiating between unity and non-unity versions?
  • Is it possible to define SB_CONFIG_UNITY while building the library in release modes?
  • What is CTest? Is it necessary for building the tester target?
  • Can everything be covered in a single CMakeLists.txt file instead of having multiple files in cmake folder?

@AJenbo
Copy link

AJenbo commented Feb 1, 2025

Is ENABLE_INSTALL a custom flag, or provided by cmake itself?

It's a custom flag:

option(ENABLE_INSTALL "Enable install targets" ON)

is how you define an option and set it's description and default value.

@AJenbo
Copy link

AJenbo commented Feb 1, 2025

What is CTest? Is it necessary for building the tester target?

It's not needed for building the tester target, but it is used to automate running the tests during the GitHub Action:

        run: ctest --test-dir build --output-on-failure -j $(nproc)

(last line in .github/workflows/cmake.yml)

It's also useful for IDEs that support CMake to auto discover tests.

@glebm
Copy link
Author

glebm commented Feb 2, 2025

Is ENABLE_INSTALL a custom flag, or provided by cmake itself?

It's a custom flag defined on line 5.
It is not really necessary but useful for people who like to keep their list of targets minimal (e.g. when using SheenBidi as a subproject the install targets are unnecessary).

The library aims to be compatible with C89, can it be configured for cmake to catch issues while building?

I've pushed a commit that does that. The oldest standard that CMake supports is C_STANDARD 90, which is described in the documentation as C89/C90: https://cmake.org/cmake/help/latest/prop_tgt/C_STANDARD.html#prop_tgt:C_STANDARD

Is it possible to use only a single target sheenbidi instead of differentiating between unity and non-unity versions?

Unity and non-unity have different sources, so there have to be two targets.
Currently, there sheenbidi target is the unity target, and sheenbidi_non_unity is the non-unity target that is only used for testing.

If we wanted to switch unity/non-unity based on a user-provided option, we could add an ALIAS that goes to one of the two options based on the option value.

However, I'm not sure what the use-case for that would be. Currently, the unity target is the only target that is installed.

(I also think in the future the unity target can be removed because all modern compilers support LTO but that can be a separate PR/discussion).

Is it possible to define SB_CONFIG_UNITY while building the library in release modes?

Currently, SB_CONFIG_UNITY is always defined for the sheenbidi target (regardless of the release/debug modes).
The sheenbidi_non_unity target is only used for tests and never has SB_CONFIG_UNITY defined.

What is CTest? Is it necessary for building the tester target?

CTest is the built-in CMake test tool. Like @AJenbo explains above, it handles tests in a uniform way.
There is a bit more information about CTest here https://cmake.org/cmake/help/book/mastering-cmake/chapter/Testing%20With%20CMake%20and%20CTest.html#how-does-cmake-facilitate-testing

Can everything be covered in a single CMakeLists.txt file instead of having multiple files in cmake folder?

There are 2 files in the cmake directory. The cmake/Sanitizers.cmake only contains the add_sanitizers function and we could put it into the main CMake file if you prefer. However, it is more idiomatic in CMake to have helper functions in separate files in the cmake subdirectory.

However,cmake/SheenBidi.cmake.in is standard boilerplate that has to be in its own file. It is used by configure_package_config_file to provide CMake package definitions at install time.

@glebm
Copy link
Author

glebm commented Feb 2, 2025

I've pushed a commit adding CMake documentation to the README.md, so you can see what it looks like from the perspective of the user or someone developing SheenBidi itself.

@AJenbo
Copy link

AJenbo commented Feb 2, 2025

@mta452 Visual Studio added support for CMake project in 2017 so this can also server as a replacement for Projects/VS_2017 in case you want to keep integrations to a minimum (I can help with adjusting .appveyor.yml after this PR is merged if you would like that).

I can also help you get coveralls working again using the GitHub action instead of Travis as a follow up to this.

.github/workflows/cmake.yml Outdated Show resolved Hide resolved
@glebm
Copy link
Author

glebm commented Feb 2, 2025

Added the "generator" target, so it can now also be built with CMake. It is also built in GitHub Actions.

glebm added 2 commits February 2, 2025 15:55
Must be the same as CMake namespace to use the standard package
generation.
@glebm
Copy link
Author

glebm commented Feb 2, 2025

One problem with always forcing the standard to C89 is that stdlib headers may fail to parse if they require a newer C standard (for example on Amiga with libnix https://github.com/diasurgical/devilutionX/actions/runs/13100931473/job/36549084009)

I've changed it to force C89 on CI but not by default.

glebm added 2 commits February 2, 2025 17:30
This is a library so the LTO decision should be left to the user.
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.

CMake support
3 participants