Skip to content

Commit a2608d6

Browse files
cfisclaude
andcommitted
Add include_dirs support to CMake visitor and fix CI test scope
CMake visitor now accepts include_dirs parameter for specifying header include paths in generated CMakeLists.txt. CI runs only rice_test and cmake_test to avoid clang-version-dependent ffi golden file mismatches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b7da0f2 commit a2608d6

5 files changed

Lines changed: 71 additions & 58 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ jobs:
2929
bundler-cache: true
3030

3131
- name: Run tests
32-
run: bundle exec rake test
32+
run: bundle exec ruby -Ilib -Itest test/rice_test.rb test/cmake_test.rb

lib/ruby-bindgen/visitors/cmake/cmake.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
module RubyBindgen
22
module Visitors
33
class CMake
4-
attr_reader :project, :outputter
4+
attr_reader :project, :outputter, :include_dirs
55

6-
def initialize(project, outputter)
7-
@project = project
6+
def initialize(outputter, project = nil, include_dirs: [])
7+
@project = project&.gsub(/-/, '_')
88
@outputter = outputter
9+
@include_dirs = include_dirs
910
end
1011

1112
def render_template(template, local_variables = {})
@@ -24,23 +25,23 @@ def visit_translation_unit(translation_unit, path, relative_path)
2425
end
2526

2627
def create_project(path)
27-
rice_include_path = File.expand_path(File.join(Gem.find_files("rice").first, "..", "..", "include"))
2828
# Create top level CMakeLists.txt
29-
directories = path.children.find_all do |path|
30-
path.directory?
29+
directories = path.children.find_all do |child|
30+
child.directory? && child.basename.to_s[0] != "." && child.basename.to_s != "build"
3131
end
3232

3333
files = path.glob("*-rb.cpp")
3434

35-
content = render_template("project", :rice_include_path => rice_include_path,
36-
:project => self.project, :directories => directories, :files => files)
35+
content = render_template("project",
36+
:project => self.project, :directories => directories, :files => files, :include_dirs => self.include_dirs)
3737
self.outputter.write("CMakeLists.txt", content)
3838
end
3939

4040
def create_directories(path)
4141
path.children.each do |child|
4242
next unless child.directory?
4343
next if child.basename.to_s[0] == "."
44+
next if child.basename.to_s == "build"
4445

4546
directories = child.children.find_all do |path|
4647
path.directory?
@@ -52,16 +53,15 @@ def create_directories(path)
5253
content = render_template("directory",
5354
:project => self.project, :directories => directories, :files => files)
5455
relative_path = child.relative_path_from(self.outputter.base_path)
55-
#
56-
# self.outputter.write(File.join(relative_path, "CMakeLists.txt"), content)
56+
self.outputter.write(File.join(relative_path, "CMakeLists.txt"), content)
5757

5858
self.create_directories(child)
5959
end
6060
end
6161

6262
def visit_start
6363
pathname = Pathname.new(self.outputter.base_path)
64-
#create_project(pathname)
64+
create_project(pathname)
6565
create_directories(pathname)
6666
end
6767

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,73 @@
1-
cmake_minimum_required (VERSION 3.26)
2-
3-
project("<%= project %>")
1+
cmake_minimum_required(VERSION 3.26)
42

53
set(CMAKE_CXX_STANDARD 17)
64
set(CMAKE_CXX_STANDARD_REQUIRED ON)
75

8-
add_library (${CMAKE_PROJECT_NAME} SHARED)
9-
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES SUFFIX ".so")
6+
project("<%= project %>" LANGUAGES CXX)
107

11-
if (MINGW)
12-
target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC -ftemplate-backtrace-limit=0)
13-
target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC -Wa,-mbig-obj)
14-
# https://github.com/doxygen/doxygen/issues/9269#issuecomment-1094975328
15-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1")
16-
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
17-
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
18-
add_compile_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
19-
add_compile_definitions(CVAPI_EXPORTS)
20-
target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC /bigobj)
8+
# Create the Extension Library
9+
if (MSVC)
10+
add_library(${CMAKE_PROJECT_NAME} SHARED)
11+
else ()
12+
add_library(${CMAKE_PROJECT_NAME} MODULE)
13+
endif ()
2114

22-
# The default of /EHsc crashes Ruby when calling longjmp with optimizations on (/O2)
23-
string(REGEX REPLACE "/EHsc" "/EHs" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
24-
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${CMAKE_PROJECT_NAME})
25-
set_property(TARGET ${CMAKE_PROJECT_NAME} PROPERTY VS_DEBUGGER_COMMAND $<$<CONFIG:DEBUG>:\$(ProjectDir))
15+
# Fetch Rice from GitHub
16+
include(FetchContent)
2617

