How to see GraphViz output from Julia REPL? - julia

I'm trying to follow this tutorial which uses GraphViz to display a diagram. When running the first piece of code:
using Decapodes, Decapodes.Diagrams
using Catlab.Present, Catlab.Graphics
Variable = #decapode Decapodes2D begin
C::Form0{X}
end;
draw_equation(decapode) = to_graphviz(decapode, node_labels=true, prog="neato",
node_attrs=Dict(:shape=>"oval"),
graph_attrs=Dict(:nodesep=>"4.0"))
draw_equation(Variable)
I get the following output in the Julia REPL:
Catlab.Graphics.Graphviz.Graph("G", true, "neato", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node("n1", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => "C:Ω₀"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:nodesep => "4.0", :rankdir => "LR"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:height => "0.05", :margin => "0", :shape => "oval", :width => "0.05"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => "0.5"))
I expect the diagram to show up in another window, but no such window is created.
I'm running MacOS Monterey 12.4, Julia 1.7, and have GraphViz installed via Home-brew as well as the GraphViz.jl package. How can I view the diagram?

You need to use Graphviz to generate the image.
Assuming graphviz is in your system path you can do:
using Catlab
open("out.pdf","w") do f
write(f, Catlab.Graphics.Graphviz.run_graphviz(draw_equation(Variable);format="pdf"))
end

Related

How to specific a dictionary for a TOML file in Julia?

if I want to have a dictionary for entries in a TOML file, how can I set that up in Julia?
I want it to be something like:
["hello"]
world = Dict("z" => 25, "c" => 1)
Currently you can also use TOML module built into Pkg module without installing anything:
julia> using Pkg
julia> Pkg.TOML.print(Dict("hello" => Dict("world" => Dict("hellow" => "wurld"))))
[hello.world]
hellow = "wurld"
You can quite simply use TOML by doing the following:
add https://github.com/JuliaLang/TOML.jl.git in the package manager.
import TOML
TOML.print(Dict("hello" => Dict("world" => Dict("hellow" => "wurld"))))
which will output:
[hello.world]
hellow = "wurld"
See the TOML.jl for more info.

Typing pipe character prepends with backslash

