From 357efef78d31f7539fb0ec4cea214680b1d48b8e Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Wed, 1 May 2019 12:44:35 +0100 Subject: [PATCH 01/14] Fix absolute PATH building method for Windows Installer and Tests | include win_installer into ApplicationBuilder.jl and set cpu_target default to nothing --- Manifest.toml | 10 ++++------ src/ApplicationBuilder.jl | 6 +++++- src/win-installer.jl | 7 +++++-- test/build_examples/blink.jl | 2 +- test/build_examples/commandline_hello.jl | 2 +- test/build_examples/hello.jl | 2 +- test/build_examples/libui.jl | 2 +- test/build_examples/sdl.jl | 2 +- test/bundle.jl | 3 ++- 9 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 0423754..b9e81ec 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,9 +1,7 @@ # This file is machine-generated - editing it directly is not advised [[ApplicationBuilderAppUtils]] -git-tree-sha1 = "655b936802c498ddaee84c0824610250433f4ace" -repo-rev = "master" -repo-url = "https://github.com/NHDaly/ApplicationBuilderAppUtils.jl" +path = "C:\\Users\\gabriel.freire\\.julia\\dev\\ApplicationBuilderAppUtils" uuid = "96374992-6a10-11e9-2fa0-73472aac04df" version = "0.1.0" @@ -23,10 +21,10 @@ uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" version = "0.8.10" [[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +deps = ["Libdl", "SHA"] +git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648" uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" +version = "0.5.4" [[BufferedStreams]] deps = ["Compat", "Test"] diff --git a/src/ApplicationBuilder.jl b/src/ApplicationBuilder.jl index 73c3296..7a8f953 100644 --- a/src/ApplicationBuilder.jl +++ b/src/ApplicationBuilder.jl @@ -9,6 +9,10 @@ export build_app_bundle include("mac_commandline_app.jl") end +@static if Sys.iswindows() + include("win-installer.jl") +end + """ build_app_bundle(juliaprog_main; appname, builddir, binary_name, resources, libraries, verbose, bundle_identifier, @@ -32,7 +36,7 @@ function build_app_bundle(juliaprog_main; resources = String[], libraries = String[], verbose = false, bundle_identifier = nothing, app_version = "0.1", icns_file = nothing, certificate = nothing, entitlements_file = nothing, - snoopfile = nothing, autosnoop = false, cpu_target="x86-64", + snoopfile = nothing, autosnoop = false, cpu_target=nothing, create_installer = false, commandline_app = false, ) diff --git a/src/win-installer.jl b/src/win-installer.jl index 1cbe11d..e53b62b 100644 --- a/src/win-installer.jl +++ b/src/win-installer.jl @@ -1,5 +1,8 @@ +JULIA_HOME = ENV["JULIA_HOME"] +LICENSE_PATH = joinpath(abspath(JULIA_HOME, ".."), "License.md") + function win_installer(builddir; name = "nothing", - license = "$JULIA_HOME/../License.md") + license = LICENSE_PATH) # check = success(`makensis`) # !check && throw(ErrorException("NSIS not found in path. Exiting.")) @@ -29,7 +32,7 @@ function win_installer(builddir; name = "nothing", """ @info "Creating installer at $builddir" - nsis_file = joinpath(builddir, "..", "$name.nsi") + nsis_file = joinpath(abspath(builddir, ".."), "$name.nsi") open(nsis_file, "w") do f write(f, nsis_commands) end diff --git a/test/build_examples/blink.jl b/test/build_examples/blink.jl index c81f1a6..15f0a37 100644 --- a/test/build_examples/blink.jl +++ b/test/build_examples/blink.jl @@ -2,7 +2,7 @@ using ApplicationBuilder using Pkg -examples_blink = joinpath(@__DIR__, "..", "..", "examples", "blink.jl") +examples_blink = joinpath(abspath(@__DIR__, "..", ".."), "examples", "blink.jl") # Allow this file to be called either as a standalone file to build the above # example, or from runtests.jl using a provided builddir. diff --git a/test/build_examples/commandline_hello.jl b/test/build_examples/commandline_hello.jl index 1150a8c..62b5fbd 100644 --- a/test/build_examples/commandline_hello.jl +++ b/test/build_examples/commandline_hello.jl @@ -4,6 +4,6 @@ using ApplicationBuilder # example, or from runtests.jl using a provided builddir. @isdefined(builddir) || (builddir="builddir") -build_app_bundle(joinpath(@__DIR__,"..","..","examples","commandline_hello.jl"), +build_app_bundle(joinpath(abspath(@__DIR__,"..",".."),"examples","commandline_hello.jl"), appname="hello", binary_name="hello", commandline_app=true, builddir=builddir) diff --git a/test/build_examples/hello.jl b/test/build_examples/hello.jl index d104640..3eae4c1 100644 --- a/test/build_examples/hello.jl +++ b/test/build_examples/hello.jl @@ -1,6 +1,6 @@ using ApplicationBuilder -examples_hello = joinpath(@__DIR__, "..", "..", "examples", "hello.jl") +examples_hello = joinpath(abspath(@__DIR__, "..", ".."), "examples", "hello.jl") # Allow this file to be called either as a standalone file to build the above # example, or from runtests.jl using a provided builddir. diff --git a/test/build_examples/libui.jl b/test/build_examples/libui.jl index 1e1f165..7398fc3 100644 --- a/test/build_examples/libui.jl +++ b/test/build_examples/libui.jl @@ -12,7 +12,7 @@ libUIPkg = Pkg.dir("Libui") using Libui -ApplicationBuilder.build_app_bundle(joinpath(@__DIR__, "..", "..", "examples", "libui.jl"); +ApplicationBuilder.build_app_bundle(joinpath(abspath(@__DIR__, "..", ".."), "examples", "libui.jl"); verbose = true, resources = [], libraries = [ Libui.libui ], diff --git a/test/build_examples/sdl.jl b/test/build_examples/sdl.jl index 5cd12a4..d110cea 100644 --- a/test/build_examples/sdl.jl +++ b/test/build_examples/sdl.jl @@ -1,7 +1,7 @@ using ApplicationBuilder using Pkg -examples_blink = joinpath(@__DIR__, "..", "..", "examples", "sdl.jl") +examples_blink = joinpath(abspath(@__DIR__, "..", ".."), "examples", "sdl.jl") # Allow this file to be called either as a standalone file to build the above # example, or from runtests.jl using a globally-defined builddir. diff --git a/test/bundle.jl b/test/bundle.jl index 46c63f4..480f23d 100644 --- a/test/bundle.jl +++ b/test/bundle.jl @@ -10,6 +10,7 @@ builddir = mktempdir() @testset "HelloWorld.app" begin @test 0 == include("build_examples/commandline_hello.jl") @test isdir(joinpath(builddir, "hello")) - @test success(`$builddir/hello/bin/hello`) + p = joinpath(builddir,"hello", "bin", "hello") + @test success(`$p`) #@test success(`open $builddir/hello.app`) end From e373d8b07d83a5563a43b05fd0677ee0821dbafe Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Wed, 1 May 2019 12:48:45 +0100 Subject: [PATCH 02/14] Keep original Manifest.toml --- Manifest.toml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index b9e81ec..bf0f170 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,7 +1,9 @@ # This file is machine-generated - editing it directly is not advised [[ApplicationBuilderAppUtils]] -path = "C:\\Users\\gabriel.freire\\.julia\\dev\\ApplicationBuilderAppUtils" +git-tree-sha1 = "655b936802c498ddaee84c0824610250433f4ace" +repo-rev = "master" +repo-url = "https://github.com/NHDaly/ApplicationBuilderAppUtils.jl" uuid = "96374992-6a10-11e9-2fa0-73472aac04df" version = "0.1.0" @@ -21,10 +23,10 @@ uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" version = "0.8.10" [[BinaryProvider]] -deps = ["Libdl", "SHA"] -git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648" +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.4" +version = "0.5.3" [[BufferedStreams]] deps = ["Compat", "Test"] @@ -174,4 +176,4 @@ uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" -version = "0.4.2" +version = "0.4.2" \ No newline at end of file From 59f18edf8697f4844791a90b804ea6f6cb419e49 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Wed, 1 May 2019 14:41:38 +0100 Subject: [PATCH 03/14] Fix JULIA_HOME key issue --- src/win-installer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win-installer.jl b/src/win-installer.jl index e53b62b..7bf3fdb 100644 --- a/src/win-installer.jl +++ b/src/win-installer.jl @@ -1,4 +1,4 @@ -JULIA_HOME = ENV["JULIA_HOME"] +JULIA_HOME = get(ENV, "JULIA_HOME", "") LICENSE_PATH = joinpath(abspath(JULIA_HOME, ".."), "License.md") function win_installer(builddir; name = "nothing", From d796a54237f273c3e0942da8b1d418c8dd664d89 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Thu, 2 May 2019 17:25:34 +0100 Subject: [PATCH 04/14] Add name to windows installer | Add support for Windows command line apps --- src/ApplicationBuilder.jl | 7 ++++++- src/win-installer.jl | 3 ++- src/win_commandline_app.jl | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/win_commandline_app.jl diff --git a/src/ApplicationBuilder.jl b/src/ApplicationBuilder.jl index 7a8f953..031bbe6 100644 --- a/src/ApplicationBuilder.jl +++ b/src/ApplicationBuilder.jl @@ -10,6 +10,7 @@ export build_app_bundle end @static if Sys.iswindows() + include("win_commandline_app.jl") include("win-installer.jl") end @@ -52,6 +53,10 @@ function build_app_bundle(juliaprog_main; if occursin(r"\s", bundle_identifier) throw(ArgumentError("Bundle identifier must not contain whitespace.")) end if occursin(r"[^A-Za-z0-9-.]", bundle_identifier) throw(ArgumentError("Bundle identifier must contain only alphanumeric characters (A-Z,a-z,0-9), hyphen (-), and period (.).")) end + elseif Sys.iswindows() + if commandline_app + @warn "Will create windows script" + end else if commandline_app @warn "Ignore `commandline_app=true` on non-macOS system." @@ -87,7 +92,7 @@ function build_app_bundle(juliaprog_main; end applet_name = nothing - if commandline_app # MacOS only + if commandline_app # MacOS and Windows only # TODO: What if the user specifies Resources that could overwrite # applet resources? (ie Scripts/ or applet.rsrc) applet_name = build_commandline_app_bundle(builddir, binary_name, appname, verbose) diff --git a/src/win-installer.jl b/src/win-installer.jl index e53b62b..18946ff 100644 --- a/src/win-installer.jl +++ b/src/win-installer.jl @@ -1,4 +1,4 @@ -JULIA_HOME = ENV["JULIA_HOME"] +JULIA_HOME = get(ENV, "JULIA_HOME", "") LICENSE_PATH = joinpath(abspath(JULIA_HOME, ".."), "License.md") function win_installer(builddir; name = "nothing", @@ -9,6 +9,7 @@ function win_installer(builddir; name = "nothing", nsis_commands = """ # set the name of the installer + Name "$(name)" Outfile "$(name)_Installer.exe" # Default install directory diff --git a/src/win_commandline_app.jl b/src/win_commandline_app.jl new file mode 100644 index 0000000..63e9778 --- /dev/null +++ b/src/win_commandline_app.jl @@ -0,0 +1,32 @@ +function get_commandline_sh_script(appname) + """ + #!/bin/bash + PROGRAM_NAME="$(appname)" + DIR=\${BASH_SOURCE[0]} + \$(dirname \$DIR)/\$PROGRAM_NAME.exe \$@ + """ +end + +# Build a wrapper app that opens a terminal and runs the provided binary. +# Returns a new script name only if binary_name is already "appname" (to prevent collision). +function build_commandline_app_bundle(builddir, binary_name, appname, verbose) + println("~~~~~~ Creating commandline-app wrapper script. ~~~~~~~") + + mkpath(builddir) # Create builddir if it doesn't already exist. + + app_path = joinpath(builddir, appname) + exe_dir = "bin" # Put the binaries next to the applet in MacOS. + script_name = "$(binary_name).sh" + if binary_name == appname # Prevent collisions. + script_name = "$(binary_name)_wrapper.sh" + end + script_path = joinpath(app_path, exe_dir, script_name) + mkpath(dirname(script_path)) + + verbose && println(" Creating wrapper script: $script_path") + write(script_path, get_commandline_sh_script(appname)) + run(`chmod +x $script_path`) + + return script_name +end + \ No newline at end of file From 9c44b6352abdc08d7ca5197a8cc0135e335f8ab1 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Thu, 2 May 2019 17:37:48 +0100 Subject: [PATCH 05/14] Prevent executable appname being replaced by binary_name used on commandline_app script --- src/ApplicationBuilder.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ApplicationBuilder.jl b/src/ApplicationBuilder.jl index 031bbe6..d63de3c 100644 --- a/src/ApplicationBuilder.jl +++ b/src/ApplicationBuilder.jl @@ -152,7 +152,7 @@ function build_app_bundle(juliaprog_main; "COMPILING_APPLE_BUNDLE"=>"true") do verbose && println(" PackageCompiler.static_julia(...)") # Compile executable and copy julia libs to $launcher_dir. - PackageCompiler.build_executable(juliaprog_main, binary_name, custom_program_c; + PackageCompiler.build_executable(juliaprog_main, appname, custom_program_c; builddir=launcher_dir, verbose=verbose, optimize="3", snoopfile=snoopfile, debug="0", cpu_target=cpu_target, compiled_modules="yes", From 39e192b6da55709f81de3b7e9723936ba1b2b91d Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Thu, 2 May 2019 18:35:43 +0100 Subject: [PATCH 06/14] Fix tests --- Manifest.toml | 12 +++++------- test/ApplicationBuilder.jl | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index bf0f170..b9e81ec 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,9 +1,7 @@ # This file is machine-generated - editing it directly is not advised [[ApplicationBuilderAppUtils]] -git-tree-sha1 = "655b936802c498ddaee84c0824610250433f4ace" -repo-rev = "master" -repo-url = "https://github.com/NHDaly/ApplicationBuilderAppUtils.jl" +path = "C:\\Users\\gabriel.freire\\.julia\\dev\\ApplicationBuilderAppUtils" uuid = "96374992-6a10-11e9-2fa0-73472aac04df" version = "0.1.0" @@ -23,10 +21,10 @@ uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" version = "0.8.10" [[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +deps = ["Libdl", "SHA"] +git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648" uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" +version = "0.5.4" [[BufferedStreams]] deps = ["Compat", "Test"] @@ -176,4 +174,4 @@ uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" -version = "0.4.2" \ No newline at end of file +version = "0.4.2" diff --git a/test/ApplicationBuilder.jl b/test/ApplicationBuilder.jl index 09c4b75..de6eaac 100644 --- a/test/ApplicationBuilder.jl +++ b/test/ApplicationBuilder.jl @@ -50,7 +50,7 @@ end @testset "HelloWorld.app" begin @test 0 == include("build_examples/hello.jl") @test isdir("$builddir/HelloWorld.app") - @test success(`$builddir/HelloWorld.app/Contents/MacOS/hello`) + @test success(`$builddir/HelloWorld.app/Contents/MacOS/HelloWorld`) # There shouldn't be a Libraries dir since none specified. @test !isdir("$builddir/HelloWorld.app/Contents/Libraries") @@ -58,7 +58,7 @@ end # Ensure all dependencies on Julia libs are internal, so the app is portable. @testset "No external Dependencies" begin @test !success(pipeline( - `otool -l "$builddir/HelloWorld.app/Contents/MacOS/hello"`, + `otool -l "$builddir/HelloWorld.app/Contents/MacOS/HelloWorld"`, `grep 'julia'`, # Get all julia deps `grep -v '@rpath'`)) # make sure all are relative. end From 52f0f6b2679dab23827a04a33ab4db0b2303dc90 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Thu, 2 May 2019 18:45:07 +0100 Subject: [PATCH 07/14] fix manifest --- Manifest.toml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index b9e81ec..bf0f170 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,7 +1,9 @@ # This file is machine-generated - editing it directly is not advised [[ApplicationBuilderAppUtils]] -path = "C:\\Users\\gabriel.freire\\.julia\\dev\\ApplicationBuilderAppUtils" +git-tree-sha1 = "655b936802c498ddaee84c0824610250433f4ace" +repo-rev = "master" +repo-url = "https://github.com/NHDaly/ApplicationBuilderAppUtils.jl" uuid = "96374992-6a10-11e9-2fa0-73472aac04df" version = "0.1.0" @@ -21,10 +23,10 @@ uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" version = "0.8.10" [[BinaryProvider]] -deps = ["Libdl", "SHA"] -git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648" +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.4" +version = "0.5.3" [[BufferedStreams]] deps = ["Compat", "Test"] @@ -174,4 +176,4 @@ uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" -version = "0.4.2" +version = "0.4.2" \ No newline at end of file From aec3253fde889ca17c40e74830f2c03ce2a3e114 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Thu, 2 May 2019 18:58:24 +0100 Subject: [PATCH 08/14] rollback appname --- src/ApplicationBuilder.jl | 2 +- test/ApplicationBuilder.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ApplicationBuilder.jl b/src/ApplicationBuilder.jl index d63de3c..031bbe6 100644 --- a/src/ApplicationBuilder.jl +++ b/src/ApplicationBuilder.jl @@ -152,7 +152,7 @@ function build_app_bundle(juliaprog_main; "COMPILING_APPLE_BUNDLE"=>"true") do verbose && println(" PackageCompiler.static_julia(...)") # Compile executable and copy julia libs to $launcher_dir. - PackageCompiler.build_executable(juliaprog_main, appname, custom_program_c; + PackageCompiler.build_executable(juliaprog_main, binary_name, custom_program_c; builddir=launcher_dir, verbose=verbose, optimize="3", snoopfile=snoopfile, debug="0", cpu_target=cpu_target, compiled_modules="yes", diff --git a/test/ApplicationBuilder.jl b/test/ApplicationBuilder.jl index de6eaac..09c4b75 100644 --- a/test/ApplicationBuilder.jl +++ b/test/ApplicationBuilder.jl @@ -50,7 +50,7 @@ end @testset "HelloWorld.app" begin @test 0 == include("build_examples/hello.jl") @test isdir("$builddir/HelloWorld.app") - @test success(`$builddir/HelloWorld.app/Contents/MacOS/HelloWorld`) + @test success(`$builddir/HelloWorld.app/Contents/MacOS/hello`) # There shouldn't be a Libraries dir since none specified. @test !isdir("$builddir/HelloWorld.app/Contents/Libraries") @@ -58,7 +58,7 @@ end # Ensure all dependencies on Julia libs are internal, so the app is portable. @testset "No external Dependencies" begin @test !success(pipeline( - `otool -l "$builddir/HelloWorld.app/Contents/MacOS/HelloWorld"`, + `otool -l "$builddir/HelloWorld.app/Contents/MacOS/hello"`, `grep 'julia'`, # Get all julia deps `grep -v '@rpath'`)) # make sure all are relative. end From 0fb751142b88c65450bec8729da72364f56052ca Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Thu, 9 May 2019 17:01:54 +0100 Subject: [PATCH 09/14] Repalce .sh for .bat to enable for direct execution using environment variables for command line tool --- src/win_commandline_app.jl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/win_commandline_app.jl b/src/win_commandline_app.jl index 63e9778..4bbfeea 100644 --- a/src/win_commandline_app.jl +++ b/src/win_commandline_app.jl @@ -1,9 +1,8 @@ function get_commandline_sh_script(appname) """ - #!/bin/bash - PROGRAM_NAME="$(appname)" - DIR=\${BASH_SOURCE[0]} - \$(dirname \$DIR)/\$PROGRAM_NAME.exe \$@ + @echo off + set dir=%~dp0 + call %dir%$(appname).exe %* """ end @@ -16,17 +15,16 @@ function build_commandline_app_bundle(builddir, binary_name, appname, verbose) app_path = joinpath(builddir, appname) exe_dir = "bin" # Put the binaries next to the applet in MacOS. - script_name = "$(binary_name).sh" + script_name = "$(binary_name).bat" if binary_name == appname # Prevent collisions. - script_name = "$(binary_name)_wrapper.sh" + script_name = "$(binary_name)_exec.bat" end script_path = joinpath(app_path, exe_dir, script_name) mkpath(dirname(script_path)) verbose && println(" Creating wrapper script: $script_path") write(script_path, get_commandline_sh_script(appname)) - run(`chmod +x $script_path`) + run(`chmod u+x $script_path`) return script_name end - \ No newline at end of file From ecb24a469d1b8d4b518d9b934cb5aa68a1dae339 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Fri, 7 Jun 2019 16:52:45 +0100 Subject: [PATCH 10/14] Implementation of Inno setup compiler script, made CLI tests work on Windows, added extra option to choose installer compiler for Windows ISS/NSIS --- src/ApplicationBuilder.jl | 3 +- src/win-installer.jl | 130 ++++++++++++++++++++++++++++++------- test/ApplicationBuilder.jl | 1 + test/build_app-cli.jl | 59 ++++++++++++----- test/bundle.jl | 1 + test/runtests.jl | 31 +++++---- 6 files changed, 172 insertions(+), 53 deletions(-) diff --git a/src/ApplicationBuilder.jl b/src/ApplicationBuilder.jl index 031bbe6..3bbfa4a 100644 --- a/src/ApplicationBuilder.jl +++ b/src/ApplicationBuilder.jl @@ -39,6 +39,7 @@ function build_app_bundle(juliaprog_main; certificate = nothing, entitlements_file = nothing, snoopfile = nothing, autosnoop = false, cpu_target=nothing, create_installer = false, commandline_app = false, + installer_compiler=SetupCompilers.iss ) # ----------- Input sanity checking -------------- @@ -276,7 +277,7 @@ function build_app_bundle(juliaprog_main; end end elseif Sys.iswindows() - create_installer && win_installer(builddir, name = appname) + create_installer && win_installer(builddir, name=appname, installer_compiler=installer_compiler) end println("~~~~~~ Done building '$appbundle'! ~~~~~~~") diff --git a/src/win-installer.jl b/src/win-installer.jl index 18946ff..ae5ab35 100644 --- a/src/win-installer.jl +++ b/src/win-installer.jl @@ -1,43 +1,129 @@ JULIA_HOME = get(ENV, "JULIA_HOME", "") LICENSE_PATH = joinpath(abspath(JULIA_HOME, ".."), "License.md") +baremodule SetupCompilers + iss="iss" + nsis="nsis" +end + function win_installer(builddir; name = "nothing", - license = LICENSE_PATH) + license = LICENSE_PATH, installer_compiler=SetupCompilers.iss) # check = success(`makensis`) # !check && throw(ErrorException("NSIS not found in path. Exiting.")) - nsis_commands = """ - # set the name of the installer - Name "$(name)" - Outfile "$(name)_Installer.exe" + commands = if installer_compiler == SetupCompilers.nsis + """ + # set the name of the installer + Name "$(name)" + Outfile "$(name)_Installer.exe" - # Default install directory - InstallDir "\$LOCALAPPDATA" + # Default install directory + InstallDir "\$LOCALAPPDATA" - Page license - Page directory - Page instfiles + Page license + Page directory + Page instfiles - LicenseData "$license" + LicenseData "$license" - # create a default section. - Section "Install" + # create a default section. + Section "Install" - SetOutPath "$(joinpath("\$INSTDIR", name))" - File /nonfatal /a /r "$builddir" + SetOutPath "$(joinpath("\$INSTDIR", name))" + File /nonfatal /a /r "$builddir" - CreateShortcut "$(joinpath("\$INSTDIR", name, "$name.lnk"))" "$(joinpath(builddir, "core", "blink.exe"))" + CreateShortcut "$(joinpath("\$INSTDIR", name, "$name.lnk"))" "$(joinpath(builddir, "core", "blink.exe"))" - SectionEnd - """ + SectionEnd + """ + elseif installer_compiler == SetupCompilers.iss + """ + ; $name InnoSetup Compiler + ; This software is property of Gabriel Freire. All Rights reserved. + ; Copyright 2019 + ; Requires InnoSetup Latest (5.5 tested) + ; This script compiles the setup file for $name in the SETUP folder + + #define MyAppName "$name" + #define MyAppVersion "1.0" + #define ApplicationVersion GetStringFileInfo("$(joinpath(builddir, name, "bin", "$(name).exe"))", "FileVersion") + #define MyAppExeName "$name.exe" + + + [Setup] + AppId={{802D0907-22CE-4E43-8FAB-017F687159C4} + AppName={#MyAppName} + AppVersion={#ApplicationVersion} + AppVerName={#MyAppName} + VersionInfoVersion={#ApplicationVersion} + DefaultDirName={pf}\\{#MyAppName} + DisableDirPage=yes + DisableProgramGroupPage=yes + OutputDir=.\\ + OutputBaseFilename=$(name * "Setup") + UninstallDisplayIcon={app}\\{#MyAppExeName} + Compression=lzma + SolidCompression=yes + ; Tell Windows Explorer to reload the environment + ChangesEnvironment=yes + + [CustomMessages] + AppAddPath=Add application directory to your environmental path (required) + + [Languages] + Name: "english"; MessagesFile: "compiler:Default.isl" + + [Tasks] + Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + Name: modifypath; Description:{cm:AppAddPath}; Flags: unchecked + + [Registry] + Root: HKCU; Subkey: "Environment"; ValueType:expandsz; ValueName: "Path"; ValueData: "{olddata};{app}\\bin"; Flags: preservestringtype + + [Files] + Source: "$(joinpath(builddir, name, "bin") * "\\*")"; DestDir: "{app}\\bin"; Flags: ignoreversion + Source: "$(joinpath(builddir, name, "res") * "\\*")"; DestDir: "{app}\\res"; Flags: ignoreversion + Source: "$(joinpath(builddir, name, "lib") * "\\*")"; DestDir: "{app}\\lib"; Flags: ignoreversion + + [Code] + + var CancelWithoutPrompt: boolean; + + function InitializeSetup(): Boolean; + begin + CancelWithoutPrompt := false; + result := true; + Log('{#ApplicationVersion}'); + end; + + procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean); + begin + if CurPageID=wpInstalling then + Confirm := not CancelWithoutPrompt; + end; + + [Icons] + Name: "{commonprograms}\\{#MyAppName}"; Filename: "{app}\\{#MyAppExeName}" + Name: "{commondesktop}\\{#MyAppName}"; Filename: "{app}\\{#MyAppExeName}"; Tasks: desktopicon + Name: "{commonstartup}\\{#MyAppName}"; Filename: "{app}\\{#MyAppExeName}"; + """ + else + throw(ArgumentError("Unknown compiler: $installer_compiler")) + end + + ext = if installer_compiler == SetupCompilers.nsis + "nsi" + elseif installer_compiler == SetupCompilers.iss + "iss" + end @info "Creating installer at $builddir" - nsis_file = joinpath(abspath(builddir, ".."), "$name.nsi") - open(nsis_file, "w") do f - write(f, nsis_commands) + compiler_file = joinpath(abspath(builddir, ".."), "$name.$ext") + open(compiler_file, "w") do f + write(f, commands) end - run(`makensis $nsis_file`) + # run(`makensis $nsis_file`) @info "Created installer successfully." diff --git a/test/ApplicationBuilder.jl b/test/ApplicationBuilder.jl index 09c4b75..0269458 100644 --- a/test/ApplicationBuilder.jl +++ b/test/ApplicationBuilder.jl @@ -1,5 +1,6 @@ # MacOS tests +push!(LOAD_PATH, "..\\..\\") using Test using Pkg using ApplicationBuilder diff --git a/test/build_app-cli.jl b/test/build_app-cli.jl index 8169551..1c28cd0 100644 --- a/test/build_app-cli.jl +++ b/test/build_app-cli.jl @@ -1,28 +1,55 @@ + +push!(LOAD_PATH, "..\\..\\") using Test +# prevent shell_split on removing all slashes +path_to_cmd(path::String) = replace(path, "\\" => "\\\\") + julia = Base.julia_cmd().exec[1] -build_app_jl = joinpath(@__DIR__, "..", "build_app.jl") -examples_hello = joinpath(@__DIR__, "..", "examples", "hello.jl") +build_app_jl = joinpath(abspath(@__DIR__, ".."), "build_app.jl") +examples_hello = joinpath(abspath(@__DIR__, ".."), "examples", "hello.jl") builddir = mktempdir() @assert isdir(builddir) @testset "Basic file resource args" begin # Test the build_app.jl script CLI args. -res1 = @__FILE__ # haha copy this file itself as a "resource"! -res2 = joinpath(@__DIR__, "runtests.jl") # lol sure this is a resource, why not. -NEWARGS = Base.shell_split("""--verbose - -R $res1 --resource $res2 -L $res1 --lib $res2 - $examples_hello "HelloWorld" $builddir""") -eval(:(ARGS = $NEWARGS)) -@test 0 == include("$build_app_jl") -@test isdir("$builddir/HelloWorld.app") -@test isfile("$builddir/HelloWorld.app/Contents/MacOS/hello") - -# Make sure the specified resources and libs were copied: -@test isfile("$builddir/HelloWorld.app/Contents/Resources/$(basename(res1))") -@test isfile("$builddir/HelloWorld.app/Contents/Resources/$(basename(res2))") -@test isfile("$builddir/HelloWorld.app/Contents/Libraries/$(basename(res1))") + res1 = @__FILE__ # haha copy this file itself as a "resource"! + res2 = joinpath(@__DIR__, "runtests.jl") # lol sure this is a resource, why not. + + NEWARGS = Base.shell_split("""--verbose + -R $(path_to_cmd(res1)) --resource $(path_to_cmd(res2)) -L $(path_to_cmd(res1)) --lib $(path_to_cmd(res2)) + $(path_to_cmd(examples_hello)) "HelloWorld" $(path_to_cmd(builddir))""") + eval(:(ARGS = $NEWARGS)) + + @test 0 == include(build_app_jl) + println("=== Build Directory ===") + println(readdir(builddir)) + println(readdir("$builddir/HelloWorld")) + println(readdir("$builddir/HelloWorld/bin")) + println(readdir("$builddir/HelloWorld/res")) + println(readdir("$builddir/HelloWorld/lib")) + + if Sys.isapple() + @test isdir("$builddir/HelloWorld.app") + @test isfile("$builddir/HelloWorld.app/Contents/MacOS/hello") + + # Make sure the specified resources and libs were copied: + @test isfile("$builddir/HelloWorld.app/Contents/Resources/$(basename(res1))") + @test isfile("$builddir/HelloWorld.app/Contents/Resources/$(basename(res2))") + @test isfile("$builddir/HelloWorld.app/Contents/Libraries/$(basename(res1))") + else + @test isdir("$builddir/HelloWorld") + @test isdir("$builddir/HelloWorld/bin") + @test isfile("$builddir/HelloWorld/bin/hello.exe") + @test isfile("$builddir/HelloWorld/bin/hello.dll") + @test isfile("$builddir/HelloWorld/bin/hello.a") + + # Make sure the specified resources and libs were copied: + @test isfile("$builddir/HelloWorld/res/$(basename(res1))") + @test isfile("$builddir/HelloWorld/res/$(basename(res2))") + @test isfile("$builddir/HelloWorld/lib/$(basename(res1))") + end end @testset "Exits without juliaprog_main" begin diff --git a/test/bundle.jl b/test/bundle.jl index 480f23d..a6c510a 100644 --- a/test/bundle.jl +++ b/test/bundle.jl @@ -1,5 +1,6 @@ # Windows and Linux tests +push!(LOAD_PATH, "..\\..\\") using Test using Pkg using ApplicationBuilder diff --git a/test/runtests.jl b/test/runtests.jl index 5cf3b7e..27e29d3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,22 +1,25 @@ using Test - @testset "ApplicationBuilder.jl" begin -# TODO: Make the tests work on Windows and Linux!!! :'( -@static if Sys.isapple() + # TODO: Make the tests work on Windows and Linux!!! :'( + @static if Sys.isapple() -@testset "Test ApplicationBuilder (by compiling examples/*.jl)" begin - include("ApplicationBuilder.jl") -end -@testset "Command-line interface (compiling examples/*.jl)" begin - include("build_app-cli.jl") -end + @testset "Test ApplicationBuilder (by compiling examples/*.jl)" begin + include("ApplicationBuilder.jl") + end + @testset "Command-line interface (compiling examples/*.jl)" begin + include("build_app-cli.jl") + end -else # Windows and Linux + end + @static if Sys.iswindows() # Windows -@testset "bundle.jl" begin - include("bundle.jl") -end + @testset "bundle.jl" begin + include("bundle.jl") + end -end + @testset "Command-line interface (compiling examples/*.jl)" begin + include("build_app-cli.jl") + end + end end From 879a0fe7a07dd458f82b029f096a7142ad4f1f91 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Fri, 7 Jun 2019 17:17:45 +0100 Subject: [PATCH 11/14] Remove LOAD_PATH modification from test files --- test/ApplicationBuilder.jl | 1 - test/build_app-cli.jl | 1 - test/bundle.jl | 1 - 3 files changed, 3 deletions(-) diff --git a/test/ApplicationBuilder.jl b/test/ApplicationBuilder.jl index 0269458..09c4b75 100644 --- a/test/ApplicationBuilder.jl +++ b/test/ApplicationBuilder.jl @@ -1,6 +1,5 @@ # MacOS tests -push!(LOAD_PATH, "..\\..\\") using Test using Pkg using ApplicationBuilder diff --git a/test/build_app-cli.jl b/test/build_app-cli.jl index 1c28cd0..75ddfe8 100644 --- a/test/build_app-cli.jl +++ b/test/build_app-cli.jl @@ -1,5 +1,4 @@ -push!(LOAD_PATH, "..\\..\\") using Test # prevent shell_split on removing all slashes diff --git a/test/bundle.jl b/test/bundle.jl index a6c510a..480f23d 100644 --- a/test/bundle.jl +++ b/test/bundle.jl @@ -1,6 +1,5 @@ # Windows and Linux tests -push!(LOAD_PATH, "..\\..\\") using Test using Pkg using ApplicationBuilder From 05c0a91af2315b03eb62ea3173144c5517d3553b Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Fri, 7 Jun 2019 17:29:22 +0100 Subject: [PATCH 12/14] Use string value --- src/ApplicationBuilder.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ApplicationBuilder.jl b/src/ApplicationBuilder.jl index 3bbfa4a..d3e1d05 100644 --- a/src/ApplicationBuilder.jl +++ b/src/ApplicationBuilder.jl @@ -39,7 +39,7 @@ function build_app_bundle(juliaprog_main; certificate = nothing, entitlements_file = nothing, snoopfile = nothing, autosnoop = false, cpu_target=nothing, create_installer = false, commandline_app = false, - installer_compiler=SetupCompilers.iss + installer_compiler="iss" ) # ----------- Input sanity checking -------------- From f4e9f717cb008ab76396e82077321cb2991b458d Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Tue, 18 Jun 2019 19:50:45 +0100 Subject: [PATCH 13/14] Fix command line wrapper and iss win-installer --- src/win-installer.jl | 31 +++++++++++++++++++++++++++---- src/win_commandline_app.jl | 6 +++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/win-installer.jl b/src/win-installer.jl index ae5ab35..725f42a 100644 --- a/src/win-installer.jl +++ b/src/win-installer.jl @@ -6,6 +6,15 @@ baremodule SetupCompilers nsis="nsis" end +function _hasfilesin(path::String)::Bool + for (root, dir, files) in walkdir(path) + if length(files) > 0 + return true + end + end + return false +end + function win_installer(builddir; name = "nothing", license = LICENSE_PATH, installer_compiler=SetupCompilers.iss) @@ -38,6 +47,22 @@ function win_installer(builddir; name = "nothing", SectionEnd """ elseif installer_compiler == SetupCompilers.iss + res_path = joinpath(builddir, name, "res") + lib_path = joinpath(builddir, name, "lib") + files = + """ + [Files] + Source: "$(joinpath(builddir, name, "bin") * "\\*")"; DestDir: "{app}\\bin"; Flags: ignoreversion + """ + + if isdir(res_path) && _hasfilesin(res_path) + files *= """\nSource: "$(res_path * "\\*")"; DestDir: "{app}\\res"; Flags: ignoreversion""" + end + + if isdir(lib_path) && _hasfilesin(lib_path) + files *= """\nSource: "$(lib_path * "\\*")"; DestDir: "{app}\\lib"; Flags: ignoreversion""" + end + """ ; $name InnoSetup Compiler ; This software is property of Gabriel Freire. All Rights reserved. @@ -67,6 +92,7 @@ function win_installer(builddir; name = "nothing", SolidCompression=yes ; Tell Windows Explorer to reload the environment ChangesEnvironment=yes + UsePreviousAppDir=False [CustomMessages] AppAddPath=Add application directory to your environmental path (required) @@ -81,10 +107,7 @@ function win_installer(builddir; name = "nothing", [Registry] Root: HKCU; Subkey: "Environment"; ValueType:expandsz; ValueName: "Path"; ValueData: "{olddata};{app}\\bin"; Flags: preservestringtype - [Files] - Source: "$(joinpath(builddir, name, "bin") * "\\*")"; DestDir: "{app}\\bin"; Flags: ignoreversion - Source: "$(joinpath(builddir, name, "res") * "\\*")"; DestDir: "{app}\\res"; Flags: ignoreversion - Source: "$(joinpath(builddir, name, "lib") * "\\*")"; DestDir: "{app}\\lib"; Flags: ignoreversion + $(files) [Code] diff --git a/src/win_commandline_app.jl b/src/win_commandline_app.jl index 4bbfeea..cb1e274 100644 --- a/src/win_commandline_app.jl +++ b/src/win_commandline_app.jl @@ -1,8 +1,8 @@ function get_commandline_sh_script(appname) """ @echo off - set dir=%~dp0 - call %dir%$(appname).exe %* + set source_dir=%~dp0 + call "%source_dir%$(appname).exe" %* """ end @@ -17,7 +17,7 @@ function build_commandline_app_bundle(builddir, binary_name, appname, verbose) exe_dir = "bin" # Put the binaries next to the applet in MacOS. script_name = "$(binary_name).bat" if binary_name == appname # Prevent collisions. - script_name = "$(binary_name)_exec.bat" + script_name = "$(binary_name)_.bat" end script_path = joinpath(app_path, exe_dir, script_name) mkpath(dirname(script_path)) From 71cfcf3e4e0dad22f1249fdb574791f248ae2ad8 Mon Sep 17 00:00:00 2001 From: Gabriel Freire Date: Wed, 19 Jun 2019 00:29:06 +0100 Subject: [PATCH 14/14] fix windows installer and fix apple test --- src/win-installer.jl | 4 ++-- test/build_app-cli.jl | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/win-installer.jl b/src/win-installer.jl index 725f42a..8bfbf6f 100644 --- a/src/win-installer.jl +++ b/src/win-installer.jl @@ -56,11 +56,11 @@ function win_installer(builddir; name = "nothing", """ if isdir(res_path) && _hasfilesin(res_path) - files *= """\nSource: "$(res_path * "\\*")"; DestDir: "{app}\\res"; Flags: ignoreversion""" + files = "$files\nSource: \"$(res_path * "\\*")\"; DestDir: \"{app}\\res\"; Flags: ignoreversion" end if isdir(lib_path) && _hasfilesin(lib_path) - files *= """\nSource: "$(lib_path * "\\*")"; DestDir: "{app}\\lib"; Flags: ignoreversion""" + files = "$files\nSource: \"$(lib_path * "\\*")\"; DestDir: \"{app}\\lib\"; Flags: ignoreversion" end """ diff --git a/test/build_app-cli.jl b/test/build_app-cli.jl index 75ddfe8..9576316 100644 --- a/test/build_app-cli.jl +++ b/test/build_app-cli.jl @@ -22,12 +22,6 @@ builddir = mktempdir() eval(:(ARGS = $NEWARGS)) @test 0 == include(build_app_jl) - println("=== Build Directory ===") - println(readdir(builddir)) - println(readdir("$builddir/HelloWorld")) - println(readdir("$builddir/HelloWorld/bin")) - println(readdir("$builddir/HelloWorld/res")) - println(readdir("$builddir/HelloWorld/lib")) if Sys.isapple() @test isdir("$builddir/HelloWorld.app")