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

Fix windows binutils #247

Merged
merged 6 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/alpine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ concurrency:
cancel-in-progress: true

env:
CACHE_VER: 17
CACHE_VER: 19
TZ: "Etc/UTC"
VERBOSE: no

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gem-test-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ concurrency:
cancel-in-progress: true

env:
CACHE_VER: 16
CACHE_VER: 19
DEBIAN_FRONTEND: "noninteractive"
TZ: "Etc/UTC"
# show cmake output
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ concurrency:
cancel-in-progress: true

env:
CACHE_VER: 17
CACHE_VER: 19
VERBOSE: no

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ concurrency:
cancel-in-progress: true

env:
CACHE_VER: 17
CACHE_VER: 19
DEBIAN_FRONTEND: "noninteractive"
TZ: "Etc/UTC"
# show cmake output (yes/no)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows-msys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ concurrency:
cancel-in-progress: true

env:
CACHE_VER: 17
CACHE_VER: 19
VERBOSE: no

jobs:
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ if (${SETUP_MODE})

add_dependencies(tebako-fs packaged_filesystem)

add_custom_target(tebako COMMAND ruby ${EXE}/tebako-packager finalize ${OSTYPE_TXT} ${RUBY_SOURCE_DIR} ${APP_NAME} ${RUBY_VER} ${DEPS_BIN_DIR}/patchelf ${WITH_PATCHELF})
add_custom_target(tebako COMMAND ruby ${EXE}/tebako-packager finalize ${RUBY_SOURCE_DIR} ${APP_NAME} ${RUBY_VER} ${DEPS_BIN_DIR}/patchelf ${WITH_PATCHELF})
add_dependencies(tebako setup tebako-fs)

endif(${SETUP_MODE})
21 changes: 10 additions & 11 deletions exe/tebako-packager
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,18 @@ begin

when "finalize"
# ARGV[0] -- command
# ARGV[1] -- OSTYPE
# ARGV[2] -- RUBY_SOURCE_DIR
# ARGV[3] -- APP_NAME
# ARGV[4] -- RUBY_VER
# ARGV[5] -- patchelf executable
# ARGV[6] -- WITH_PATHELF
unless ARGV.length == 7
# ARGV[1] -- RUBY_SOURCE_DIR
# ARGV[2] -- APP_NAME
# ARGV[3] -- RUBY_VER
# ARGV[4] -- patchelf executable
# ARGV[5] -- WITH_PATHELF
unless ARGV.length == 6
raise Tebako::Error,
"tebako-packager finalize command expects 7 arguments, #{ARGV.length} has been provided."
"tebako-packager finalize command expects 6 arguments, #{ARGV.length} has been provided."
end
ruby_ver = Tebako::RubyVersion.new(ARGV[4])
with_patchelf = ARGV[6].casecmp("ON").zero? || ARGV[6].casecmp("YES").zero?
Tebako::Packager.finalize(ARGV[1], ARGV[2], ARGV[3], ruby_ver, with_patchelf ? ARGV[5] : nil)
ruby_ver = Tebako::RubyVersion.new(ARGV[3])
with_patchelf = ARGV[5].casecmp("ON").zero? || ARGV[5].casecmp("YES").zero?
Tebako::Packager.finalize(ARGV[1], ARGV[2], ruby_ver, with_patchelf ? ARGV[4] : nil)
else
raise Tebako::Error, "tebako-packager cannot process #{ARGV[0]} command"
end
Expand Down
14 changes: 0 additions & 14 deletions lib/tebako/build_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,6 @@ module Tebako
# Ruby build helpers
module BuildHelpers
class << self
def ncores
if RUBY_PLATFORM.include?("darwin")
out, st = Open3.capture2e("sysctl", "-n", "hw.ncpu")
else
out, st = Open3.capture2e("nproc", "--all")
end

if !st.signaled? && st.exitstatus.zero?
out.strip.to_i
else
4
end
end

def run_with_capture(args)
args = args.compact
puts " ... @ #{args.join(" ")}"
Expand Down
35 changes: 28 additions & 7 deletions lib/tebako/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

