Skip to content

Conversation

@cfis
Copy link
Contributor

@cfis cfis commented Jun 6, 2025

Fix the issues described in #8752. Specifically:

  • Correctly pass command line arguments to CMake
  • Call CMake twice - once to configure a project and a second time to build (which is the standard way to use CMake). This fixes the previously incorrect assumption that CMake generates a Make file.
  • Update the tests to specify a CMake minimum version of 3.26 (which is already two years old). 3.26 is a bit arbitrary but it aligns with Rice, and updates from the ancient 3.5 version being used (which CMake generates a warning message saying stop using it!)
  • Update the CMake call to use CMAKE_RUNTIME_OUTPUT_DIRECTORY and CMAKE_LIBRARY_OUTPUT_DIRECTORY to tell CMake to copy compiled binaries to the a Gem's lib directory.

Note the updated builder took inspiration from the Cargo Builder, meaning you first create an instance of CmakeBuilder versus just calling class methods.

Closes #8752.

Make sure the following tasks are checked

cfis pushed a commit to ruby-rice/rice that referenced this pull request Jun 6, 2025
@cfis cfis force-pushed the master branch 4 times, most recently from 3b7bba4 to 719dc4b Compare June 7, 2025 04:29
cfis pushed a commit to ruby-rice/rice that referenced this pull request Jun 7, 2025
@cfis
Copy link
Contributor Author

cfis commented Jun 13, 2025

@segiddins any other questions I can answer or feedback I should address?

@cfis
Copy link
Contributor Author

cfis commented Jun 26, 2025

Just following up - @segiddins anything else you would like to see changed? Would love to push this forward if possible.

Copy link
Contributor

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

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

Is there any existing gem using CMake extensions, or is current support so limited that nobody is using the feature?

Unfortunately I know nothing about CMake, but I did my best to try review this.

@cfis
Copy link
Contributor Author

cfis commented Jul 2, 2025

Thanks for the feedback!

Is there any existing gem using CMake extensions, or is current support so limited that nobody is using the feature?

Unfortunately I know nothing about CMake, but I did my best to try review this.

That is a good question - I don't know of any.

