Skip to content

Commit

Permalink
Fix windows support for build_executable.jl. fix JuliaLang#9973
Browse files Browse the repository at this point in the history
  • Loading branch information
dhoegh committed Feb 1, 2015
1 parent e41a507 commit 65ad20b
Showing 1 changed file with 70 additions and 33 deletions.
103 changes: 70 additions & 33 deletions contrib/build_executable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function build_executable(exename, script_file, targetdir=nothing; force=false)
patchelf = nothing
if targetdir != nothing
patchelf = find_patchelf()
if patchelf == nothing
if patchelf == nothing && !(OS_NAME == :Windows)
println("ERROR: Using the 'targetdir' option requires the 'patchelf' utility. Please install it.")
return 1
end
Expand Down Expand Up @@ -109,37 +109,62 @@ function build_executable(exename, script_file, targetdir=nothing; force=false)
run(`$(julia) $(build_sysimg) $(sys.buildfile) native $(userimgjl) --force`)
println()

gcc = find_system_gcc()
# This argument is needed for the gcc, see issue #9973
win_arg = @windows ? "-D_WIN32_WINNT=0x0600" : ""
@windowsxp_only win_arg = "-D_WINVER=0x0502"

for exe in [exe_release, exe_debug]
incs = join(get_includes(), " ")
println("running: gcc -g -Wl,--no-as-needed $(incs) $(cfile) -o $(exe.buildfile) -Wl,-rpath,$(sys.buildpath) -L$(sys.buildpath) $(exe.libjulia) -l$(exename)")
run(`gcc -g -Wl,--no-as-needed $(get_includes()) $(cfile) -o $(exe.buildfile) -Wl,-rpath,$(sys.buildpath) -L$(sys.buildpath) $(exe.libjulia) -l$(exename)`)
incs = get_includes()
@windows_only begin
if contains(gcc, "WinRPM")
# This should not bee necessary, it is done due to WinRPM's gcc's
# include paths is not correct see WinRPM.jl issue #38
old_path = ENV["path"]
ENV["path"] = old_path*";"*dirname(gcc)
push!(incs, "-I"*abspath(joinpath(dirname(gcc),"..","include")))
else
gcc = Base.shell_split(gcc)
end
end
println("running: $gcc -g -Wl,--no-as-needed $win_arg $(join(incs, " ")) $(cfile) -o $(exe.buildfile) -Wl,-rpath,$(sys.buildpath) -L$(sys.buildpath) $(exe.libjulia) -l$(exename)")
run(`$gcc -g -Wl,--no-as-needed $win_arg $(incs) $(cfile) -o $(exe.buildfile) -Wl,-rpath,$(sys.buildpath) -L$(sys.buildpath) $(exe.libjulia) -l$(exename)`)
@windows_only begin
if contains(gcc, "WinRPM")
ENV["path"] = old_path
end
end
println()
end

println("running: rm -rf $(tmpdir) $(sys.buildfile).o $(sys.buildfile0).o $(sys.buildfile0).ji")
run(`rm -rf $(tmpdir) $(sys.buildfile).o $(sys.buildfile0).o $(sys.buildfile0).ji`)
map(f-> rm(f, recursive=true), [tmpdir, sys.buildfile*".o", sys.buildfile0*".o", sys.buildfile0*".ji"])
println()

if targetdir != nothing
# Move created files to target directory
run(`mv $(exe_release.buildfile) $(exe_debug.buildfile) $(sys.buildfile).$(Sys.dlext) $(sys.buildfile).ji $(targetdir)`)
for file in [exe_release.buildfile, exe_debug.buildfile, sys.buildfile*".$(Sys.dlext)", sys.buildfile*".ji"]
mv(file,joinpath(targetdir, basename(file)))
end

# Copy needed shared libraries to the target directory
tmp = ".*\.$(Sys.dlext).*"
shlibs = filter(Regex(tmp),readdir(sys.buildpath))
for shlib in shlibs
run(`cp $(joinpath(sys.buildpath, shlib)) $(targetdir)`)
cp(joinpath(sys.buildpath, shlib), joinpath(targetdir, shlib))
end

# Fix rpath in executable and shared libraries
shlibs = filter(Regex(tmp),readdir(targetdir))
push!(shlibs, exe_release.filename)
push!(shlibs, exe_debug.filename)

for shlib in shlibs
rpath = readall(`$(patchelf) --print-rpath $(joinpath(targetdir, shlib))`)[1:end-1]
if Base.samefile(rpath, sys.buildpath)
run(`$(patchelf) --set-rpath $(targetdir) $(joinpath(targetdir, shlib))`)
@unix_only begin
# Fix rpath in executable and shared libraries
shlibs = filter(Regex(tmp),readdir(targetdir))
push!(shlibs, exe_release.filename)
push!(shlibs, exe_debug.filename)
println(shlibs)
for shlib in shlibs
rpath = readall(`$(patchelf) --print-rpath $(joinpath(targetdir, shlib))`)[1:end-1]
if Base.samefile(rpath, sys.buildpath)
run(`$(patchelf) --set-rpath $(targetdir) $(joinpath(targetdir, shlib))`)
end
end
end
end
Expand All @@ -151,20 +176,13 @@ function build_executable(exename, script_file, targetdir=nothing; force=false)
end

function find_patchelf()
patchelf = nothing

for x in [joinpath(JULIA_HOME, "patchelf"), "patchelf"]
patchelf = x
works = true
for patchelf in [joinpath(JULIA_HOME, "patchelf"), "patchelf"]
try
x=readall(`$(patchelf) --version`)
catch
works = false
if success(`$(patchelf) --version`)
return patchelf
end
end
works && break
end

patchelf
end

function get_includes()
Expand Down Expand Up @@ -219,12 +237,31 @@ function emit_cmain(cfile, exename, relocation)
end

function emit_userimgjl(userimgjl, script_file)
f = open(userimgjl, "w")
write( f, """
include(\"$(script_file)\")
"""
)
close(f)
open(userimgjl, "w") do f
write( f, "include(\"$(escape_string(script_file))\")")
end
end

# Search for a linker to link sys.o into sys.dl_ext. Honor LD environment variable.
function find_system_gcc()
# On Windows, check to see if WinRPM is installed, and if so, see if gcc is installed
@windows_only try
require("WinRPM")
winrpmgcc = joinpath(WinRPM.installdir,"usr","$(Sys.ARCH)-w64-mingw32",
"sys-root","mingw","bin","gcc.exe")
if success(`$winrpmgcc --version`)
return winrpmgcc
end
end

# See if `gcc` exists
try
if success(@windows ? `cmd /c gcc -v` : `gcc -v`)
return @windows ? "cmd /c gcc" : "gcc"
end
end

error( "GCC not found on system: " * @windows? "GCC can be installed via `Pkg.add(\"WinRPM\"); WinRPM.install(\"gcc\")`" : "" )
end

if !isinteractive()
Expand Down

0 comments on commit 65ad20b

Please sign in to comment.