require "digest"
require "fileutils"
require "find"
require "pathname"
require "open3"
require "thor"
require "yaml"
Expand All @@ -36,6 +38,7 @@
require_relative "cli_helpers"
require_relative "error"
require_relative "ruby_version"
require_relative "scenario_manager"
require_relative "version"

# Tebako - an executable packager
Expand Down Expand Up @@ -66,10 +69,11 @@ def clean_ruby
(om,) = bootstrap(clean: true)

suffix = options["Ruby"].nil? ? "" : "_#{options["Ruby"]}"
nmr = "src/_ruby#{suffix}*"
nms = "stash#{suffix}*"
FileUtils.rm_rf(Dir.glob(File.join(om.deps, nmr)), secure: true)
FileUtils.rm_rf(Dir.glob(File.join(om.deps, nms)), secure: true)
nmr = Dir.glob(File.join(om.deps, "src", "_ruby#{suffix}*"))
nms = Dir.glob(File.join(om.deps, "stash#{suffix}*"))

FileUtils.rm_rf(nmr + nms, secure: true)
extra_win_clean(nmr)
end

desc "hash", "Print build script hash (ci cache key)"
Expand Down Expand Up @@ -147,13 +151,29 @@ def bootstrap(clean: false)
[options_manager, cache_manager]
end

# Ruby extension maker sometimes creates files with 'NUL' name on Windows
# This method removes such files
def extra_win_clean(nmr)
return unless nmr.any? && ScenarioManagerBase.new.msys?

nmr.each do |path|
if File.basename(path) == "NUL"
full_path = "//?/#{path}"
FileUtils.rm_f(full_path)
end
end
FileUtils.rm_rf(nmr, secure: true)
end

def initialize(*args)
super
return if args[2][:current_command].name.include?("hash")

puts "Tebako executable packager version #{Tebako::VERSION}"
end
end

no_commands do
def options
original_options = super
tebafile = original_options["tebafile"].nil? ? DEFAULT_TEBAFILE : original_options["tebafile"]
Expand All @@ -164,9 +184,7 @@ def options
original_options
end
end
end

no_commands do
def source
c_path = Pathname.new(__FILE__).realpath
@source ||= File.expand_path("../../..", c_path)
Expand All @@ -177,7 +195,10 @@ def validate_press_options

opts = ""
opts += " '--root'" if options["root"].nil?
opts += " '--entry-point'" if options["entry-point"].nil?
if options["entry-point"].nil?
opts += ", " unless opts.empty?
opts += " '--entry-point'"
end
raise Thor::Error, "No value provided for required options #{opts}" unless opts.empty?
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/tebako/cli_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ def do_press_runtime(options_manager, scenario_manager)
return unless %w[both runtime bundle].include?(options_manager.mode)

generate_files(options_manager, scenario_manager)
merged_env = ENV.to_h.merge(options_manager.b_env)
merged_env = ENV.to_h.merge(scenario_manager.b_env)
Tebako.packaging_error(103) unless system(merged_env, press_cfg_cmd(options_manager))
Tebako.packaging_error(104) unless system(merged_env, press_build_cmd(options_manager))
end

def do_setup(options_manager)
puts "Setting up tebako packaging environment"

merged_env = ENV.to_h.merge(options_manager.b_env)
merged_env = ENV.to_h.merge(Tebako::ScenarioManagerBase.new.b_env)
Tebako.packaging_error(101) unless system(merged_env, setup_cfg_cmd(options_manager))
Tebako.packaging_error(102) unless system(merged_env, setup_build_cmd(options_manager))
end
Expand Down
5 changes: 2 additions & 3 deletions lib/tebako/deploy_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ def initialize(fs_root, fs_entrance, target_dir, pre_dir)
@target_dir = target_dir
@pre_dir = pre_dir
@verbose = %w[yes true].include?(ENV.fetch("VERBOSE", nil))
@ncores = BuildHelpers.ncores
end

