I will explain my question in details using a super simple toy example in below.
The structure of the code is as the following. Everything is in a folder called “Test_making_app”. This folder contains two julia files and a subfoler called “Temp”. The main Julia file is called “Test_making_app.jl” with the following content.
module Test_making_app
function julia_main()::Cint
try
file_name=ARGS[1]
multiplier=parse(Int,ARGS[2])
input_file=open(joinpath(pwd(),file_name),"r")
input_text=readline(input_file)
close(input_file)
input_source=open(joinpath(pwd(),"Temp","input.jl"),"w")
write(input_source,"input_list=[$input_text]")
close(input_source)
include(joinpath(pwd(),"Task.jl"))
output_result=task(multiplier)
output_file=open(joinpath(pwd(),"output.txt"),"w")
write(output_file,"The user input:\n$input_text\n\nThe app output:\n$output_result")
close(output_file)
catch
Base.invokelatest(Base.display_error, Base.catch_stack())
return 1
end
return 0 # if things finished successfully
end
end # module
The second julia file is called “Task.jl” and has the following content.
include(joinpath(pwd(),"Temp","input.jl"))
x=input_list[1]
y=input_list[2]
function task(z)
return x+z*y
end
The subfolder is empty.
What is this app going to do?
First you write an input file. Let’s say a txt file with the name “input1.txt” and you write two numbers with a comma between. Let’s say I wrote 1,3
, you save it and put it in this folder (Test_making_app). In your windows cmd or your own terminal you cd to this folder, then type the follwowing;
Julia Test_making_app.jl <argument1> <argument2>
Where instead of <argument1>
you type name of your input file, here “input1.txt”. Instead of <argument2>
you type a number, let’s say “2”. So it will be like the following;
Julia Test_making_app.jl input1.txt 2
Then you press enter. The app reads your input, then creates a new julia file in the temp folder called “input.jl”. Then passes the second argument to the Task.jl file. Task.jl file receives the second argument and some other values from input.jl file, does a computation and then returns the result back to the main julia file. At the end a report is written in a new txt file saved in Test_making_app folder which is supposed to be the output for the user.
Everything works fine. This is a simple example. Of course I could write the above code in a single julia file, but I’m not going to simplify any steps above because my goal is to learn how to make something with a structure like above to become an application.
Why to make it an application?
The real examples (not this simple example) may be written in a specific version of Julia and hence later when syntax of some parts of the code are changed in newer versions of Julia, the user can’t use it as it is without going over all the files and codes and change stuff.
Now the questions!
What I could understand is that I have to use “PackageCompiler” and before using it I have to give a project style to my code in a Julia sense. To do that I have to use Pkg. Following what I understand from reading the documentations of these two (link:Pkg, link:PackageCompiler) I did the following steps.
1- Going to an empty directory. Here in my case D:\\
.
2- In Julia doing the following
(@v1.4) Pkg> generate Test_making_app
Julia> cd("Test_making_app")
(@v1.4) pkg> activate .
Activating environment at `D:\Test_making_app\Project.toml`
(Test_making_app) pkg> st
Project Test_making_app v0.1.0
Status `D:\Test_making_app\Project.toml`
(empty environment)
Then I replaced all content of my old folder “Test_making_app” (the two julia files and empty temp folder) into the src folder of this project. Then
(Test_making_app) pkg> precompile
Precompiling project...
[ Info: Precompiling Test_making_app [8f396c06-8ec7-49f7-a929-b1265c672a0b]
(Test_making_app) pkg> st
Project Test_making_app v0.1.0
Status `D:\Test_making_app\Project.toml`
(empty environment)
Now I use the PackageCompiler.
D:\>Julia -q --project
julia> using PackageCompiler
[ Info: Precompiling PackageCompiler [9b87118b-4619-50d2-8e1e-99f35a4d4d9d]
julia> create_app("Test_making_app","Test_making_app_compiled")
┌ Warning: it is not recommended to create an app without a preexisting manifest
└ @ PackageCompiler C:\Users\Amir\.julia\packages\PackageCompiler\vsMJE\src\PackageCompiler.jl:593
Updating registry at `C:\Users\Amir\.julia\registries\General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Updating `D:\Test_making_app\Project.toml`
[no changes]
Updating `D:\Test_making_app\Manifest.toml`
[no changes]
[ Info: PackageCompiler: creating base system image (incremental=false)...
[ Info: PackageCompiler: creating system image object file, this might take a while...
[ Info: PackageCompiler: creating system image object file, this might take a while...
julia>
It seems it made an application. However, I put the input1.txt file in the bin folder next to the exe file and in cmd I do the following.
D:\>cd "D:\Test_making_app_compiled\bin"
D:\Test_making_app_compiled\bin>Test_making_spp input1.txt 2
'Test_making_spp' is not recognized as an internal or external command,
operable program or batch file.
D:\Test_making_app_compiled\bin>Test_making_app input1.txt 2
ERROR: SystemError: opening file "D:\\Test_making_app_compiled\\bin\\Temp\\input.jl": No such file or directory
Stacktrace:
[1] systemerror(::String, ::Int32; extrainfo::Nothing) at .\error.jl:168
[2] #systemerror#50 at .\error.jl:167 [inlined]
[3] systemerror at .\error.jl:167 [inlined]
[4] open(::String; read::Nothing, write::Nothing, create::Nothing, truncate::Bool, append::Nothing) at .\iostream.jl:254
[5] open(::String, ::String) at .\iostream.jl:310
[6] julia_main() at D:\Test_making_app\src\Test_making_app.jl:10
[7] julia_main() at .\none:29
D:\Test_making_app_compiled\bin>
As you see it doesn’t make the input.jl file. There is no subfolder called “Temp” in bin folder as well. Instead I have a mysterious subfolder called “Tabriz”! I like this city, but I don’t remember using its name anywhere in the process I explained in details above
So what did I miss in the process or what am I doing wrong?
I also wonder why the application folder is so huge. It is 317 MB. I’m using only read and write, converting string to integer, simple addition and multiplication in the code.