[
  {
    "path": ".gitignore",
    "content": "*.ji\n*.o\n*.so\n*.so.*\n*.dylib\n*.dll\nhello\nhello.exe\n"
  },
  {
    "path": ".mailmap",
    "content": "Luca Trevisani <lucatrv@users.noreply.github.com> <lucatrv@users.noreply.github.com>\nLuca Trevisani <lucatrv@users.noreply.github.com> <lucatrv@hotmail.com>\n\nViral B. Shah <viral@mayin.org> <viral@mayin.org>\nViral B. Shah <viral@mayin.org> <viral@juliacomputing.com>\nViral B. Shah <viral@mayin.org> <viralbshah@anubis.juliacomputing.io>\n"
  },
  {
    "path": "README.md",
    "content": "## NOTE: This repository is mainly for purposes of experimentation and no longer expected to be used going forward. `juliac.jl` has been merged into [PackageCompiler.jl](https://github.com/JuliaLang/PackageCompiler.jl). Please install that package to use `juliac.jl`.\n\n----------------------\n\n# Static Julia Compiler\n\nBuilding shared libraries and executables from Julia code.\n\nRun `juliac.jl -h` for help:\n\n```\nusage: juliac.jl [-v] [-q] [-c] [-J <file>]\n                 [--compile {yes|no|all|min}] [-C <target>]\n                 [-O {0,1,2,3}] [-g {0,1,2}] [--inline {yes|no}]\n                 [--check-bounds {yes|no}] [--math-mode {ieee,fast}]\n                 [--depwarn {yes|no|error}] [-a] [-o] [-s] [-e] [-j]\n                 [--version] [-h] juliaprog [cprog] [builddir]\n\nStatic Julia Compiler\n\npositional arguments:\n  juliaprog             Julia program to compile\n  cprog                 C program to compile (required only when\n                        building an executable; if not provided a\n                        minimal standard program is used)\n  builddir              build directory, either absolute or relative\n                        to the Julia program directory (default:\n                        \"builddir\")\n\noptional arguments:\n  -v, --verbose         increase verbosity\n  -q, --quiet           suppress non-error messages\n  -c, --clean           delete builddir\n  -J, --sysimage <file>\n                        start up with the given system image file\n  --compile {yes|no|all|min}\n                        enable or disable JIT compiler, or request\n                        exhaustive compilation\n  -C, --cpu-target <target>\n                        limit usage of CPU features up to <target>\n  -O, --optimize {0,1,2,3}\n                        set optimization level (type: Int64)\n  -g {0,1,2}            set debugging information level (type: Int64)\n  --inline {yes|no}     control whether inlining is permitted\n  --check-bounds {yes|no}\n                        emit bounds checks always or never\n  --math-mode {ieee,fast}\n                        set floating point optimizations\n  --depwarn {yes|no|error}\n                        set syntax and method deprecation warnings\n  -a, --autodeps        automatically build required dependencies\n  -o, --object          build object file\n  -s, --shared          build shared library\n  -e, --executable      build executable file\n  -j, --julialibs       sync Julia libraries to builddir\n  --version             show version information and exit\n  -h, --help            show this help message and exit\n\nexamples:\n  juliac.jl -vae hello.jl        # verbose, build executable and deps\n  juliac.jl -vae hello.jl prog.c # embed into user defined C program\n  juliac.jl -qo hello.jl         # quiet, build object file only\n  juliac.jl -vosej hello.jl      # build all and sync Julia libs\n```\n\n### Notes\n\n1. The `juliac.jl` script uses the `ArgParse` package, make sure it is installed.\n\n3. On Windows install `Cygwin` and the `mingw64-x86_64-gcc-core` package, see:\\\n   https://github.com/JuliaLang/julia/blob/master/README.windows.md\n\n2. A shared library containing the system image `libhello.so`, and a\n   driver binary `hello` are created in the `builddir` directory.\n   Running `hello` produces the following output:\n\n```\n   $ ./hello\n   hello, world\n   f() = -0.37549581296986956\n       ┌─────────────────────────────────────────────────┐\n   100 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠊⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠔⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       │⠀⠀⠀⠀⠀⠀⢀⣀⠤⠔⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n     0 │⣀⠤⠤⠔⠒⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│\n       └─────────────────────────────────────────────────┘\n       1                                       10\n```\n\n## Under the hood\n\nThe `juliac.jl` script uses the `--output-o` switch to compile the user\nscript into object code, and then builds it into the system image\nspecified by the `-J` switch. This prepares an object file, which is\nthen linked into a shared library containing the system image and user\ncode. A driver script such as the one in `program.c` can then be used to\nbuild a binary that runs the julia code.\n\nInstead of a driver script, the generated system image can be embedded\ninto a larger program following the embedding examples and relevant\nsections in the Julia manual. Note that the name of the generated system\nimage (`\"libhello\"` for `hello.jl`) is accessible from C in the\npreprocessor macro `JULIAC_PROGRAM_LIBNAME`.\n\nWith Julia 0.7, a single large binary can be created, which does not\nrequire the driver program to load the shared library. An example of\nthat is in `program2.c`, where the image file is the binary itself.\n\nFor more information on static Julia compilation see:\\\nhttps://juliacomputing.com/blog/2016/02/09/static-julia.html\n\nFor more information on embedding Julia see:\\\nhttps://github.com/JuliaLang/julia/blob/master/doc/src/manual/embedding.md\n"
  },
  {
    "path": "hello.jl",
    "content": "module Hello\n\nusing UnicodePlots\nusing Distributions\nf() = rand(Normal())\n\nBase.@ccallable function julia_main(ARGS::Vector{String})::Cint\n    println(\"hello, world\")\n    @show f()\n    println(lineplot(1:10, (1:10).^2))\n    return 0\nend\n\nend\n"
  },
  {
    "path": "juliac.jl",
    "content": "## Assumptions:\n## 1. gcc / x86_64-w64-mingw32-gcc is available and is in path\n## 2. Package ArgParse is installed\n\n# TODO: remove once Julia v0.7 is released\njulia_v07 = VERSION > v\"0.7-\"\n\nusing ArgParse\njulia_v07 && using Libdl\n\nfunction main(args)\n\n    s = ArgParseSettings(\"Static Julia Compiler\",\n                         version = \"$(basename(@__FILE__)) version 0.7-DEV\",\n                         add_version = true)\n\n    @add_arg_table s begin\n        \"juliaprog\"\n            arg_type = String\n            required = true\n            help = \"Julia program to compile\"\n        \"cprog\"\n            arg_type = String\n            default = nothing\n            help = \"C program to compile (required only when building an executable; if not provided a minimal driver program is used)\"\n        \"builddir\"\n            arg_type = String\n            default = \"builddir\"\n            help = \"build directory, either absolute or relative to the Julia program directory\"\n        \"--verbose\", \"-v\"\n            action = :store_true\n            help = \"increase verbosity\"\n        \"--quiet\", \"-q\"\n            action = :store_true\n            help = \"suppress non-error messages\"\n        \"--clean\", \"-c\"\n            action = :store_true\n            help = \"delete builddir\"\n        \"--sysimage\", \"-J\"\n            arg_type = String\n            default = nothing\n            metavar = \"<file>\"\n            help = \"start up with the given system image file\"\n        \"--compile\"\n            arg_type = String\n            default = nothing\n            metavar = \"{yes|no|all|min}\"\n            range_tester = (x -> x == \"yes\" || x == \"no\" || x == \"all\" || x == \"min\")\n            help = \"enable or disable JIT compiler, or request exhaustive compilation\"\n        \"--cpu-target\", \"-C\"\n            arg_type = String\n            default = nothing\n            metavar = \"<target>\"\n            help = \"limit usage of CPU features up to <target>\"\n        \"--optimize\", \"-O\"\n            arg_type = Int\n            default = nothing\n            metavar = \"{0,1,2,3}\"\n            range_tester = (x -> 0 <= x <= 3)\n            help = \"set optimization level\"\n        \"-g\"\n            arg_type = Int\n            default = nothing\n            dest_name = \"debug\"\n            metavar = \"{0,1,2}\"\n            range_tester = (x -> 0 <= x <= 2)\n            help = \"set debugging information level\"\n        \"--inline\"\n            arg_type = String\n            default = nothing\n            metavar = \"{yes|no}\"\n            range_tester = (x -> x == \"yes\" || x == \"no\")\n            help = \"control whether inlining is permitted\"\n        \"--check-bounds\"\n            arg_type = String\n            default = nothing\n            metavar = \"{yes|no}\"\n            range_tester = (x -> x == \"yes\" || x == \"no\")\n            help = \"emit bounds checks always or never\"\n        \"--math-mode\"\n            arg_type = String\n            default = nothing\n            metavar = \"{ieee,fast}\"\n            range_tester = (x -> x == \"ieee\" || x == \"fast\")\n            help = \"set floating point optimizations\"\n        \"--depwarn\"\n            arg_type = String\n            default = nothing\n            metavar = \"{yes|no|error}\"\n            range_tester = (x -> x == \"yes\" || x == \"no\" || x == \"error\")\n            help = \"set syntax and method deprecation warnings\"\n        \"--autodeps\", \"-a\"\n            action = :store_true\n            help = \"automatically build required dependencies\"\n        \"--object\", \"-o\"\n            action = :store_true\n            help = \"build object file\"\n        \"--shared\", \"-s\"\n            action = :store_true\n            help = \"build shared library\"\n        \"--executable\", \"-e\"\n            action = :store_true\n            help = \"build executable file\"\n        \"--julialibs\", \"-j\"\n            action = :store_true\n            help = \"sync Julia libraries to builddir\"\n    end\n\n    s.epilog = \"\"\"\n        examples:\\n\n        \\ua0\\ua0juliac.jl -vae hello.jl        # verbose, build executable and deps\\n\n        \\ua0\\ua0juliac.jl -vae hello.jl prog.c # embed into user defined C program\\n\n        \\ua0\\ua0juliac.jl -qo hello.jl         # quiet, build object file only\\n\n        \\ua0\\ua0juliac.jl -vosej hello.jl      # build all and sync Julia libs\\n\n        \"\"\"\n\n    parsed_args = parse_args(args, s)\n\n    # TODO: in future it may be possible to broadcast dictionary indexing, see: https://discourse.julialang.org/t/accessing-multiple-values-of-a-dictionary/8648\n    if !any(getindex.(parsed_args, [\"clean\", \"object\", \"shared\", \"executable\", \"julialibs\"]))\n        parsed_args[\"quiet\"] || println(\"Nothing to do, exiting\\nTry \\\"$(basename(@__FILE__)) -h\\\" for more information\")\n        exit(0)\n    end\n\n    julia_compile(\n        parsed_args[\"juliaprog\"],\n        parsed_args[\"cprog\"],\n        parsed_args[\"builddir\"],\n        parsed_args[\"verbose\"],\n        parsed_args[\"quiet\"],\n        parsed_args[\"clean\"],\n        parsed_args[\"sysimage\"],\n        parsed_args[\"compile\"],\n        parsed_args[\"cpu-target\"],\n        parsed_args[\"optimize\"],\n        parsed_args[\"debug\"],\n        parsed_args[\"inline\"],\n        parsed_args[\"check-bounds\"],\n        parsed_args[\"math-mode\"],\n        parsed_args[\"depwarn\"],\n        parsed_args[\"autodeps\"],\n        parsed_args[\"object\"],\n        parsed_args[\"shared\"],\n        parsed_args[\"executable\"],\n        parsed_args[\"julialibs\"]\n    )\nend\n\nfunction julia_compile(julia_program, c_program=nothing, build_dir=\"builddir\", verbose=false, quiet=false,\n                       clean=false, sysimage = nothing, compile=nothing, cpu_target=nothing, optimize=nothing,\n                       debug=nothing, inline=nothing, check_bounds=nothing, math_mode=nothing, depwarn=nothing,\n                       autodeps=false, object=false, shared=false, executable=true, julialibs=true)\n\n    verbose && quiet && (quiet = false)\n\n    if autodeps\n        executable && (shared = true)\n        shared && (object = true)\n    end\n\n    julia_program = abspath(julia_program)\n    isfile(julia_program) || error(\"Cannot find file:\\n  \\\"$julia_program\\\"\")\n    quiet || println(\"Julia program file:\\n  \\\"$julia_program\\\"\")\n\n    if executable\n        c_program = c_program == nothing ? joinpath(@__DIR__, \"program.c\") : abspath(c_program)\n        isfile(c_program) || error(\"Cannot find file:\\n  \\\"$c_program\\\"\")\n        quiet || println(\"C program file:\\n  \\\"$c_program\\\"\")\n    end\n\n    cd(dirname(julia_program))\n\n    build_dir = abspath(build_dir)\n    quiet || println(\"Build directory:\\n  \\\"$build_dir\\\"\")\n\n    if clean\n        if isdir(build_dir)\n            verbose && println(\"Delete build directory\")\n            rm(build_dir, recursive=true)\n        else\n            verbose && println(\"Build directory does not exist, nothing to delete\")\n        end\n    end\n\n    if !isdir(build_dir)\n        verbose && println(\"Make build directory\")\n        mkpath(build_dir)\n    end\n\n    if pwd() != build_dir\n        verbose && println(\"Change to build directory\")\n        cd(build_dir)\n    else\n        verbose && println(\"Already in build directory\")\n    end\n\n    julia_program_basename = splitext(basename(julia_program))[1]\n    o_file = julia_program_basename * \".o\"\n    s_file = \"lib\" * julia_program_basename * \".$(Libdl.dlext)\"\n    if julia_v07\n        e_file = julia_program_basename * (Sys.iswindows() ? \".exe\" : \"\")\n    else\n        e_file = julia_program_basename * (is_windows() ? \".exe\" : \"\")\n    end\n    tmp_dir = \"tmp_v$VERSION\"\n\n    # TODO: these should probably be emitted from julia-config also:\n    if julia_v07\n        shlibdir = Sys.iswindows() ? Sys.BINDIR : abspath(Sys.BINDIR, Base.LIBDIR)\n        private_shlibdir = abspath(Sys.BINDIR, Base.PRIVATE_LIBDIR)\n    else\n        shlibdir = is_windows() ? JULIA_HOME : abspath(JULIA_HOME, Base.LIBDIR)\n        private_shlibdir = abspath(JULIA_HOME, Base.PRIVATE_LIBDIR)\n    end\n\n    if object\n        julia_cmd = `$(Base.julia_cmd())`\n        if length(julia_cmd.exec) != 5 || !all(startswith.(julia_cmd.exec[2:5], [\"-C\", \"-J\", \"--compile\", \"--depwarn\"]))\n            error(\"Unexpected format of \\\"Base.julia_cmd()\\\", you may be using an incompatible version of Julia\")\n        end\n        sysimage == nothing || (julia_cmd.exec[3] = \"-J$sysimage\")\n        push!(julia_cmd.exec, \"--startup-file=no\")\n        compile == nothing || (julia_cmd.exec[4] = \"--compile=$compile\")\n        cpu_target == nothing || (julia_cmd.exec[2] = \"-C$cpu_target\")\n        optimize == nothing || push!(julia_cmd.exec, \"-O$optimize\")\n        debug == nothing || push!(julia_cmd.exec, \"-g$debug\")\n        inline == nothing || push!(julia_cmd.exec, \"--inline=$inline\")\n        check_bounds == nothing || push!(julia_cmd.exec, \"--check-bounds=$check_bounds\")\n        math_mode == nothing || push!(julia_cmd.exec, \"--math-mode=$math_mode\")\n        depwarn == nothing || (julia_cmd.exec[5] = \"--depwarn=$depwarn\")\n        if julia_v07\n            Sys.iswindows() && (julia_program = replace(julia_program, \"\\\\\", \"\\\\\\\\\"))\n            expr = \"\n  Base.init_depot_path() # initialize package depots\n  Base.init_load_path() # initialize location of site-packages\n  empty!(Base.LOAD_CACHE_PATH) # reset / remove any builtin paths\n  push!(Base.LOAD_CACHE_PATH, abspath(\\\"$tmp_dir\\\")) # enable usage of precompiled files\n  include(\\\"$julia_program\\\") # include \\\"julia_program\\\" file\n  empty!(Base.LOAD_CACHE_PATH) # reset / remove build-system-relative paths\"\n        else\n            is_windows() && (julia_program = replace(julia_program, \"\\\\\", \"\\\\\\\\\"))\n            expr = \"\n  empty!(Base.LOAD_CACHE_PATH) # reset / remove any builtin paths\n  push!(Base.LOAD_CACHE_PATH, abspath(\\\"$tmp_dir\\\")) # enable usage of precompiled files\n  include(\\\"$julia_program\\\") # include \\\"julia_program\\\" file\n  empty!(Base.LOAD_CACHE_PATH) # reset / remove build-system-relative paths\"\n        end\n        isdir(tmp_dir) || mkpath(tmp_dir)\n        command = `$julia_cmd -e $expr`\n        verbose && println(\"Build module image files \\\".ji\\\" in subdirectory \\\"$tmp_dir\\\":\\n  $command\")\n        run(command)\n        command = `$julia_cmd --output-o $(joinpath(tmp_dir, o_file)) -e $expr`\n        verbose && println(\"Build object file \\\"$o_file\\\" in subdirectory \\\"$tmp_dir\\\":\\n  $command\")\n        run(command)\n    end\n\n    if shared || executable\n        if julia_v07\n            cc = Sys.iswindows() ? \"x86_64-w64-mingw32-gcc\" : \"gcc\"\n            command = `$(Base.julia_cmd()) --startup-file=no $(joinpath(dirname(Sys.BINDIR), \"share\", \"julia\", \"julia-config.jl\"))`\n            flags = `$(Base.shell_split(read(\\`$command --allflags\\`, String)))`\n        else\n            cc = is_windows() ? \"x86_64-w64-mingw32-gcc\" : \"gcc\"\n            command = `$(Base.julia_cmd()) --startup-file=no $(joinpath(dirname(JULIA_HOME), \"share\", \"julia\", \"julia-config.jl\"))`\n            cflags = `$(Base.shell_split(readstring(\\`$command --cflags\\`)))`\n            ldflags = `$(Base.shell_split(readstring(\\`$command --ldflags\\`)))`\n            ldlibs = `$(Base.shell_split(readstring(\\`$command --ldlibs\\`)))`\n            flags = `$cflags $ldflags $ldlibs`\n        end\n    end\n\n    if shared\n        command = `$cc -m64 -shared -o $s_file $(joinpath(tmp_dir, o_file)) $flags`\n        if julia_v07\n            if Sys.isapple()\n                command = `$command -Wl,-install_name,@rpath/\\\"$s_file\\\"`\n            elseif Sys.iswindows()\n                command = `$command -Wl,--export-all-symbols`\n            end\n        else\n            if is_apple()\n                command = `$command -Wl,-install_name,@rpath/\\\"$s_file\\\"`\n            elseif is_windows()\n                command = `$command -Wl,--export-all-symbols`\n            end\n        end\n        verbose && println(\"Build shared library \\\"$s_file\\\" in build directory:\\n  $command\")\n        run(command)\n    end\n\n    if executable\n        command = `$cc -m64 -DJULIAC_PROGRAM_LIBNAME=\\\"lib$julia_program_basename\\\" -o $e_file $c_program $s_file $flags`\n        if julia_v07\n            if Sys.isapple()\n                command = `$command -Wl,-rpath,@executable_path`\n            elseif Sys.isunix()\n                command = `$command -Wl,-rpath,\\$ORIGIN`\n            end\n        else\n            if is_apple()\n                command = `$command -Wl,-rpath,@executable_path`\n            elseif is_unix()\n                command = `$command -Wl,-rpath,\\$ORIGIN`\n            end\n        end\n        verbose && println(\"Build executable file \\\"$e_file\\\" in build directory:\\n  $command\")\n        run(command)\n    end\n\n    if julialibs\n        verbose && println(\"Sync Julia libraries to build directory:\")\n        libfiles = String[]\n        dlext = \".\" * Libdl.dlext\n        for dir in (shlibdir, private_shlibdir)\n            if julia_v07\n                if Sys.iswindows() || Sys.isapple()\n                    append!(libfiles, joinpath.(dir, filter(x -> endswith(x, dlext), readdir(dir))))\n                else\n                    append!(libfiles, joinpath.(dir, filter(x -> contains(x, r\"^lib.+\\.so(?:\\.\\d+)*$\"), readdir(dir))))\n                end\n            else\n                if is_windows() || is_apple()\n                    append!(libfiles, joinpath.(dir, filter(x -> endswith(x, dlext), readdir(dir))))\n                else\n                    append!(libfiles, joinpath.(dir, filter(x -> ismatch(r\"^lib.+\\.so(?:\\.\\d+)*$\", x), readdir(dir))))\n                end\n            end\n        end\n        sync = false\n        for src in libfiles\n            if julia_v07\n                contains(src, r\"debug\") && continue\n            else\n                ismatch(r\"debug\", src) && continue\n            end\n            dst = basename(src)\n            if filesize(src) != filesize(dst) || ctime(src) > ctime(dst) || mtime(src) > mtime(dst)\n                verbose && println(\"  $dst\")\n                cp(src, dst, remove_destination=true, follow_symlinks=false)\n                sync = true\n            end\n        end\n        sync || verbose && println(\"  none\")\n    end\nend\n\nmain(ARGS)\n"
  },
  {
    "path": "program.c",
    "content": "// This file is a part of Julia. License is MIT: http://julialang.org/license\n\n// Standard headers\n#include <string.h>\n#include <stdint.h>\n\n// Julia headers (for initialization and gc commands)\n#include \"uv.h\"\n#include \"julia.h\"\n\n#ifdef JULIA_DEFINE_FAST_TLS // only available in Julia v0.7 and above\nJULIA_DEFINE_FAST_TLS()\n#endif\n\n// Declare C prototype of a function defined in Julia\nextern void julia_main();\n\nint main(int argc, char *argv[])\n{\n    intptr_t v;\n\n    // Initialize Julia\n    uv_setup_args(argc, argv); // no-op on Windows\n    libsupport_init();\n    // JULIAC_PROGRAM_LIBNAME defined on command-line for compilation\n    jl_options.image_file = JULIAC_PROGRAM_LIBNAME;\n    julia_init(JL_IMAGE_JULIA_HOME);\n\n    // Do some work\n    julia_main();\n\n    // Cleanup and graceful exit\n    jl_atexit_hook(0);\n    return 0;\n}\n"
  },
  {
    "path": "program2.c",
    "content": "// This file is a part of Julia. License is MIT: http://julialang.org/license\n\n// Standard headers\n#include <string.h>\n#include <stdint.h>\n\n// Julia headers (for initialization and gc commands)\n#include \"uv.h\"\n#include \"julia.h\"\n\n#ifdef JULIA_DEFINE_FAST_TLS // only available in Julia v0.7 and above\nJULIA_DEFINE_FAST_TLS()\n#endif\n\n// Declare C prototype of a function defined in Julia\nextern int julia_main(jl_array_t*);\n\n// main function (windows UTF16 -> UTF8 argument conversion code copied from julia's ui/repl.c)\n#ifndef _OS_WINDOWS_\nint main(int argc, char *argv[])\n{\n    int retcode;\n    int i;\n    uv_setup_args(argc, argv); // no-op on Windows\n#else\nint wmain(int argc, wchar_t *wargv[], wchar_t *envp[])\n{\n    int retcode;\n    int i;\n    char **argv;\n    for (i = 0; i < argc; i++) { // convert the command line to UTF8\n        wchar_t *warg = argv[i];\n        size_t len = WideCharToMultiByte(CP_UTF8, 0, warg, -1, NULL, 0, NULL, NULL);\n        if (!len) return 1;\n        char *arg = (char*)alloca(len);\n        if (!WideCharToMultiByte(CP_UTF8, 0, warg, -1, arg, len, NULL, NULL)) return 1;\n        argv[i] = arg;\n    }\n#endif\n\n    // initialization\n    libsupport_init();\n    // jl_options.compile_enabled = JL_OPTIONS_COMPILE_OFF;\n    // JULIAC_PROGRAM_LIBNAME defined on command-line for compilation\n    jl_options.image_file = JULIAC_PROGRAM_LIBNAME;\n    julia_init(JL_IMAGE_JULIA_HOME);\n\n    // build arguments array: `String[ unsafe_string(argv[i]) for i in 1:argc ]`\n    jl_array_t *ARGS = jl_alloc_array_1d(jl_apply_array_type(jl_string_type, 1), 0);\n    JL_GC_PUSH1(&ARGS);\n    jl_array_grow_end(ARGS, argc - 1);\n    for (i = 1; i < argc; i++) {\n        jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]);\n        jl_arrayset(ARGS, s, i - 1);\n    }\n    // call the work function, and get back a value\n    retcode = julia_main(ARGS);\n    JL_GC_POP();\n\n    // Cleanup and gracefully exit\n    jl_atexit_hook(retcode);\n    return retcode;\n}\n"
  }
]