What I am trying to accomplish is release a new version of the ruby-opencv gem. The coding is complete but the building the extension requires CMake. That is because OpenCV only has a C++ api now (the C API was removed). Its a complex build that requires something like CMake (and in fact OpenCV does use CMake). Plus I would like to make it a lot easier to wrap C++ projects for use in Ruby - thus the work on Rice (https://github.com/ruby-rice/rice) and CMake itself.

My workaround for now is the Rice gem can install a RubyGem hook which I use to install the patch above.

@simi
Copy link
Contributor

simi commented Jul 2, 2025

Is there any existing gem using CMake extensions, or is current support so limited that nobody is using the feature?

Unfortunately I know nothing about CMake, but I did my best to try review this.

I have some basic CMake knowledge, happy to help if needed.

@cfis
Copy link
Contributor Author

cfis commented Jul 2, 2025

Thanks again @deivid-rodriguez for the feedback. I think I have addressed all the issues you brought up. I also added a new test checking for presets. I have updated the patch based on the changes.

@simi Feedback or testing always welcome. Also do you know of any gems that use CMake to build extensions?

@cfis
Copy link
Contributor Author

cfis commented Jul 9, 2025

@deivid-rodriguez anything else you would like me to address?

@cfis
Copy link
Contributor Author

cfis commented Jul 28, 2025

Hi @deivid-rodriguez just following up on this PR. Thanks again for the review!

@deivid-rodriguez
Copy link
Contributor

Sorry, I haven't yet get to this, but I should be giving it a final look and reviewing it soon 👍.

@cfis
Copy link
Contributor Author

cfis commented Jul 30, 2025

No worries - thanks for the update!

Copy link
Contributor

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

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

I'm happy to merge and let you and others try it and report/fix issues. Just one small final comment about the lib_dir parameter.

@simi Would you like to have a look, too?

@deivid-rodriguez
Copy link
Contributor

Thanks for updating! Can you rebase and resolve the merge conflict?

@deivid-rodriguez
Copy link
Contributor

Also is it intentional that commit author is https://github.com/cfisoi rather the user you are commenting from and owner of your fork?

@cfis
Copy link
Contributor Author

cfis commented Sep 10, 2025

Fixed the merge conflict. And good catch on the commit author - that was from my work github account. Fixed to use my personal one.

…ically:

* Correctly pass command line arguments to CMake
* Call CMake twice - once to configure a project and a second time to build (which is the standard way to use CMake). This fixes the previously incorrect assumption that CMake generates a Make file.
* Update the tests to specify a CMake minimum version of 3.26 (which is already two years old). 3.26 is a bit arbritary but it aligns with Rice, and updates from the ancient 3.5 version being used (which CMake generates a warning message saying stop using it!)
* Update the CMake call to use CMAKE_RUNTIME_OUTPUT_DIRECTORY and CMAKE_LIBRARY_OUTPUT_DIRECTORY to tell CMake to copy compiled binaries to the a Gem's lib directory.

Note the updated builder took inspiration from the Cargo Builder, meaning you first create an instance of CmakeBuilder versus just calling class methods.
Copy link
Contributor

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

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

Defering to @simi now, looks good from my side!

@cfis
Copy link
Contributor Author

cfis commented Oct 17, 2025

Any chance this can get merged? Thanks!

@deivid-rodriguez
Copy link
Contributor

Hei @cfis, sorry we could not get this shipped before we got kicked out, neither @simi nor myself can merge this PR anymore.

You'll have to check in with the new maintainers, good luck!

@cfis
Copy link
Contributor Author

cfis commented Oct 17, 2025

I was worried that was the case :(

Well thank you for all your help!

@hsbt
Copy link
Member

hsbt commented Oct 17, 2025

@cfis 👋 This PR looks good to me.

I'm wondering does this change work with your CMake project?

@cfis
Copy link
Contributor Author

cfis commented Oct 17, 2025

@hsbt - Yes, I need it compile my new version of opencv bindings for Ruby. See https://github.com/cfis/opencv-ruby/tree/main/ext.

In the short term, the opencv-ruby bindings will require the Rice gem. The Rice gem implements this same change via a RubyGem plugin. See https://github.com/ruby-rice/rice/blob/master/lib/rubygems_plugin.rb.

But I would much rather have this in Ruby gems.

Note I have also spent a fair bit of time updating Ruby support in CMake. See https://gitlab.kitware.com/users/cfis/activity

Thanks for looking at this.

@hsbt hsbt merged commit 2db2d47 into ruby:master Oct 17, 2025
73 checks passed
@hsbt
Copy link
Member

hsbt commented Oct 17, 2025

Thanks!

@simi
Copy link
Contributor

simi commented Oct 17, 2025

Ninja is recommended because it can build projects in parallel and thus much faster than building them serially like Make does.

I had trouble mostly with this part, since it will break later bundler integration and parallelism contract. Relying on cmake output seems brittle to me and the detection of CMakePresets.json via exception is IMHO wrong. You should check for the file presence and even somehow warn during build if not included. In general it seems too brittle to be part of RubyGems by default as is now. I was looking how to fix those until... 💥. I'm sorry I can't help more now.

@cfis
Copy link
Contributor Author

cfis commented Oct 17, 2025

Hi Simi thank you for the feedback. I am more than happy to make this better.

I have some questions:

  • What do you mean "it will break later bundler integration"? And "parallelism contract"? Not following. Not assuming Make files is very important. For the openv-ruby bindings, Ninja improves compilation time by 10x.

  • CMake Presets are becoming more popular and allow authors to tailor builds per operating system. My idea was to make it easy for someone installing a gem to see what is available. But sure, that could be taken out. It would then be up to the user to go read an extension's installation instructions

I do think this MR is a big step up from what is currently in RubyGems which is broken (not passing command line variables is a show stopper).

cfis added a commit to ruby-rice/rice that referenced this pull request Oct 23, 2025
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.

Improve CMake Support

5 participants