Skip to content
Open
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
21 changes: 11 additions & 10 deletions spec/compiler/loader/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
35 changes: 19 additions & 16 deletions spec/support/tempfile.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading