Merlin complains about a missing module in the same project - emacs

I am new to Ocaml and just setting up my dev environment with emacs, merlin and flycheck. Everything works more or less expected except one thing : merlin doesn't seem to be able recognise the dependencies between the modules in the same project.
e.g. I have a test project with two modules: main.ml and awesome.ml.
here is my main.ml which references the second module awesome.ml
(* main.ml *)
open Core
module A = Awesome
let _ =
Printf.printf "hello \n Converted to string we get: %s\n"
(A.str_of_t (A.succ A.one_t));
here is awesome.ml:
(* awesome.ml *)
type t = int
let one_t = 1
let succ i = i + 1
let str_of_t = string_of_int
when I send main.ml buffer to evaluate into utop with utop-eval-buffer function, I am getting an error: "Error: Unbound module Awesome"
I have .merlin in the root of the project which has S instruction.
I know it is found by merlin as it doesn't complain about "open Core"
S src
PKG core lwt ounit
B _build/src
B +threads
here is my _tags:
<src/**>: include
<src/**>: package(oUnit), package(core)
true:thread
the regular project compilation with ocamlbuild works fine, no errors.
here is Makefile
## Makefile
default: main
main: main.native
test: test.native
%.native:
ocamlbuild -use-ocamlfind $#
mv $# $*
.PHONY: test default
any ideas why Awesome module is not recognised in utop or this is expected behaviour?

Merlin will see other modules once you have compiled them (in fact, once you have compiled its interfaces). So given your .merlin is correct it will see everything after you run compilation. Your files should indeed be in a src folder, i.e., your project layout, based on your .merlin file should look like this:
Makefile
.merlin
src/
awesome.ml
main.ml
This is not a required layout, but this is the one, that you described to Merlin. The reason, why I suspect that it is not the same, is your Makefile.
P.S. Just as a side note, there is a small issue in your code: you should open Core.Std not Core.

As Ivan's answer pointed out, Merlin can only recognize a module in your project after you compile it. If Merlin is giving you an unbound module Foo error, one solution is to run
ocamlbuild foo.cmi

I had the same problem. I tried installing merlin through opam or sources, but I couldn't solve this problem until I put the ".merlin" file in to the \src directory--not at the root-- with a "REC" tag in it.

Related

Coq error: The reference evenb was not found in the current environment

I'm trying to go through the Software Foundations Coq book (http://www.cis.upenn.edu/~bcpierce/sf/current/toc.html), but when I compile Induction.v (which looks like http://www.cs.uml.edu/~rhenniga/coq/sf_induction.html), I get the error message "Error: The reference evenb was not found in the current environment." -- even after compilation of Basics.v. Any ideas why?
I can confirm that opening CoqIDE from the same directory works on macOS: cd <sf-dir>; /Applications/CoqIDE_8.5.app/Contents/MacOS/coqide
from: The reference "X" was not found in the current environment
Try to erase every blank character in the address related to Coq or software-foundation book.
In my case, when I struggled with the file
C:\Users\XxX\Documents\software foundation\lf\Induction.v
, CoqIDE failed to execute From LF Require Export Basics and to define evenb_S theorem. Also, I couldn't see any files like Basics.vo or Basics.glob created when Basics.v with [Compile] - [Compile buffer] function in CoqIDE.
Everything works fine when I change my folder name to
C:\Users\XxX\Documents\softwarefoundation\lf\Basic.v
The Coq installer had already informed this >>
Link to the screenshot image of Coq setup
Compiling Basic.v with coqc Basics.v command should produce Basic.vo and Basic.glob files in the same directory. Then you should be fine with compiling Induction.v in the same directory as well; coqc Induction.v.

Coq: manage LoadPath in project with subdirectories

I have a Coq project with its libraries organised into subdirectories, something like:
…/MyProj/Auxiliary/Aux.v
…/MyProj/Main/Main.v (imports Auxiliary/Aux.v)
When I compile the files, I expect to do so from working directory MyProj (via a makefile). But I also want to work on the files using Proof General/Coqtop, in which case the working directory is by default the directory in which the file lives.
But this means that the LoadPath is different between the two contexts, and so the logical path needed for the library import is different. How do I set up the coqc invocation, the LoadPath, and the import declarations so that they work in both contexts?
Each approach I have tried, something goes wrong. For instance, if I compile Aux.v by invoking
coqc -R "." "MyProj" Auxiliary/Aux.v
and import it in Main.v as
Require Import MyProj.Auxiliary.Aux.
then this works when I compile Main.v with
coqc -R "." "MyProj" Main/Main.v
but fails in Coqtop, with Error: Cannot find library MyProj.Auxiliary.Aux in loadpath. On the other hand, if before the Require Import I add
Add LoadPath ".." as MyProj.
then this works in Coqtop, but fails under coqc -R "." "MyProj" Main/Main.v, with
Error: The file […]/MyProj/Auxiliary/Aux.vo contains library
MyProj.Auxiliary.Aux and not library MyProj.MyProj.Auxiliary.Aux
I’m looking for a solution that’s robust for a library that’s shared with collaborators (and hopefully eventually with users), so in particular it can’t use absolute file paths. The best I have found for now is to add emacs local variables to set the LoadPath up when Proof General invokes Coqtop:
((coq-mode . ((coq-prog-args . ("-R" ".." "MyProj" "-emacs")))))
but this (a) seems a little hacky, and (b) only works for Proof General, not in Coqide or plain Coqtop. Is there a better solution?
Allow me to side-step your question by suggesting an alternative process, hinted at by Tiago.
Assuming that your project's tree looks like this:
MyProj/Auxiliary/Aux.v
MyProj/Main/Main.v
In MyProj, write a _CoqProject file listing all your Coq files
-R . ProjectName
Auxiliary/Aux.v
Main/Main.v
When you open one of these Coq files, emacs will look for the _CoqProject and do-the-right-thing (tm).
As shown by Tiago, coq_makefile will also give you a Makefile for free.
I know you explicitly asked for something that works across different platforms, but there's already a Proof-General-specific solution that is less hacky than the one you have. Proof General has a special variable called coq-load-path that you can set with local variables, much like you did for coq-prog-args. The advantage is that you don't have to worry about any other arguments that need to be passed to coqtop (such as -emacs in your example). Thus, your .dir-locals.el file could have a line like this:
((coq-mode . ((coq-load-path . ((".." "MyProj"))))))
Unfortunately, I am not aware of anything that works across platforms, although I'm pretty sure that something specific for CoqIDE must exist. If this is the case, maybe you could set up a script to keep these configuration files updated across different platforms?
If you use coq_makefile you can install the library in your system.
Without OPAM
To initialize your project:
coq_makefile -f _CoqProject -o Makefile
Share your library with other projects:
make install
With OPAM
Assuming you have OPAM installed, you can use coq-shell to help you take care of dependencies.
To setup your project:
coq_shell_url="https://raw.githubusercontent.com/gares/opam-coq-shell/master/src/opam-coq"
curl -s "${coq_shell_url}" | bash /dev/stdin init 8.4 # Install Coq and its dependencies
eval `opam config env --switch=coq-shell-8.4` # Setup the environment
coq_makefile -f _CoqProject -o Makefile # Generates the makefile
opam pin add coq:YOURLIBRARY . # Add your library to OPAM
When you update your library you should do:
opam upgrade coq:YOURLIBRARY
Here is an example of a project that uses the OPAM method:
https://bitbucket.org/cogumbreiro/aniceto-coq/src

How to create a GTK plugin (cmxs) for my OCaml program

I'd like to make a GTK plugin for my OCaml application, loaded using Dynlink. How can I get ocamlbuild to include the lablgtk2 library in the generated plugin?
As a test, I have main.ml:
let () =
try
Dynlink.loadfile "_build/gtk_plugin.cmxs"
with Dynlink.Error err ->
failwith (Dynlink.error_message err)
gtk_plugin.ml:
let () =
print_endline "GTK plugin loaded!";
GMain.Main.main ()
_tags:
<main.*>: package(dynlink)
<gtk_plugin.*>: package(lablgtk2)
But I get:
$ ocamlbuild -use-ocamlfind main.native gtk_plugin.cmxs
$ ./main.native
Fatal error: exception Failure("error loading shared library:
.../_build/gtk_plugin.cmxs: undefined symbol: camlGtkMain")
Note: the main binary must not depend on libgtk (which might not be installed on the target system) - if the plugin fails to load I want to fall back to console mode.
You need to
add the linkall flag to main, otherwise it will remove parts of the OCaml runtime that will later be needed by dynamic plugins
compile the gtk_plugin.cmxs file with option -lflag lablgtk.cma (which I deduced from seeing in the _log that this option was not passed)
The way ocamlbuild deduces .cmxs dependencies is not optimal right now, and it's hard because different users may want different things (minimal plugins assuming libs are present, or on the contrary portable statically linked stuff). For modules coming from your project you can write a foo.mldylib file to be explicit about what you want excluded, but I don't know whether it's possible to include "all modules of this external library".
Note that it is also possible to distribute lablgtk.cmxs and the relevant .cmi along with your plugin, and load it dynamically first.
mkdir lablgtk
cp `ocamlfind query lablgtk2`/lablgtk.cmxs lablgtk
cp `ocamlfind query lablgtk2`/*.cmi lablgtk
echo "\"lablgtk\": not_hygienic" >> _tags
then in your main.ml
let () =
try
Dynlink.loadfile "lablgtk/lablgtk.cmxs";
Dynlink.loadfile "_build/gtk_plugin.cmxs"
...

re: Java package declaration: Netbeans says: ‘Incorrect Package’

orig post:
Hello List,
I am new to Java, Netbeans, and the IB Java API.
I downloaded the IB Java API software and I am using Netbeans to look at it.
On one of the files, Netbeans is indicating a problem with the file.
At the very top of the file, the author has placed a package declaration:
package samples.rfq;
Netbeans is using a red-dot to the left of the package declaration to tell me that it has a problem with the package declaration.
When I mouse-hover the package declaration, Netbeans tells me this:
Incorrect Package (Alt-Enter shows hints)
On my Mac-keyboard I press Alt-Enter and Netbeans just interprets that as an Enter (and then I need to undo that Enter).
I have 2 questions:
How do I work around the Alt-Enter-bug to see the hints?
What do you typically do when Netbeans indicates 'Incorrect Package' on one of your package declarations?
My comment to Josefx:
josefx,
I think maybe you gave me a good clue.
I looked at the file and I see it here in the (Linux) file system:
a#z2:/pt/z2/api$
a#z2:/pt/z2/api$ ls -la /pt/z2/api/samples/rfq/SampleRfq.java
-rw-r--r-- 1 a a 14475 2008-08-13 15:49 /pt/z2/api/samples/rfq/SampleRfq.java
a#z2:/pt/z2/api$
a#z2:/pt/z2/api$
a#z2:/pt/z2/api$
a#z2:/pt/z2/api$ grep package /pt/z2/api/samples/rfq/SampleRfq.java
package samples.rfq;
a#z2:/pt/z2/api$
So obviously it is in a directory which matches its package declaration.
I tried running javac against the file from a variety of directories.
This works:
cd /pt/z2/api/
javac samples/rfq/SampleRfq.java
If I run javac from any other directory it fails.
So, I see a dependency between 3 things here:
Location of the SampleRfq.java
Syntax in the package declaration
Location of the javac command
Since I got javac to work, I'm convinced of 2 things:
SampleRfq.java is in the correct directory
Syntax in the package declaration is correct
So, it looks like my issue is with Netbeans.
Netbeans is too ... 'stupid' to know that:
SampleRfq.java is in the correct directory
Syntax in the package declaration is correct
How do I help Netbeans?
I posted a question to the Netbeans mail-list and the only answer I got was: "Fix the incorrect file name".
ok,
I got the error to evaporate.
steps:
abandon my netbeans project
rsync my code to a new directory; create new NB project; (NB will not let me use old code)
right-click-project: select properties
Add folder
Pick the parent of the directory corresponding to the package
Netbeans now "knows" that the package declaration matches the directory structure.

What is the difference between building C++ Builder project from IDE and command line?

I have different behaviour of compiler, when building project from IDE and from command-line, which I can not explain.
The detailed issue's description is rather big, but it's really simple.
I have a C++ Builder project, which has a PAS-file included (IncludeUnits.pas). This pas-file has several units and inc-files listed. These files are located in separate folders and these folders are listed in library&include paths in project's options.
Folders layout:
C:\Demo\Bin
C:\Demo\Project
C:\Demo\Project\CBuilder5
C:\Demo\Project\Common
C:\Demo\Source
C:\Demo\Source\Common
Bin is output folder, Project/CBuilder5 holds project (bpr-file), Project/Common holds included pas-file (IncludeUnits.pas), Source and Source/Common hold other files (pas&inc). I think that it's pretty usual layout.
C:\Demo\Project\Common\ IncludeUnits.pas :
unit IncludeUnits;
interface
uses
Test;
implementation
end.
C:\Demo\Source\ Test.pas :
unit Test;
interface
{$I Test.inc}
implementation
end.
C:\Demo\Source\Common\ Test.inc :
// this file is empty
If I compile this project from C++ Builder IDE - it will compile fine. C++ Builder IDE doesn't have any additional paths in IDE settings set.
Now, I want to compile it from command-line. First, I issue
bpr2mak.exe MyProject.bpr
command.
This command creates MyProject.mak file, where I can see all paths ("....\Source" and "....\Source\Common" are the paths in question):
...
INCLUDEPATH = $(BCB)\include;$(BCB)\include\vcl;..\Common;..\..\Source;..\..\Source\Common
LIBPATH = $(BCB)\lib\obj;$(BCB)\lib;..\Common;..\..\Source;..\..\Source\Common
...
Now, I run make command:
make.exe -B -f"MyProject.mak"
It gives me the following output:
C:\PROGRA~1\Borland\CBUILD~2\BIN\dcc32 -N2....\Bin -N0....\Bin -$Y+ -$W -$R -v -JPHNE -M -UC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common -D_DEBUG;_RTLDLL;NO_STRICT -OC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common --BCB ..\Common\IncludeUnits.PAS
Borland Delphi Version 13.0 Copyright (c) 1983,99 Inprise Corporation
C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(6) C:\Demo\Source\Test.pas(1) C:\Demo\Source\Test.pas(5) Fatal: File not found: 'Test.inc'
As you can see - all search path is passed to compiler and the file (Test.inc) is all here - in that Source\Common folder. But still compiler can't find it?
Of course, I run both commands from folder with bpr-file. And changing paths to absolute doesn't help.
Copying Test.inc from Source\Common to Source will help. Changing {$I Test.inc} to {$I Common\Test.inc} will also help.
Why? It seems that I'm missing something. Remember: project have no problems with compiling from IDE, Test.inc is found without copying or changing declaration. Did I miss some switch to make or dcc32?
I found the reason: command line for dcc32 misses -I switch, which specifies paths for include files.
For some reason, bpr2mak doesn't respect this option. Fortunately, it allows you to specify alternate template for conversion bpr -> mak. I edited default template and added "-I" option to it, pass new template to bpr2mak - and it worked.