27-
# set(OpenCV_ROOT "${VCPKG_INSTALLED_DIR}/x64-windows/share/opencv4")
28-
#target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "C:/Source/vcpkg/installed/x64-windows/include")
29-
#target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.41.34120/include")
30-
#target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "C:/Program Files (x86)/Windows Kits/10/include/10.0.22621.0/ucrt")
31-
#target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/Llvm/lib/clang/17/include")
32-
#target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.6/include")
33-
#target_link_directories(${CMAKE_PROJECT_NAME} PUBLIC "C:/Source/vcpkg/installed/x64-windows/debug/lib")
18+
FetchContent_Declare(
19+
rice
20+
GIT_REPOSITORY https://github.com/ruby-rice/rice.git
21+
GIT_TAG master
22+
)
23+
FetchContent_MakeAvailable(rice)
3424

35-
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
36-
target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC -ftemplate-backtrace-limit=0)
37-
target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC -Wa,-mbig-obj)
38-
endif ()
25+
# Configure Ruby Detection
26+
list(PREPEND CMAKE_MODULE_PATH "${rice_SOURCE_DIR}")
3927

4028
# Find Ruby
41-
#find_package(Ruby REQUIRED)
42-
include("c:/Source/Rice/FindRuby.cmake")
43-
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${Ruby_INCLUDE_DIR} ${Ruby_CONFIG_INCLUDE_DIR})
44-
target_link_libraries(${CMAKE_PROJECT_NAME} ${Ruby_LIBRARY})
29+
find_package(Ruby REQUIRED)
30+
31+
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
32+
Ruby::Module
33+
)
34+
35+
# Link to Rice
36+
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
37+
Rice::Rice
38+
)
4539

46-
# Add include for Rice
47-
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC "<%= rice_include_path %>")
40+
# Include Directories
41+
<% include_dirs.each do |dir| -%>
42+
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
43+
"<%= dir %>"
44+
)
45+
<% end -%>
4846

49-
# OpenCv
50-
find_package(OpenCV CONFIG REQUIRED)
51-
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${OpenCV_INCLUDE_DIRS})
52-
target_link_libraries(${CMAKE_PROJECT_NAME} ${OpenCV_LIBS})
47+
# Configure Extension Output
48+
get_target_property(RUBY_EXT_SUFFIX Ruby::Ruby INTERFACE_RUBY_EXTENSION_SUFFIX)
49+
50+
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
51+
PREFIX ""
52+
SUFFIX "${RUBY_EXT_SUFFIX}"
53+
OUTPUT_NAME "<%= project %>"
54+
CXX_VISIBILITY_PRESET hidden
55+
VISIBILITY_INLINES_HIDDEN ON
56+
WINDOWS_EXPORT_ALL_SYMBOLS OFF
57+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../lib/${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}"
58+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../lib"
59+
)
5360

5461
# Subdirectories
5562
<% directories.each do |directory| -%>
56-
add_subdirectory ("<%= directory.relative_path_from(directory.parent) %>")
63+
add_subdirectory("<%= directory.relative_path_from(directory.parent) %>")
5764
<% end -%>
5865

5966
# Sources
6067
<% if !files.empty? -%>
61-
target_sources(${CMAKE_PROJECT_NAME} PUBLIC
62-
<% files.each do |file| -%>
68+
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
69+
<% files.each do |file| -%>
6370
"<%= file.relative_path_from(file.parent) %>"
64-
<% end -%>
71+
<% end -%>
6572
)
66-
<% end -%>
73+
<% end -%>

test/bindings/cpp/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
3737
Rice::Rice
3838
)
3939

40+
# Include Directories
41+
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
42+
"${CMAKE_CURRENT_SOURCE_DIR}/../../headers/cpp"
43+
)
44+
4045
# Configure Extension Output
4146
get_target_property(RUBY_EXT_SUFFIX Ruby::Ruby INTERFACE_RUBY_EXTENSION_SUFFIX)
4247

test/cmake_test.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ class CMakeTest < AbstractTest
66
def test_cmake
77
header = "cpp/classes.hpp"
88
parser = create_parser(header)
9-
visitor = create_visitor(RubyBindgen::Visitors::CMake, header, project: "test_project")
9+
visitor = create_visitor(RubyBindgen::Visitors::CMake, header, project: "test_project",
10+
include_dirs: ["${CMAKE_CURRENT_SOURCE_DIR}/../../headers/cpp"])
1011
parser.generate(visitor)
1112
validate_result(visitor.outputter)
1213
end

0 commit comments

Comments
 (0)