attr_reader :gem_home
Expand Down Expand Up @@ -162,7 +161,7 @@ def collect_and_deploy_gem_and_gemfile(gemspec)
Dir.chdir(@pre_dir) do
bundle_config
puts " *** It may take a long time for a big project. It takes REALLY long time on Windows ***"
BuildHelpers.run_with_capture_v([@bundler_command, bundler_reference, "install", "--jobs=#{@ncores}"])
BuildHelpers.run_with_capture_v([@bundler_command, bundler_reference, "install", "--jobs=#{ncores}"])
BuildHelpers.run_with_capture_v([@bundler_command, bundler_reference, "exec", @gem_command, "build", gemspec])
install_all_gems_or_fail
end
Expand Down Expand Up @@ -222,7 +221,7 @@ def deploy_gemfile
Dir.chdir(@tld) do
bundle_config
puts " *** It may take a long time for a big project. It takes REALLY long time on Windows ***"
BuildHelpers.run_with_capture_v([@bundler_command, bundler_reference, "install", "--jobs=#{@ncores}"])
BuildHelpers.run_with_capture_v([@bundler_command, bundler_reference, "install", "--jobs=#{ncores}"])
end

check_entry_point("local")
Expand Down
28 changes: 3 additions & 25 deletions lib/tebako/options_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,19 @@ def initialize(options)
@options = options
@rv = Tebako::RubyVersion.new(@options["Ruby"])
@ruby_ver, @ruby_hash = @rv.extend_ruby_version
@scmb = ScenarioManagerBase.new
end

attr_reader :ruby_ver, :rv

def b_env
u_flags = if RbConfig::CONFIG["host_os"] =~ /darwin/
"-DTARGET_OS_SIMULATOR=0 -DTARGET_OS_IPHONE=0 #{ENV.fetch("CXXFLAGS", nil)}"
else
ENV.fetch("CXXFLAGS", nil)
end
@b_env ||= { "CXXFLAGS" => u_flags }
end

def cfg_options
## {v_parts[3]} may be something like rc1 that won't work with CMake
v_parts = Tebako::VERSION.split(".")
# Cannot use 'xxx' as parameters because it does not work in Windows shells
# So we have to use \"xxx\"
@cfg_options ||=
"-DCMAKE_BUILD_TYPE=Release -DRUBY_VER:STRING=\"#{@ruby_ver}\" -DRUBY_HASH:STRING=\"#{@ruby_hash}\" " \
"-DDEPS:STRING=\"#{deps}\" -G \"#{m_files}\" -B \"#{output_folder}\" -S \"#{source}\" " \
"-DDEPS:STRING=\"#{deps}\" -G \"#{@scmb.m_files}\" -B \"#{output_folder}\" -S \"#{source}\" " \
"#{remove_glibc_private} -DTEBAKO_VERSION:STRING=\"#{v_parts[0]}.#{v_parts[1]}.#{v_parts[2]}\""
end

Expand Down Expand Up @@ -127,7 +119,7 @@ def deps_lib_dir

def fs_current
fs_current = Dir.pwd
if RUBY_PLATFORM =~ /msys|mingw|cygwin/
if @scmb.msys?
fs_current, cygpath_res = Open3.capture2e("cygpath", "-w", fs_current)
Tebako.packaging_error(101) unless cygpath_res.success?
fs_current.strip!
Expand Down Expand Up @@ -158,20 +150,6 @@ def mode
@mode ||= @options["mode"].nil? ? "bundle" : @options["mode"]
end

def m_files
# [TODO]
# Ninja generates incorrect script for tebako press target -- gets lost in a chain custom targets
# Using makefiles has negative performance impact so it needs to be fixed
@m_files ||= case RUBY_PLATFORM
when /linux/, /darwin/
"Unix Makefiles"
when /msys|mingw|cygwin/
"MinGW Makefiles"
else
raise Tebako::Error.new("#{RUBY_PLATFORM} is not supported.", 112)
end
end

