diff --git a/spec/compiler/loader/spec_helper.cr b/spec/compiler/loader/spec_helper.cr index 5b2a6454bfa1..c1b235eb207e 100644 --- a/spec/compiler/loader/spec_helper.cr +++ b/spec/compiler/loader/spec_helper.cr @@ -5,15 +5,16 @@ SPEC_CRYSTAL_LOADER_LIB_PATH = File.join(SPEC_TEMPFILE_PATH, "loader") def build_c_dynlib(c_filename, *, lib_name = nil, target_dir = SPEC_CRYSTAL_LOADER_LIB_PATH) o_filename = File.join(target_dir, Crystal::Loader.library_filename(lib_name || File.basename(c_filename, ".c"))) - {% if flag?(:msvc) %} - o_basename = o_filename.rchop(".lib") - `#{ENV["CC"]? || "cl.exe"} /nologo /LD #{Process.quote(c_filename)} #{Process.quote("/Fo#{o_basename}")} #{Process.quote("/Fe#{o_basename}")}` - {% elsif flag?(:win32) && flag?(:gnu) %} - o_basename = o_filename.rchop(".a") - `#{ENV["CC"]? || "cc"} -shared -fvisibility=hidden #{Process.quote(c_filename)} -o #{Process.quote(o_basename + ".dll")} #{Process.quote("-Wl,--out-implib,#{o_basename}.a")}` - {% else %} - `#{ENV["CC"]? || "cc"} -shared -fvisibility=hidden #{Process.quote(c_filename)} -o #{Process.quote(o_filename)}` - {% end %} + status = + {% if flag?(:msvc) %} + o_basename = o_filename.rchop(".lib") + Process.run [ENV.fetch("CC", "cl.exe"), "/nologo", "/LD", c_filename, "/Fo#{o_basename}", "/Fe#{o_basename}"] + {% elsif flag?(:win32) && flag?(:gnu) %} + o_basename = o_filename.rchop(".a") + Process.run [ENV.fetch("CC", "cc"), "-shared", "-fvisibility=hidden", c_filename, "-o", "#{o_basename}.dll", "-Wl,--out-implib,#{o_basename}.a"] + {% else %} + Process.run [ENV.fetch("CC", "cc"), "-shared", "-fvisibility=hidden", c_filename, "-o", o_filename] + {% end %} - raise "BUG: failed to compile dynamic library" unless $?.success? + raise "BUG: failed to compile dynamic library" unless status.success? end diff --git a/spec/support/tempfile.cr b/spec/support/tempfile.cr index 61086a30494c..27acb5cdde59 100644 --- a/spec/support/tempfile.cr +++ b/spec/support/tempfile.cr @@ -66,29 +66,32 @@ def with_temp_executable(name, file = __FILE__, &) end def with_temp_c_object_file(c_code, *, filename = "temp_c", file = __FILE__, &) - # can't use backtick in interpreted code (#12241) + # can't spawn processes in interpreted code (#12241) pending_interpreted! "Unable to compile C code in interpreted code" obj_ext = {{ flag?(:msvc) ? ".obj" : ".o" }} with_tempfile("#{filename}.c", "#{filename}#{obj_ext}", file: file) do |c_filename, o_filename| File.write(c_filename, c_code) - {% if flag?(:msvc) %} - # following is based on `Crystal::Compiler#linker_command` - unless cl = ENV["CC"]? - cl = "cl.exe" - if msvc_path = Crystal::System::VisualStudio.find_latest_msvc_path - # we won't be cross-compiling the specs binaries, so host and target - # bits are identical - bits = {{ flag?(:bits64) ? "x64" : "x86" }} - cl = Process.quote(msvc_path.join("bin", "Host#{bits}", bits, cl).to_s) + status = + {% if flag?(:msvc) %} + # following is based on `Crystal::Compiler#linker_command` + cl = ENV.fetch("CC") do + if msvc_path = Crystal::System::VisualStudio.find_latest_msvc_path + # we won't be cross-compiling the specs binaries, so host and target + # bits are identical + bits = {{ flag?(:bits64) ? "x64" : "x86" }} + msvc_path.join("bin", "Host#{bits}", bits, "cl.exe").to_s + else + "cl.exe" + end end - end - - `#{cl} /nologo /c /MD #{Process.quote(c_filename)} #{Process.quote("/Fo#{o_filename}")}`.should be_truthy - {% else %} - `#{ENV["CC"]? || "cc"} #{Process.quote(c_filename)} -c -o #{Process.quote(o_filename)}`.should be_truthy - {% end %} + Process.run [cl, "/nologo", "/c", "/MD", c_filename, "/Fo#{o_filename}"] + {% else %} + cc = ENV.fetch("CC", "cc") + Process.run [cc, c_filename, "-c", "-o", o_filename] + {% end %} + status.success?.should be_true yield o_filename end