Strange problem with JULIA_HOME and Cxx


#1

I just downloaded and installed the julia 1.0 binaries to /usr/local. The I tried to do a Pkg.add(“Cxx”).
The following is copied from my terminal, and shows that JULIA_HOME is defined in my environment (as are DATAROOTDIR and SYSCONFDIR). Something that Cxx is calling to initialize and build Cxx isn’t finding it. Can anyone give me an idea of where to look? BTW, I’m running on Fedora 28.

dave@vorpal ~]$ echo $JULIA_HOME
/usr/local/bin
[dave@vorpal ~]$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.0 (2018-08-08)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> using Pkg

julia> Pkg.add("Cxx")
   Cloning default registries into /home/dave/.julia/registries
   Cloning registry General from "https://github.com/JuliaRegistries/General.git"
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
 Resolving package versions...
 Installed Compat ─ v1.1.0
 Installed Cxx ──── v0.2.0
  Updating `~/.julia/environments/v1.0/Project.toml`
  [a0b5b9ef] + Cxx v0.2.0
  Updating `~/.julia/environments/v1.0/Manifest.toml`
  [34da2185] + Compat v1.1.0
  [a0b5b9ef] + Cxx v0.2.0
  [2a0f44e3] + Base64 
  [ade2ca70] + Dates 
  [8bb1440f] + DelimitedFiles 
  [8ba89e20] + Distributed 
  [b77e0a4c] + InteractiveUtils 
  [76f85450] + LibGit2 
  [8f399da3] + Libdl 
  [37e2e46d] + LinearAlgebra 
  [56ddb016] + Logging 
  [d6f4376e] + Markdown 
  [a63ad114] + Mmap 
  [44cfe95a] + Pkg 
  [de0858da] + Printf 
  [3fa0cd96] + REPL 
  [9a3f8284] + Random 
  [ea8e919c] + SHA 
  [9e88b42a] + Serialization 
  [1a1011a3] + SharedArrays 
  [6462fe0b] + Sockets 
  [2f01184e] + SparseArrays 
  [10745b16] + Statistics 
  [8dfed614] + Test 
  [cf7118a7] + UUIDs 
  [4ec0a83e] + Unicode 
  Building Cxx → `~/.julia/packages/Cxx/E2QsE/deps/build.log`
┌ Error: Error building `Cxx`: 
│ ERROR: LoadError: UndefVarError: JULIA_HOME not defined
│ Stacktrace:
│  [1] top-level scope at none:0
│  [2] include at ./boot.jl:317 [inlined]
│  [3] include_relative(::Module, ::String) at ./loading.jl:1038
│  [4] include(::Module, ::String) at ./sysimg.jl:29
│  [5] include(::String) at ./client.jl:388
│  [6] top-level scope at none:0
│ in expression starting at /home/dave/.julia/packages/Cxx/E2QsE/deps/build.jl:18
└ @ Pkg.Operations /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/Pkg/src/Operations.jl:1068

julia>


#2

Sadly the Cxx package has not been maintained, and cannot run on Julia 1.0, see here. The author of that package has been busy with his impressive work on the Julia compiler itself. In the meantime the best suggestion for C++ interoperability is CxxWrap.jl, which admittedly requires significantly more effort for creating wrappers.

As a long time C++ user I would very much like to see Cxx.jl working, but ironically I have had very little occassion to use C++ since I started using Julia, so I’m afraid I haven’t been any help myself. One of the barriers at the moment is that fixing Cxx.jl for Julia 1.0 requires some LLVM knowledge, which is somewhat rarer than simply having Julia + C++ knowledge.


#3

Thanks for the quick response. I was originally hoping to install OpenCV.jl, which uses Cxx.jl. I may take a look at using CxxWrap to interface to opencv.


#4

It has a bit of a threshold, but once you have the basics in place, it’s not hard. I would suggest splitting the c++ code for the bindings and the Julia code into separate repositories, that kind of simplifies the installation, because then you can just use BinaryBuilder. So, you’d make one repository to use BinaryBuilder to build opencv by itself, then another repo for the bindings, and then another repo for the julia code.
Sounds like a lot of hassle, but once the boiler plate code is in place, it’s really not that bad.


#5

If you only need a limited small subset of OpenCV functionality for personal use, maybe it’s a good idea to follow “hourglass-pattern”. Basically, you need a thin C89 wrapper for the C++ code, and then Julia wrapper can be generated using Clang.jl. But it looks like OpenCV does not provide up-to-date C APIs now, so you might need to manually write your own C89 wrapper.

I played around with this pattern a while ago, wrapping a small C++ lib. The lib didn’t provide a C89 wrapper, so I wrote one only exposing those APIs that I needed. Just as @jstrube mentioned above, I also used BinaryBuilder for auto-building. There are three repos: a hand written C89 wrapper, a auto-builder created by BinaryBuilder and a Julia wrapper generated by Clang. A big advantage of this pattern is the C89 APIs could also be easily interop-ed in C#, Python or other popular “production languages”. There is no fancy stuff here, just some trivial C wrapper code. However, It may not suit for big projects since writing the C89 wrapper is a bunch of boring work.


#6

Internally, this is sort of what CxxWrap does, it exposes C++ functions to the ccall interface, but it’s a lot easier than designing a C interface from scratch.


#7

Thanks for the input. I’m going to be off net for about six weeks soon, but after I get back, I’ll give that a shot. I happen to have been working on interfacing opencv with go, so I’ve got a good basis for automating a lot of the boring stuff.