diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb29f398..7401d144 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,10 +39,10 @@ jobs: uses: actions/cache@v4 with: path: ports - key: cross-compiled-v8-${{ matrix.platform }}-${{ hashFiles('**/.ports_versions') }} + key: cross-compiled-v9-${{ matrix.platform }}-${{ hashFiles('**/.ports_versions') }} restore-keys: | - cross-compiled-v8-${{ matrix.platform }}-${{ hashFiles('**/.ports_versions') }} - cross-compiled-v8-${{ matrix.platform }}- + cross-compiled-v9-${{ matrix.platform }}-${{ hashFiles('**/.ports_versions') }} + cross-compiled-v9-${{ matrix.platform }}- - name: Build gem shell: bash @@ -94,6 +94,18 @@ jobs: ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path" exit $LASTEXITCODE + - name: Test if tsql wrapper works + shell: pwsh + run: | + tsql-ttds -C + exit $LASTEXITCODE + + - name: Test if defncopy wrapper works + shell: pwsh + run: | + defncopy-ttds -v + exit $LASTEXITCODE + test-windows-mingw: needs: - cross-compile @@ -207,6 +219,18 @@ jobs: ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path" exit $LASTEXITCODE + - name: Test if tsql wrapper works + shell: pwsh + run: | + tsql-ttds -C + exit $LASTEXITCODE + + - name: Test if defncopy wrapper works + shell: pwsh + run: | + defncopy-ttds -v + exit $LASTEXITCODE + test-windows-ucrt: needs: - cross-compile @@ -311,12 +335,30 @@ jobs: $gemVersion = (Get-Content VERSION).Trim() gem install "tiny_tds-$gemVersion.gem" + - name: Debug + shell: pwsh + run: | + Get-ChildItem "C:\\msys64\\mingw64\\bin" + Get-ChildItem "C:\\mingw64\\bin" + - name: Test if TinyTDS loads shell: pwsh run: | ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path" exit $LASTEXITCODE + - name: Test if tsql wrapper works + shell: pwsh + run: | + tsql-ttds -C + exit $LASTEXITCODE + + - name: Test if defncopy wrapper works + shell: pwsh + run: | + defncopy-ttds -v + exit $LASTEXITCODE + install-linux: needs: - cross-compile @@ -372,7 +414,9 @@ jobs: gem update --system 3.3.22 && ${{ matrix.bootstrap }} gem install --no-document ./gems/tiny_tds-$(cat VERSION)-${{ matrix.platform }}.gem && - ruby -e \"require 'tiny_tds'; puts TinyTds::Gem.root_path\" + ruby -e \"require 'tiny_tds'; puts TinyTds::Gem.root_path\" && + tsql-ttds -C && + defncopy-ttds -v " test-linux: diff --git a/CHANGELOG.md b/CHANGELOG.md index c79b64f8..ffe8e6b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Reduce number of files shipped with precompiled Windows gem * Provide precompiled gem for Linux (GNU + MUSL / 64-bit x86 + ARM) +* Fix wrappers for `tsql` and `defncopy` utility. ## 3.1.0 diff --git a/Rakefile b/Rakefile index e4bef2f7..ec6da503 100644 --- a/Rakefile +++ b/Rakefile @@ -40,9 +40,17 @@ Rake::ExtensionTask.new('tiny_tds', SPEC) do |ext| spec.metadata.delete('msys2_mingw_dependencies') if spec.platform.to_s =~ /mingw/ - spec.files << "ports/#{spec.platform.to_s}/bin/libsybdb-5.dll" + spec.files += [ + "ports/#{spec.platform.to_s}/bin/libsybdb-5.dll", + "ports/#{spec.platform.to_s}/bin/defncopy.exe", + "ports/#{spec.platform.to_s}/bin/tsql.exe" + ] elsif spec.platform.to_s =~ /linux/ - spec.files << "ports/#{spec.platform.to_s}/lib/libsybdb.so.5" + spec.files += [ + "ports/#{spec.platform.to_s}/lib/libsybdb.so.5", + "ports/#{spec.platform.to_s}/bin/defncopy", + "ports/#{spec.platform.to_s}/bin/tsql" + ] end end diff --git a/ext/tiny_tds/extconf.rb b/ext/tiny_tds/extconf.rb index 152ef052..47f6630c 100644 --- a/ext/tiny_tds/extconf.rb +++ b/ext/tiny_tds/extconf.rb @@ -105,8 +105,9 @@ def configure_defaults recipe.configure_options << "--enable-sspi" end - recipe.configure_options << "LDFLAGS=-L#{openssl_recipe.path}/lib" - recipe.configure_options << "LIBS=-liconv -lssl -lcrypto #{"-lwsock32 -lgdi32 -lws2_32 -lcrypt32" if MiniPortile.windows?} #{"-ldl -lpthread" if MiniPortile.linux?}" + # pass an additional runtime path to the linker so defncopy and tsql can find our shared sybdb + recipe.configure_options << "LDFLAGS=-L#{openssl_recipe.path}/lib #{"-Wl,-rpath='$$ORIGIN/../lib'" if MiniPortile.linux?}" + recipe.configure_options << "LIBS=-liconv -lssl -lcrypto #{"-lwsock32 -lgdi32 -lws2_32 -lcrypt32" if MiniPortile.windows?} #{"-ldl -lpthread" if MiniPortile.linux?}" recipe.configure_options << "CPPFLAGS=-I#{openssl_recipe.path}/include" recipe.configure_options << "OPENSSL_CFLAGS=-L#{openssl_recipe.path}/lib" diff --git a/lib/tiny_tds/bin.rb b/lib/tiny_tds/bin.rb index 832692a3..8bd5f3e9 100644 --- a/lib/tiny_tds/bin.rb +++ b/lib/tiny_tds/bin.rb @@ -19,12 +19,16 @@ def initialize(name) @root = Gem.root_path @exts = (ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']) | ['.exe'] + puts @exts.inspect + @name = name @binstub = find_bin @exefile = find_exe end def run(*args) + puts which.inspect + with_ports_paths do return nil unless path Kernel.system Shellwords.join(args.unshift(path)) @@ -43,6 +47,8 @@ def info private def search_paths + puts ENV['PATH'].inspect + ENV['PATH'].split File::PATH_SEPARATOR end @@ -77,8 +83,12 @@ def find_exe def which search_paths.each do |path| + puts "currently looking in #{path}" + @exts.each do |ext| exe = File.expand_path File.join(path, "#{name}#{ext}"), @root + puts "I put together #{exe}?" + next if exe == @binstub next unless File.executable?(exe) next unless binary?(exe) diff --git a/lib/tiny_tds/gem.rb b/lib/tiny_tds/gem.rb index a52f047d..55be78b4 100644 --- a/lib/tiny_tds/gem.rb +++ b/lib/tiny_tds/gem.rb @@ -12,15 +12,11 @@ def ports_root_path end def ports_bin_paths - Dir.glob(File.join(ports_root_path,ports_host,'**','bin')) + Dir.glob(File.join(ports_root_path, '**', 'bin')) end def ports_lib_paths - Dir.glob(File.join(ports_root_path,ports_host,'**','lib')) - end - - def ports_host - RbConfig::CONFIG["arch"] + Dir.glob(File.join(ports_root_path, '**', 'lib')) end end end diff --git a/test/gem_test.rb b/test/gem_test.rb index 0412a88a..eea45623 100644 --- a/test/gem_test.rb +++ b/test/gem_test.rb @@ -98,79 +98,6 @@ class GemTest < Minitest::Spec end end end - - describe '#ports_lib_paths' do - let(:ports_lib_paths) { TinyTds::Gem.ports_lib_paths } - - describe 'when the ports directories exist' do - let(:fake_lib_paths) do - ports_host_root = File.join(gem_root, 'ports', 'fake-host-with-dirs') - [ - File.join('a','lib'), - File.join('a','inner','lib'), - File.join('b','lib') - ].map do |p| - File.join(ports_host_root, p) - end - end - - before do - RbConfig::CONFIG['arch'] = 'fake-host-with-dirs' - fake_lib_paths.each do |path| - FileUtils.mkdir_p(path) - end - end - - after do - FileUtils.remove_entry_secure( - File.join(gem_root, 'ports', 'fake-host-with-dirs'), true - ) - end - - it 'should return all the lib directories' do - _(ports_lib_paths.sort).must_equal fake_lib_paths.sort - end - - it 'should return all the lib directories regardless of cwd' do - Dir.chdir '/' - _(ports_lib_paths.sort).must_equal fake_lib_paths.sort - end - end - - describe 'when the ports directories are missing' do - before do - RbConfig::CONFIG['arch'] = 'fake-host-without-dirs' - end - - - it 'should return no directories' do - _(ports_lib_paths).must_be_empty - end - - it 'should return no directories regardless of cwd' do - Dir.chdir '/' - _(ports_lib_paths).must_be_empty - end - end - end - - describe '#ports_host' do - { - 'x64-mingw-ucrt' => 'x64-mingw-ucrt', - 'x64-mingw32' => 'x64-mingw32', - 'x86_64-linux' => 'x86_64-linux', - }.each do |host,expected| - describe "on a #{host} architecture" do - before do - RbConfig::CONFIG['arch'] = host - end - - it "should return a #{expected} ports host" do - _(TinyTds::Gem.ports_host).must_equal expected - end - end - end - end end end