Running ClojureScript: Unable to locate cljs/main.clj - clojure

Total rookie here. I am trying to run ClojureScript for the first time and followed the quickstart tutorial. However, upon entering...
clj --main cljs.main --compile hello-world.core --repl
I get the following error message:
Execution error (FileNotFoundException) at clojure.main/main (main.java:40).
FileNotFoundException: Could not locate cljs/main__init.class or cljs/main.clj on classpath.

It can’t find the cljs.main in the Clojurescript jar. As the QuickStart mentions, you need a deps.edn for Mac/Linux or the cljs.jar for Windows.

This error surfaces when one runs clj --main cljs.main --compile hello-world.core --repl from directory or path which does not have file deps.end or cljs.jar.
Considering the directory structure at https://clojurescript.org/guides/quick-start,
hello-world #### Run that command in this directory
├─ src
│ └─ hello_world
│ └─ core.cljs
├─ cljs.jar
└─ deps.edn

Make sure you are in the hello-world project directory and run the following command....
Docs are wrong, run the command on the root where deps.edn exist

I'm not sure about your specific error, but I created a CLJS sample project that will get you started:
https://github.com/cloojure/cljs-base-project
Just clone the repo to your computer, then you can run the Doo unit tests:
> lein clean; lein doo chrome test once
or use Figwheel:
> lein clean; lein figwheel

Just happened to me in a Linux box, even though I had the correct deps.edn as mentioned in the quickstart.
The solution was to simply remove a previously created .cpcache folder that I had from trying with a different docker image.

Related

How to build cv2 binding

