cpm-cmake / CPM.cmake

📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Enhancement: add option PATCHES in which we can pass filepathes for patches to apply to the lib/package

Gerodote opened this issue · comments

Assume we have a bad library that needs to be patched and we don't want to create a pull request, wait until a miracle happens and so on, or library just don't have github/gitlab pull request capability.

We would like to make a patch.

How to?

  1. Create patch:
    somehow get the lib
    cd the_lib_folder
    git init
    git add .
    git commit -m "initial"
  2. edit something, use your preferred method to change the code
  3. get your edits as a patch file(s) :
    git diff | tee /path_to_your_package/patches/pkg_name/patch_name.patch
  4. apply patches.
    apply -p1 -rnN -d ${library_name_SOURCE_DIR} -i filepath_to_the_patch
    there's also a git am command, you can find it somewhere at internet just googling, it will do the same, maybe its better option because IDK is the apply command portable on Windows and other environments.

How to apply patches in cmake ?
Current solution:

CPMAddPackage(pkg_name ...)
execute_process(COMMAND apply -rnN -p1 -d ${library_name_SOURCE_DIR} -i ${CMAKE_CURRENT_SOURCE_DIR}/patches/pkg_name/patch_name.patch  ... ) # -N is essential. it won't allow patch twice.

What is the proposal?

Add PATCHES option in CPMAddPackage . ( Maybe in CPMFindPackage too ).
It should take filepathes for patches. e.g. it should take ${CMAKE_CURRENT_SOURCE_DIR}/patches/${pkg_name}/* ( it can be a list of patches, which we could get using
file(GLOB_RECURSE pkg_name_patches CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/patches/pkg_name/*.patch )

I've dug into this, and it seems git apply is so tangled with git base directory that it's almost impossible to use... stackoverflow link

Also, if you don't have apply command, it seems patch does exactly the same with the same flags.

CPM already has the patch command, is this to add more convenience?

If this is to add convenience, CPM could do find_package(Patch) for the patch command and simply apply it for each file or error out if the command is not available. I do not like to acquire libraries as git repos. I prefer to get archives.

This would be much better if cmake -E patch was a thing!

At any rate, one can currently do something like:

find_package(Patch REQUIRED)

# magic_enum
#  Reflection for enumerations, pretty cool really.
#  Note the limitations: https://github.com/Neargye/magic_enum/blob/master/doc/limitations.md
set(CMAKE_FOLDER "${BASE_FOLDER}/magic_enum")
CPMAddPackage(
  NAME magic_enum
  URL      https://github.com/Neargye/magic_enum/archive/refs/tags/v0.9.5.tar.gz
  URL_HASH SHA256=44ad80db5a72f5047e01d90e18315751d9ac90c0ab42cbea7a6f9ec66a4cd679
  SYSTEM   True
  PATCH_COMMAND
    "${Patch_EXECUTABLE}" -p1 < "${CMAKE_CURRENT_LIST_DIR}/magic_enum_format.patch"
)