I'm getting a weird and very annoying behavior in my terminal. When I type a protocol (i.e 'http:') then the pipe (|) character a backslash() is automatically inserted before the pipe character.
My test:
type 'htt'+'|' => 'ht|'
type 'htt:'+'|' => 'htt:|'
type 'http'+'|' => 'http|'
type 'http:'+'|' => 'http:\|'
type 'http://foo.com'+'|' => 'http://foo.com\|'
type 'curl http://foo.com'+'|' => 'curl http://foo.com\|'
type 'curl https://foo.com'+'|' => 'curl http://foo.com\|'
The same thing happens when I use 'ftp:' but not when I use 'telnet:'
Does anybody know what could be doing this?
This is my system:
OSX sierra
iTerm2 3.0.12
zsh 5.2 (x86_64-apple-darwin16.1.0)
pretzo (https://github.com/sorin-ionescu/prezto)

application is linking with both qt5 and qt4

I created a simple c++ library. Running ldd give
ldd libTESTPlugin.so.1.0.0 | grep -i qt
libQt5Widgets.so.5 => /lib64/libQt5Widgets.so.5 (0x00007f5345f14000)
libQt5Gui.so.5 => /lib64/libQt5Gui.so.5 (0x00007f5345a71000)
libQt5Core.so.5 => /lib64/libQt5Core.so.5 (0x00007f53455e7000)
libQtXml.so.4 => /lib64/libQtXml.so.4 (0x00007f5344074000)
libQtCore.so.4 => /lib64/libQtCore.so.4 (0x00007f5343b71000)
libQtGui.so.4 => /lib64/libQtGui.so.4 (0x00007f5342e4b000)
libQtNetwork.so.4 => /lib64/libQtNetwork.so.4 (0x00007f5342afa000)
libQtSvg.so.4 => /lib64/libQtSvg.so.4 (0x00007f53428a0000)
libQtWebKit.so.4 => /lib64/libQtWebKit.so.4 (0x00007f53403b3000)
libQtSql.so.4 => /lib64/libQtSql.so.4 (0x00007f5340170000)
libQtLocation.so.1 => /lib64/libQtLocation.so.1 (0x00007f5336a09000)
libQtSensors.so.1 => /lib64/libQtSensors.so.1 (0x00007f53367d5000)
libQtOpenGL.so.4 => /lib64/libQtOpenGL.so.4 (0x00007f5334ccb000)
libQtDeclarative.so.4 => /lib64/libQtDeclarative.so.4 (0x00007f5329d06000)
libQtScript.so.4 => /lib64/libQtScript.so.4 (0x00007f5329845000)
libQtXmlPatterns.so.4 => /lib64/libQtXmlPatterns.so.4 (0x00007f53291c0000)
so my lib is linked with both qt4 and qt5. It is giving me some integration issue with one other software which is linked with only qt5.
Is there a way to specify the linking only with Qt5 and NOT with Qt4?
Try to set Qt5 as default qt version using QT_SELECT environment variable:
export QT_SELECT = <Qt version>
For example:
export QT_SELECT = qt5
Also, if you are using Qt Creator, check again your build configuration.
PS:
I am not sure if they still include qtchooser, but you can try to run this command to list all installed versions on your system:
qtchooser -list-versions
Maybe you link with another lib also using Qt, like for example QWT. If you choose the wrong version of such lib it might load the wrong versions of dynamic Qt libs.
See https://stackoverflow.com/a/51282459/1328780 for a solution in case of QWT.

cocoapods dylib dependency use_frameworks

I have built a dynamic library (to add ICU support in this case) which i need to add as a dependency to a pod. For that I created a pod with the following podspec (I removed things like authors, license, ... to keep it short)
Pod::Spec.new do |s|
s.name = 'unicode'
s.version = '57.0'
s.source = { :git => "git#bitbucket.org:mycompany/unicode.git", :tag => "#{s.version}" }
s.requires_arc = false
s.platform = :ios, '8.0'
s.default_subspecs = 'all'
s.subspec 'all' do |ss|
ss.header_mappings_dir = 'icu4c/include'
ss.source_files = 'icu4c/include/**/*.h'
ss.public_header_files = 'icu4c/include/**/*.h'
ss.vendored_libraries = 'Frameworks/lib*.dylib'
end
end
Here i have a second pod where i need to link these libraries too
Pod::Spec.new do |s|
s.name = 'sqlite3'
s.version = '3.14.2'
s.summary = 'SQLite is an embedded SQL database engine'
s.documentation_url = 'https://sqlite.org/docs.html'
s.homepage = 'https://github.com/clemensg/sqlite3pod'
s.authors = { 'Clemens Gruber' => 'clemensgru#gmail.com' }
v = s.version.to_s.split('.')
archive_name = "sqlite-amalgamation-"+v[0]+v[1].rjust(2, '0')+v[2].rjust(2, '0')+"00"
#s.source = { :http => "https://www.sqlite.org/#{Time.now.year}/#{archive_name}.zip" }
s.source = { :git => "git#bitbucket.org:wrthphoenixspeedy/sqlite3.git", :tag => "#{s.version}" }
s.requires_arc = false
s.platform = :ios, '8.0'
s.default_subspecs = 'common'
s.subspec 'common' do |ss|
ss.source_files = "#{archive_name}/sqlite*.{h,c}"
ss.osx.pod_target_xcconfig = { 'OTHER_CFLAGS' => '$(inherited) -DHAVE_USLEEP=1' }
# Disable OS X / AFP locking code on mobile platforms (iOS, tvOS, watchOS)
sqlite_xcconfig_ios = { 'OTHER_CFLAGS' => '$(inherited) -DHAVE_USLEEP=1 -DSQLITE_ENABLE_LOCKING_STYLE=0' }
ss.ios.pod_target_xcconfig = sqlite_xcconfig_ios
ss.tvos.pod_target_xcconfig = sqlite_xcconfig_ios
ss.watchos.pod_target_xcconfig = sqlite_xcconfig_ios
end
# enable support for icu - International Components for Unicode
s.subspec 'icu' do |ss|
ss.dependency 'sqlite3/common'
ss.pod_target_xcconfig = { 'OTHER_CFLAGS' => '$(inherited) -DSQLITE_ENABLE_ICU=1' }
ss.dependency 'unicode', '57.0'
ss.libraries = 'icucore', 'icudata.57.1', 'icui18n.57.1', 'icuio.57.1', 'icule.57.1', 'iculx.57.1', 'icutu.57.1', 'icuuc.57.1'
end
end
And with these i am able to compile it. Cocoapods is copying these libraries on build time into the folder ../Frameworks/ rather than to do while on run time. Instead it fails because it says that it doesn't find the library in ../lib.
dyld: Library not loaded: ../lib/libicudata.57.1.dylib
Referenced from: /var/containers/Bundle/Application/9663CB3A-6ACD-487E-A92D-48F8AFE5260C/MyApp.app/MyApp
Reason: image not found
I have to use use_frameworks! because i am using some Swift frameworks too.
So i am doing something wrong... the question is, can i link a dylib from one pod to another pod? and if so... how?
Based on the disparity between "libs" and "Frameworks", this looks like an issue with either runpath search paths (the running app is not looking for the library from Frameworks), or with the install name of the library not matching the location where it's placed relative to where it is dynamically loaded from.
Make sure that in the app that bundles the dynamic library you have the following paths included in your "Runpath Search Path": #executable_path/../Frameworks, #loader_path/../Frameworks
Make sure that the "Dynamic Library Install Name" name of the library being loaded is set to the equivalent of #rpath/$(EXECUTABLE_PATH) (i.e. in your case it should be "#rpath/libicudata.57.1.dylib"). You can set it during build time using the -install_name compiler (linker?) flag, or with install_name_tool, like so: install_name_tool -id "#rpath/libicudata.57.1.dylib" libicudata.57.1.dylib . Hopefully doesn't come to this though.

Is there any way to build package dependency tree in julia-lang?

Using npm list will show a tree of installed packages, versions and relations:
Although Julia package management is differ (e.g normally no duplicate copy of a package exists), But is there any way to:
Know why one package have been installed?
or build a package dependency tree.
I don't think there's a simple function, but it shouldn't be too hard to do with these two functions:
julia> Pkg.dependents("Cairo")
10-element Array{AbstractString,1}:
"Tk"
"Gtk"
"Mamba"
"Drawing"
"GtkUtilities"
"ProfileView"
"Brim"
"Winston"
"EcologicalNetwork"
"VennEuler"
julia> Pkg.installed()
Dict{ASCIIString,VersionNumber} with 119 entries:
"Libz" => v"0.0.2"
"Gtk" => v"0.9.3"
"Interact" => v"0.3.0"
"ForwardDiff" => v"0.1.4"
"Benchmark" => v"0.1.0"
"AxisAlgorithms" => v"0.1.4"
"Cairo" => v"0.2.31+"
"HttpParser" => v"0.1.1"
"DataFrames" => v"0.6.10"
"Requests" => v"0.3.4"
"QuartzImageIO" => v"0.1.0+"
"Markdown" => v"0.3.0"
"Requires" => v"0.2.2"
"ArgParse" => v"0.3.0"
⋮ => ⋮
simple code bellow will printout the requires-by result for a package:
whorequires(pkgname) = whorequires(pkgname, 0);
function whorequires(pkgname, i)
deps = Pkg.dependents(pkgname);
[print('-') for j=1:i];
println(pkgname);
length(deps) > 0 && [whorequires(dep,i+1) for dep in deps];
end
julia> whorequires("JuliaParser");
JuliaParser
-CodeTools
--Atom
-ASTInterpreter
--Gallium
-Jewel
EDIT (to cover issue commented by #amrods)
whorequires(pkgname) = whorequires(pkgname, 0, Dict{ASCIIString,Vector{ASCIIString}}());
function whorequires(pkgname, i, m)
[print('-') for j=1:i];
if (haskey(m,pkgname))
println("$pkgname *[duplicated]* is required by ", length(m[pkgname]), " packages");
else
println(pkgname);
m[pkgname] = Pkg.dependents(pkgname);
if (length(m[pkgname]) > 0)
for dep in m[pkgname]
whorequires(dep,i+1,m);
end
end
end
end
There is a package, although not registered, which does this: https://github.com/peng1999/PkgDependency.jl
It's quite straightforward to use
pkg> add https://github.com/peng1999/PkgDependency.jl
julia> using PkgDependency
julia> PkgDependency.tree("HTTP")
HTTP v0.9.13
NetworkOptions v1.2.0
IniFile v0.5.0
URIs v1.3.0
MbedTLS v1.0.3
MbedTLS_jll v2.16.8+1
JLLWrappers v1.3.0
Preferences v1.2.2
TOML v1.0.3
Artifacts v1.3.0
It relies on a new (>1.4) experimental API, which can be used on its own to list (direct) dependencies, but it's quite ugly:
julia> using Pkg
julia> Pkg.dependencies()[Pkg.project().dependencies["HTTP"]].dependencies
Dict{String, Base.UUID} with 5 entries:
"Dates" => UUID("ade2ca70-3891-5945-98fb-dc099432e06a")
"Base64" => UUID("2a0f44e3-6c83-55bd-87e4-b1978d98bd5f")
"Sockets" => UUID("6462fe0b-24de-5631-8697-dd941f90decc")
"IniFile" => UUID("83e8ac13-25f8-5344-8a64-a9f2b223428f")
"MbedTLS" => UUID("739be429-bea8-5141-9913-cc70e7f3736d")
If you only want the list for dependencies of the currently active project, then Pkg.project().dependencies is enough.
I've opened a Pkg.jl issue to discuss this here.

Resources