I have followed the opencv doc for creating my own bindings.
I run the file gen2.py which generated some header files:
./
../
pyopencv_generated_enums.h
pyopencv_generated_funcs.h
pyopencv_generated_include.h
pyopencv_generated_modules_content.h
pyopencv_generated_modules.h
pyopencv_generated_types_content.h
pyopencv_generated_types.h
pyopencv_signatures.json
How should I build this?
I tried running cmake CMakeLists.txt directly in /opencv/modules/python but some defines were not found.
and I tried on re-building running cmake CMakeLists.txt in /opencv/ , where I got:
FATAL: In-source builds are not allowed.
You should create a separate directory for build files.
I think both approaches were quite wrong, but I haven't found any doc explaining how to build using the generated headers.
I'm using opencv 4.5.5 which I cloned and built.
EDIT
I found this in /source/opencv/modules/python/bindings/CMakeLists.txt:
string(REPLACE ";" "\n" opencv_hdrs_ "${opencv_hdrs}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs_}")
add_custom_command(
OUTPUT ${cv2_generated_files}
COMMAND "${PYTHON_DEFAULT_EXECUTABLE}" "${PYTHON_SOURCE_DIR}/src2/gen2.py" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/headers.txt"
DEPENDS "${PYTHON_SOURCE_DIR}/src2/gen2.py"
"${PYTHON_SOURCE_DIR}/src2/hdr_parser.py"
# not a real build dependency (file(WRITE) result): ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
${opencv_hdrs}
COMMENT "Generate files for Python bindings and documentation"
)
I guess I have to add the path to my headers in ${CMAKE_CURRENT_BINARY_DIR}/headers.txt just not sure how to get the value of CMAKE_CURRENT_BINARY_DIR
EDIT 2
As proposed by #berak, I tried CMAKE_EXTRA_MODULES_PATH=my/path
this seems to get me really close to what I need.
It compiles my sources and generates the .so files as libopencv_xxx.so and saves them in my /usr/local/lib
(when running nm on it I see my class and method)
BUT! when I import cv2 in a script I don't achieve to load my module.
I tried print(cv2.__dict__) and greped on it, but it's not there.
Any clue on how to add the compiled modules into my python-opencv installation?
There's not much documentation on how to create a bind (at least I only found this, which is very helpful but doesn't have all the information).
First, your module must use the following tree structure (I did everything with cmake):
.
src
└── modules
└── your_module
├── CMakeLists.txt
├── include
│   └── opencv2
│   └── your_module_bind_lib.hpp
└── src
└── your_module_bind_lib.cpp
An example of my CMakeLists.txt (this of course may change according to your project):
set(the_description "yourModule LIB")
ocv_define_module(your_module opencv_imgproc WRAP python)
include_directories(${OpenCV_INCLUDE_DIRS})
Then I cloned OpenCV with
git clone https://github.com/opencv/opencv.git
Make a build folder
mkdir wherever/build
And run the following command for cmake
cd wherever/build
cmake -DOPENCV_EXTRA_MODULES_PATH=/project_from_previous_tree/src/modules/ -D BUILD_EXAMPLES=OFF -D BUILD_opencv_apps=OFF -D BUILD_DOCS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D CMAKE_INSTALL_PREFIX=/usr/local/ your_opencv_location/opencv/
make -j8
make install
In that command the only "special" thing was DOPENCV_EXTRA_MODULES_PATH (thanks to #berak for the idea).
And then? what happens in python level?
Make sure your python installation actually points to the built opencv, or use something like:
import sys
sys.path.append('/usr/local/lib/python3.8/site-packages/cv2/python-3.8')
import cv2
where /usr/local/lib/python3.8/site-packages/cv2/python-3.8' is where the generated .so is located in my PC.
With this you will be able to use things like
cv2.my_cpp_function()
cv2.my_cpp_class.some_method()
...
Where my_cpp stuff was declared and defined in the module project following the doc and can "easily" have OpenCV typed objects as parameters.
Et voila, now you can use your c++ functions in python.
Notice that this solution does not do any modification to the opencv directory cloned from Git.
You're not supposed to run gen2.py manually, cmake will do this for you at some stage, internally.
since you seem to be on some linux, rather follow the build steps here, this will also generate python bindings, the gist of it is:
make a special "build folder" and cd into it (dont try to build in the src folder, you'll never be able to clean anything up)
run cmake <some args> path_to_src_folder (or better even - cmake-gui) , check if python3 shows up in the "To be build" section of the output
run make install

How do I create a Clojure application with lein uberjar if I have a dependency in checkouts?

I have a Clojure application that is using a library which is symlinked from inside the "checkouts" directory.
This lets me work on both the app and the library at the same time. And lein knows how to compile and run the program without any problems.
But I want to make a standalone with lein uberjar, and it's complaining
Caused by: java.io.FileNotFoundException: Could not locate mylib/core__init.class, mylib/core.clj or mylib/core.cljc on classpath.
I assume that that is because mylib isn't mentioned in my project.clj file. It isn't, precisely because I want to use the version of mylib symlinked inside "checkouts".
But the uberjar command doesn't seem to be able to see it.
How can I solve this?
You can accomplish this by installing mylib in your local repository (~/.m2/repository).
Run lein install in the dependent project to install it in your local repository.
Add the project to :dependencies: in project.clj:
[mylib "version"]
Run lein uberjar in the main project.
The project will find the jar in your local repository.
/Edit
If you want to develop two libraries at the same time you can use a checkouts folder where checkouts contains a symlink to the dependent library.
mkdir checkouts
ln -nfs full-path-other-lib-dir full-path-checkouts-dir
Now changes in other-lib are immediately available in the main project.
See [https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies](the Leiningen checkouts documentation).
OK, it appears that the "checkouts" feature of lein works with lein test and lein run but not with lein uberjar.
I added the following to the local source code of a lib tupelo.core:
(def dummy-sample-data "Bogus!")
In the consuming project demo.core we can access the new Var:
(ns demo.core
(:use tupelo.core tupelo.test))
(defn -main [& args]
(println :foo-enter)
(spyx dummy-sample-data)
(println :foo-leave))
lein run produces:
:foo-enter
dummy-sample-data => "Bogus!"
:foo-leave
project.clj remains unchanged:
(defproject demo "0.1.0-SNAPSHOT"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [
[criterium "0.4.5"]
[org.clojure/math.combinatorics "0.1.6"]
[org.clojure/clojure "1.10.1"]
[prismatic/schema "1.1.12"]
[tupelo "0.9.201"]
<snip>
where "0.9.201" is the latest version of tupelo on Clojars. Checkouts looks like:
~/expr/demo > ls -ldF checkouts/*
lrwxrwxrwx 1 alan alan 17 May 12 13:57 checkouts/tupelo -> /home/alan/tupelo/
but uberjar fails:
~/expr/demo > lein clean ; lein uberjar
Compiling demo.core
Syntax error compiling at (demo/core.clj:6:3).
Syntax error compiling at (demo/core.clj:6:3).
Unable to resolve symbol: dummy-sample-data in this context
Full report at:
/tmp/clojure-10416346559924917196.edn
Compilation failed: Subprocess failed
Options
If you are wanting to deploy an application, you have 2 options:
If the lib exists on Clojars or Maven, you should probably deploy a release there before making a uberjar. If the lib is not ready for Clojars or Maven, maybe you aren't ready to use it in a uberjar...?
Simply copy the source tree of mylib (or use a symlink!) under the ./src dir in your project. You'll also have to copy in the dependencies into myproj/project.clj. You are effectively merging myproj and mylib, at least temporarily with this approach. If the are coupled tightly enough to require co-development, perhaps it should be a permanent merge?

How to AOT compile a single clojure file using clj tool? (without deps.edn file)

Let's say I have the following file:
hello/core.clj:
(ns hello.core)
(println "Hello")
Is it possible to AOT compile this file to classfiles using a clj tool without using any "project"-like setup? I've tried something like this:
$ clj -e '(compile "hello/core")'
but am getting an error about unability to locate hello/core.clj file.
Looks like clj's default expectation is for source files to be under src directory (from the guide):
By default, the clj tool will look for source files in the src directory, so create the src directory and declare your program at src/hello.clj
And for compile to work, *compile-path* (defaults to "classes") must also exist:
$ mkdir classes
$ tree
.
├── classes
└── src
└── hello
└── core.clj
$ test clj -e "(compile 'hello.core)"
Hello
hello.core
Then your class files should be in classes directory.

Leiningen 2 does not look in localrepo?

I'm using Leiningen 2 and am struggling to get it to recognize the local repository ($HOME/.m2)
I'm trying to use the storm-rdbms(storm-contrib) which is not on clojar
Here are the steps I've taken:
Using the lein-localrepo plugin, installed storm-rdbms under the .m2 local repository
The pom.xml shows this:
<groupId>storm-rdbms</groupId>
<artifactId>storm-rdbms</artifactId>
<versioning>
<versions>
<version>0.1-SNAPSHOT</version>
</versions>
<lastUpdated>20130214173431</lastUpdated>
</versioning>
my project.clj file :
:dependencies [[org.clojure/clojure "1.4.0"]
[storm "0.8.2"]
[storm-rdbms "0.1-SNAPSHOT"]]
:plugins [[lein-localrepo "0.4.1"]]
:repositories {"local" ~(str (.toURI (java.io.File. "~/.m2")))})
I run lein deps:
Could not find artifact storm-rdbms:storm-rdbms:jar:0.1-SNAPSHOT
This could be due to a typo in :dependencies or network issues.
Could not resolve dependencies
I've tried this with Maven as well, but Maven 3 is not even able to install the jar when following the directions from here.
Please shed some light on what I'm doing wrong here. Thanks so much!
when you run mvn install, storm-rdbms seems not to ?properly? install a pom when it installs the jar, which was preventing lein from finding it.
here are the full steps I used:
git clone git://github.com/nathanmarz/storm-contrib.git
cd storm-contrib/storm-rdbms/
mvn install
cp pom.xml ~/.m2/repository/storm/storm-rdbms/0.1-SNAPSHOT/storm-rdbms.pom
cd ~/my-storm-project
emacs project.clj and add this dep:
[storm/storm-rdbms "0.1-SNAPSHOT"]
lein deps
I'm not sure if this is because it's a sub project. I was unable to build the parent project because one of the other sub-projects was broken when I checked it out...

Clojure & ZeroMQ

Can anyone tell me some working dependencies to get up and running with zeromq and clojure?
I've tried several but leiningen isn't able to fetch them:
(Could not find artifact org.zmq:zmq:jar:2.1.0 in central (http://repo1.maven.org/maven2))
[org.zmq/zmq "2.1.0"]
[org.zmq/jzmq "1.0.0"]
I have compiled jzmq (/usr/local/share/java/jzmq.jar) and added this to my project.clj:
:native-path "/usr/local/lib"
There's a 2.0-SNAPSHOT here:
Lein should already have the clojars repo loaded.
What I propose is a mixture of what's already been proposed, but for the sake of completeness and hopefully to give a final answer I give it a try.
Since the dependency is not in the online repos I would include the jar(s) in the project's directory structure itself, e.g. in the directory repository and keep it in the source control system as the other files of the project. It's an important part of the project and without the dependency it won't run.
In this directory I would save the jar with the help of Maven Install plugin.
mvn install:install-file \
-Dfile=/usr/local/share/java/jzmq.jar \
-DgroupId=org.zeromq \
-DartifactId=jzmq \
-Dversion=2.1.0 \
-Dpackaging=jar \
-DlocalRepositoryPath=repository
When the jar file gets copied to the local repository, you define it and the dependency in project.clj as follows:
(defproject clojure-interal-repo-test "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.4.0"]
[org.zeromq/jzmq "2.1.0"]]
:repositories [["zeromq-repository" {:url "file:repository"
:snapshots false
:checksum :ignore
:update :never}]])
Within the project, run lein2 deps :tree to verify its correctness.
$ lein2 deps :tree
Retrieving org/zeromq/jzmq/2.1.0/jzmq-2.1.0.jar (4k) from file:repository/
[org.clojure/clojure "1.4.0"]
[org.zeromq/jzmq "2.1.0"]
Please note that the 4k above is the size of a fake file I created to test it out.
Read the document Repeatability in Leiningen's wiki should you need a bit more.
The only way I could get it to work was to use jeromq.
[org.zeromq/jeromq "0.3.2"]
Jeromq is native Java.
You can create a Maven local repository, install the compiled library into your local repo, and then, add the following to your project.clj
:repositories {"local" ~(str (.toURI (java.io.File. "your_local_repository_path")))}
Similar question, I have answered earlier here
Unfortunately, ZeroMQ is not present in public repository, at least at the last time I checked (a month ago I think). So you have to install the jar manually:
mvn install:install-file -Dfile=/usr/local/share/java/jzmq.jar -DgroupId=org.zeromq \
-DartifactId=jzmq -Dversion=2.1.0 -Dpackaging=jar
Then you can use the artifact as [org.zeromq/jzmq "2.1.0"] in your project.clj.