def output_folder
@output_folder ||= File.join(prefix, "o")
end
Expand Down
30 changes: 16 additions & 14 deletions lib/tebako/packager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
require_relative "stripper"
require_relative "packager/pass1_patch"
require_relative "packager/pass1a_patch"
require_relative "packager/pass2"
require_relative "packager/pass2_patch"
require_relative "packager/patch_helpers"

# Tebako - an executable packager
Expand Down Expand Up @@ -93,15 +93,16 @@ def do_patch(patch_map, root)
patch_map.each { |fname, mapping| PatchHelpers.patch_file("#{root}/#{fname}", mapping) }
end

def finalize(os_type, src_dir, app_name, ruby_ver, patchelf)
def finalize(src_dir, app_name, ruby_ver, patchelf)
puts "-- Running finalize script"

RubyBuilder.new(ruby_ver, src_dir).target_build
exe_suffix = Packager::PatchHelpers.exe_suffix(os_type)
exe_suffix = ScenarioManagerBase.new.exe_suffix
src_name = File.join(src_dir, "ruby#{exe_suffix}")
patchelf(src_name, patchelf)
package_name = "#{app_name}#{exe_suffix}"
strip_or_copy(os_type, src_name, package_name)
# strip_or_copy(os_type, src_name, package_name)
Tebako::Stripper.strip_file(src_name, package_name)
puts "Created tebako package at \"#{package_name}\""
end

Expand Down Expand Up @@ -149,7 +150,8 @@ def pass1a(ruby_source_dir)
def pass2(ostype, ruby_source_dir, deps_lib_dir, ruby_ver)
puts "-- Running pass2 script"

do_patch(Pass2.get_patch_map(ostype, deps_lib_dir, ruby_ver), ruby_source_dir)
patch = Pass2Patch.new(ostype, deps_lib_dir, ruby_ver).patch_map
do_patch(patch, ruby_source_dir)
end

# Stash
Expand Down Expand Up @@ -194,15 +196,15 @@ def patchelf(src_name, patchelf)
BuildHelpers.run_with_capture(params)
end

def strip_or_copy(os_type, src_name, package_name)
# [TODO] On MSys strip sometimes creates a broken executable
# https://github.com/tamatebako/tebako/issues/172
if Packager::PatchHelpers.msys?(os_type)
FileUtils.cp(src_name, package_name)
else
Tebako::Stripper.strip_file(src_name, package_name)
end
end
# def strip_or_copy(_os_type, src_name, package_name)
# [TODO] On MSys strip sometimes creates a broken executable
# https://github.com/tamatebako/tebako/issues/172
# if Packager::PatchHelpers.msys?(os_type)
# FileUtils.cp(src_name, package_name)
# else
# Tebako::Stripper.strip_file(src_name, package_name)
# end
# end
end
end
end
12 changes: 5 additions & 7 deletions lib/tebako/packager/pass1_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,23 +202,21 @@ def patch_map
def gnumakefile_in_patch_p1 # rubocop:disable Metrics/MethodLength
objext = @ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
{
" DLLWRAP += -mno-cygwin" =>
"# tebako patched DLLWRAP += -mno-cygwin",
"$(Q) $(DLLWRAP) \\" => GNUMAKEFILE_IN_DLLTOOL_SUBST,

"$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
"$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext} $(WINMAINOBJ) # tebako patched",

"$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@" =>

"$(WINMAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@ # tebako patched",

"--output-exp=$(RUBY_EXP) \\" =>
"--output-exp=$(RUBY_EXP) --output-lib=$(LIBRUBY) --output-def=tebako.def \\",
"--output-exp=$(RUBY_EXP) \\" => "# tebako patched --output-exp=$(RUBY_EXP) \\",

"--export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)" =>
"--export-all $(LIBRUBY_A) $(LIBS) -o program-stub.exe # tebako patched",
"# tebako patched --export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)",

"@rm -f $(PROGRAM)" =>
"@rm -f program-stub.exe # tebako patched",
"@rm -f $(PROGRAM)" => "# tebako patched @rm -f $(PROGRAM)",

" $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)" =>
"# tebako patched $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)",
Expand Down
Loading