Handle parallel build error correctly in emacs compilation mode - emacs

When I'm using M-x compile to do parallel compilation with make -jn for a multi (level) dir project, when I got an error, I can't get to the correct place with next-error stuff. Emacs always goes to wrong directory for the problematic file. But I have no problem if I just do it without -jn.

next-error uses the text output of your compilation to determine where to go. But with parallel compilation, this text output can be corrupted, and even if it is not corrupted it can and often is ambiguous (think of one task compiling foo/bar and the other task compiling toto/titi, and the output looking like "entering directory foo; entering directory toto; error in bar:20; error in titi:69").
I can only think of the following ways to solve this problem:
structure your make files so that you never change directory (so all the file names are relative to the same current working directory).
change your make files so as to pass absolute file names to your compiler, so all the file names in error messages are absolute.
hack Emacs's compile.el so that when looking for "bar", it fetches it in all the directories that have been mentioned before.
This last change would probably be a good one (i.e. patch welcome), but note that it would still bump into problems if "bar" exists in both "foo" and "toto".
The other two changes can also still bump into problems because the output can also end up looking like "Entering directory foEntering directory toto; o;"; and I don't know what can be done to avoid this problem.

Related

Running a Matlab p-file coded for Windows on a MacOS

I have several Windows sourced p-files internally coded with the '\' file separator that I want to run on Matlab under macOS.
I get errors caused by the '\' because macOS uses '/'.
eg The pfile tries to call a file named "model\xyz' which causes a warning:
"Name is nonexistent or not a directory: model\ "
1) Is there code that I might insert somewhere to recognise the 'model\' call from the pcode file and change it to 'model/' before it is used by MATLAB addpath?
2) Is there a generic fix I could apply to the addpath code?
3) Or better still is there a way to modify the Windows p-file without access to its source code so that it will run under macOS?
There are several things you can do (none of which are particularly easy; listed here in increasing order of how nasty I think they are):
Contact the author of the code and ask them to fix it.
Install an older MATLAB version (R2007b <= ver < R2015b, I think) which allowed debugging (stepping into) p-files within MATLAB, then, assuming that there is some line in the original source code that does
filepath = ['model' '\' 'xyz.m'];
step until you see filepath appear in the workspace (having the wrong path in it), then simply edit the value to the correct path, and hope for the best.
(Essentially the same idea as before, but on newer MATLAB versions, VERY DIFFICULT to pull off) Obtain an external debugger, attach to the MATLAB process, run the p-file and scan the memory for the contents of filepath. When you discover it, change the value to the correct path and detach/disable the debugger.
If this code relies on some external (and open source) function to get (or use) the path, you can modify its behavior to output the string you want. This requires some knowledge about the source code.
Find/make a tool for decoding p-files and fix the resulting source code yourself.
For completeness I describe how my problem was solved:
As suggested by Dev-iL I was eventually able to locate the author and he modified his code. This is the best solution but it took some time and is not always possible.
Based on: https://au.mathworks.com/matlabcentral/answers/117110-dealing-with-and-windows-vs-unix-for-path-definition I located a module (I've forgotten its name) within the Matlab package which handles file calls and intercepted all incoming file path names containing the '\' Windows separator, and replaced them with the always acceptable '/'. This quick and dirty fix worked until solution 1. was obtained.
Thanks to all who responded so quickly to this question.

How to produce a .js file from a haskell source file with haste?

So I noticed, while answering this question, that the one who asked the question appears to be a javascript developer. And as the code I wrote in haskell is easy enough, I thought I give haste a try and try to compile it to javascript.
So, I downloaded the Windows binary package of haste (why does the .msi require a reboot?!!?), added it to my path, issued haste-cabal update and haste-cabal install split and after a bit of reading the output of hastec --help, I issued:
PS E:\h\stackoverflow> hastec -o hexagon.js --pretty-print hexagon.hs
as my best guess on how to get the output I am looking for.
Opposite to my expectation, haste output was this:
hastec.exe: user error (shell expression failed in readModule: Data.Binary.Get.runGet at position 8: not enough bytes)
So, my question: What do I have to do to get a java script source file?
Is it possible that you have an old version of Haste lying around, or have intermediate files (.jsmod, for instance) from a different version of the compiler in your source directory? This sounds like the (quite unhelpful) error message Haste produces when it runs into a corrupted intermediate file.
Check that the version of the binary you're calling is what you expect (hastec --version). Then, try getting rid of all intermediate files in the directory as well as any files in %USERPROFILE%\AppData\Roaming\haste, reinstalling split, and recompiling with the -fforce-recomp flag. You should also add a main function, so that Haste has an entry point to your program from which to start linking. If all you want to do is to make some Haskell function available to external JavaScript, you can use the export foreign function interface:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Haste.Foreign
import Hexagon
main = export "picture" Hexagon.picture
You will probably also want to compile your program with the --onexec flag, to make sure that main runs and exports picture immediately when loaded, and not on page load which is the default:
> hastec -o hexagon.js --pretty-print --onexec hexagon.hs
After doing this, any code included after hexagon.js will be able to call e.g. Haste.picture(5); in order to produce a picture of size 5.
(Re: MSI installer requiring a reboot, this is required since it adds the Haste binaries to your %PATH%, which does not take effect immediately. I assume that a re-login would be enough to make it take effect, however.)

How to import files relative to main file, instead of current directory? ((Chez) Scheme)

For example, in my main.scm file I have (load "util.scm"). util.scm is a file in the same folder as main.scm. Both files are located in ~/documents/myproject/.
Now when I'm in this directory, and I run $ chez-scheme main.scm everything works fine. However, if I'm in my home directory and run $chez-scheme documents/myproject/main.scm it complains, not being able to find the file util.scm. I suppose this is the case because the current directory was my relevant home directory, and as such util.scm is indeed not there, it is actually in documents/myproject/. That being said, I'm used (in other languages) to the functionality of looking these paths up relative to the file containing the instruction to import, and I'd like to have that here as well. I've tried prefixing it by ./ or defining the file as a libary and doing (import (util)) but none of it works outside of documents/myproject/. Is there any way to get this to work as I intend it to?
I assume this is Chez-Scheme-specific. If not I'd prefer an answer that is implementation-neutral.
load is kind of awkward in R5RS since the report states that system interfaces are off topic in the report, but they include load which is a half hearted solution. The report does not say if the load is relative to the current directory or the file the load form originates from so in order to be portable I guess you are required to run your script from the current directory and have your loaded file relative to both.
Since Chez Scheme implements R6RS load is not really the right form to use. R6RS removed load in favor of libraries. You should make your file a library and consult how to install it. In some systems that is just placing the files in the right path, adding library location in configuration or running install script. How one uses the library is the same in all implementations, by using import.
According to Chez documentation you can pass --libdirs to it to give it one or more paths to consider for loading libraries. You can see the paths it scans by evaluating (library-directories)
There are several different ways to accomplish what (I think) you are trying to do, but eventually they all boil down to letting Chez know where to look for things. When given relative paths, include and load use the source-directories parameter to search for the requested file. Libraries have their path automatically prepended to source-directories while they are being loaded or compiled, so if your main.scm were a library definition then it would find util.scm as you expect.
However, it sounds like main.scm isn't a library, it's a top-level program. Unfortunately, Chez doesn't have a command line option to set the source-directories like it does for library directories. That leaves you with a bit less flexibility. Any of the following will work:
Make util.scm a library and invoke Chez with the --libdirs option to let it know where to look for libraries.
Set source-directories and load main.scm from inside the REPL rather than from the command line.
Write a wrapper shell script that does the above by echoing the commands into scheme so you don't have to type it yourself. (Only suitable if you don't also need to then type into the scheme session).
Write a wrapper shell script that cds into your project directory before running scheme (and presumably cds back to the original directory when it's done).

How do I prevent emacs from resolving directory symlinks in paths?

I have a project, call it 'foobar', that when I checkout has all its source in the folder "foobar/foobar". Because the top level foobar directory contains nothing except for the inner foobar directory, it's pointless, but that's how things were originally checked into the project and it's outside my control. This has the unfortunate effect of making paths longer and harder to read, so I rename the toplevel foobar to "foobar-checkout" and then make a symlink called "foobar" that links to "foobar-checkout/foobar". This way I can open "foobar/source.c" instead of "foobar/foobar/source.c".
This works for when I'm in the shell, and when I first open the file in emacs, but after that emacs will resolve the symlink. So if I have source.c open and I press Ctrl+x Ctrl+f to open a new file, the path it lists is "foobar-checkout/foobar/" rather than "foobar/". Is there a way to get emacs to not resolve the symlink so I can enjoy the shorter path?
I've just tried this on GNU Emacs 22.2.1, and it doesn't seem to resolve my symlinks. Is it possible that the resolving of symlinks is not vanilla emacs behavior and is rather something unintentionally introduced with a file opening module, such as ffap.el?
Either way, I couldn't test my idea, but it occured to me that you might override file-symlink-p, described currently as:
file-symlink-p is a built-in function in `C source code'.
(file-symlink-p FILENAME)
Return non-nil if file FILENAME is the name of a symbolic link.
The value is the link target, as a string.
Otherwise it returns nil.
This function returns t when given the name of a symlink that
points to a nonexistent file.
If you modify that to always return nil, perhaps emacs won't resolve the symlinks:
(defun file-symlink-p (FILENAME)
nil)
Of course, this will probably break some other stuff, but maybe it's worth a shot.
You might like to use directory-abbrev-alist or maybe vc-follow-symlinks.

How to run a LISP program

Does the LISP program need to be in the same folder as the LISP compiler or can I call it from anywhere?
The basic operation is to call load with a pathname.
(load #p"/home/user710086/foo.lisp")
Then, you may need to run whatever "main" function is supplied by that file.
The location can also be in the current directory, which is, of course, platform dependent. The current directory usually has nothing to do with the directory the Lisp executable resided in, but is the directory of the shell you called it from. I do not know what the current directory is in Windows when you click on something, but I would guess that it is some home-directory-surrogate.
There are several things that may wrap around that basic operation. Usually, code is organized into an ASDF system, and has defined one or more packages. You would then add the .asd file to asdf:*asdf-registry* and then load the package with
(asdf:load-sys 'foo)
This would load all files defined in the .asd file in a calculated order, thus providing you with the system's functionality.