In GHC, is there a way I can check compilation without actually producing output? - ghc

Sometimes, I write code to a file solely for the purpose of checking whether it compiles -- with no interest in the generated binaries.
For example, if I am doing a learning exercise and want to produce some error or see if certain code compiles without error, I'd like to see the ordinary compile output printed to the terminal but without generating the *.hi or *.o files that occur by running ghc <myprogram>.hs.
I sometimes effectively do this using runhaskell, but that is not ideal -- it requires a main function, and actually runs the program whereas I am just looking for a compilation check.
Is there some way to suppress generation when running GHC, only displaying the ordinary compilation errors and warnings?

One of the answers to this question suggested the answer that I'm looking for: ghc option -fno-code.
I.e., compile but don't generate binaries with:
$ ghc -fno-code <myprogram>.hs

In the same spirit to the purpose of the question and in addition to the working answer by #mherzl, my answer below:
while true;do
inotifywait -e modify myprogram.hs
ghc -fno-code myprogram.hs
done
This only works on Linux systems having the inotifywait tool. It blocks an detects if the file is modified.

Related

How do i analyse a complex project like open62541?

I am a student and currently trying to analyse the reference implementation for the OPC Ua protocol in C with cppcheck and frama-c. My goal is not to do very dedicated testing but more some general/basic tests to see if there are some obvious issues with the code.
The project can be found here
I am running a VM with Ubuntu 19.10 and Frama-C version 20.0 (Calcium).
The steps i performed are as follows:
git clone https://github.com/open62541/open62541.git
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 /path/to/source
frama-c -json-compilation-database /path/to/compile_commands.json
Until now everything works as expected and there are no Errors.
However now i am having trouble understanding how to continue.
Do i need to do my analysis on all files seperately or is it possible to throw in the whole project like with cppcheck?
How would i approach this in general? Do i need to to analyse all files step by step?
For example i tried:
frama-c -json-compilation-database /path/to/compilation_commands.json -val /path/to/open62541/src/
which returns:
[kernel] Parsing src (with preprocessing)
gcc: warning: /path/to/open62541/src/: linker input file unused because linking not done
[kernel] User Error: cannot find entry point `main'.
Please use option `-main' for specifying a valid entry point.
[kernel] Frama-C aborted: invalid user input.
So apperantly frama-c requires an entry point, however i do not know which entry point i need to specify.
Any help regarding this is much appreciated.
I apologize for my lack of understanding. This is my first project of this kind and i am a little bit overwhelmed by frama-c and the complexity of the open62541 project.
Do i need to do my analysis on all files separately or is it possible to throw in the whole project like with cppcheck?
Frama-C can actually analyze the entire project in one go provided multiple files do not define the same symbols. See http://blog.frama-c.com/index.php?post/2018/01/25/Analysis-scripts%3A-helping-automate-case-studies, paragraph "Setting sources and testing parsing":
The list of source files to be given to Frama-C can be obtained from the compile_commands.json file. However, it is often the case that the software under analysis contains several binaries, each requiring a different set of sources. The JSON compilation database does not map the sources used to produce each binary, so it is not always possible to entirely automate the process.
The key point in your case is that the compilation_commands.json instructs Frama-C on how to parse each file, but you must still supply the files you want to see parsed yourself. With your current command-line, Frama-C tries to interpret /path/to/open62541/src/ as a file (and fails), and has no other file to parse. This is why you get the error User Error: cannot find entry point 'main'.
Thus, you must specify the files you want to parse on the command-line. This can be done in two ways:
manually, by extracting the files referenced in compilation_commands.json
automatically, using the frama-c-script helpers, described at http://blog.frama-c.com/index.php?post/2019/01/16/Setting-up-an-analysis-with-the-help-of-frama-c-script
I used the first approach, but I suggest you use the second, as frama-c-script is very helpful to start a first analysis.
Once you have done this listing step, you will encounter at least three more problems:
Frama-C will choke on # include <sys/param.h>, because this file is not present in the standard C library bundled with Frama-C. Either remove this include in the source files, or add an empty sys/param.h somewhere
some .c files refer to generated headers that are not present in the git repo of open62541. So you will need to compile the repo to get those headers before launching Frama-C.
Frama-C will also choke on the definition of the macro UA_STATIC_ASSERT in architecture_definitions.h. I did not investigate whether one of the definitions was accepted, and I simply defined it to the empty macro.
After all this, you should be good to go.

Why do which and Sys.which return different paths?

I tried to run a Python script from R with:
system('python script.py arg1 arg2')
And got an error:
ImportError: No module named pandas
This was a bit of a surprise since the script was working from the terminal as expected. Having encountered this type of issue before (with knitr, whence the engine.path chunk option), I know to check:
Sys.which('python')
# python
# "/usr/bin/python"
And compare it to the command line:
$ which python
# /Users/michael.chirico/anaconda2/bin/python
(i.e., the error arises because I have pandas installed for the anaconda distribution, though TBH I don't know why I have a different distribution)
Hence I can fix my issue by running:
system('/Users/michael.chirico/anaconda2/bin/python script.py arg1 arg2')
My question is two-fold:
How does R's system/Sys.which find a different python than my terminal?
How can I fix this besides writing out the full binary path each time?
I read ?Sys.which for some hints, but to no avail. In particular, ?Sys.which suggests Sys.which is using which:
This is an interface to the system command which
This is clearly (?) untrue; to be sure, I checked Sys.which('which') and which which to confirm both are pointing to /usr/bin/which (goaded on by this tidbit):
On a Unix-alike the full path to which (usually /usr/bin/which) is found when R is installed.
To the latter, on a whim I tried Sys.setenv(python = '/Users/michael.chirico/anaconda2/bin/python') to no avail.
As some of the comments hint, this is a problem that arises because the PATH environment variable is different for programs launched by Finder (or the Dock) than it is in the Terminal. There are ways to set the PATH for Dock-launched applications, but they aren't pretty. Here's a place to start looking if you want to go that route:
https://apple.stackexchange.com/questions/51677/how-to-set-path-for-finder-launched-applications
The other thing you can do, which is probably more straightforward, is tell R to set the PATH variable when it starts up, using Sys.setenv to add the path to your desired Python instance. You can do that for just one project, for your whole user account, or for the whole system, by placing the command in a .Rprofile file in the corresponding location. More information on how to do this here:
https://stat.ethz.ch/R-manual/R-devel/library/base/html/Startup.html

Does changing the order of compiling with GCC in unix delete files?

So I just messed up real bad.. I'm hoping someone can tell me I didn't just ruin everything I did for the last 4 weeks with this simple typo..
I kept making changes to my C program and would recompile to test the changes using this in terminal:
gcc -o server server.c
Due to programming for the past 5 hours straight for the most part.. I accidentally typed this the last time I tried compiling:
gcc -o server.c server
I got some long message and realized my mistake.. tried recompiling using the first way I listed.. And it says "no such file server.c"
I typed "ls" and sure enough.. my program isn't there.
Please tell me everything I did hasn't vanished? :((
Unfortunately, you told the compiler to read your executable, and write its output to your source file. The file is gone. If you are on a Windows system, perhaps it could be undeleted with something like Norton Utilities. If not, you're probably out of luck.
Next time, consider using a Makefile to contain the compiler commands, so you can just type "make" to build your program. Other strategies include keeping the file open in a single editor session the whole time you're working, and using a source control system like git or subversion (which would let you back up to previous versions of the file, as well.)

Can I run a script with LispWorks, like with SBCL's "--script" option?

I mean with SBCL I can run a script as easy as sbcl --script piece-of-code.lisp. But I can't find an obvious way to do so with LispWorks. Of course there's always a deploy and run option, but it requires a build script for every little exercise.
Is there a way to run a script with LispWorks without building an executable or running it from listener manually?
I'd recommend you create lispworks console, like in:
http://www.lispworks.com/documentation/lw60/LW/html/lw-177.htm#83244
Then, you can use lw-console -init foo.lisp without IDE.
The sbcl --script is to make sbcl aware the first line of your code might be #!/usr/bin/sbcl ... and LispWorks doesn't seem to have that.
However, if you just want to run a script and not make it executable, then you can write:
lispworks -init my-lisp-init
And it will load my-lisp-init.lisp if I understood the documentation right
The various command line option for the latest LispWorks 6.1 are described here:
http://www.lispworks.com/documentation/lw61/LW/html/lw-517.htm#pgfId-891723

C compilation flags from R

Can you set R's C and C++ flags at compilation time when installing from R CMD INSTALL (essentially, in this particular case I want to turn off compiler optimization, but ideally there's a general solution)?
I know you can affect some options using --configure-args="...", and I rather optimistically tried --configure-args="diable-optimization", to no avail. Similarly, I could also edit $RHOME/etc/Makeconf but again this is not really the kind of solution I'm looking for (and not possible where I don't have the relevant write permission).
I define my flags through an autoconf script and with a Makevars file in the package/src directory, if this makes any difference.
Dirk - very helpful discussion (as always) and definitly pointed me in the right direction. For my specific issue, it turned out in addition to the Makevars file I had to pass arguments through to configure. I have no idea why this is the case (and reading around doesn't seem to be the norm, so maybe I've done something wrong somewhere), but if anyone else has the same problem, using a ~/.R/Makevars combined with the following arguments for configure/INSTALL worked for me.
R CMD INSTALL --configure-args="CFLAGS=-g CXXFLAGS=-g" package.tar.gz
Yes, I use a file ~/.R/Makevars for that. Also handy to set CC and CXX to different compilers when, say, switching gcc versions, or switching to llvm, or ...
I can confirm that the Makevars file is very useful (specially if you need to use "-L/my/libs" or "-I/my/includes", or others build flags).
For the build, if you want to set an option for the site/machine, you can also change variables in the Makeconf file (/path/R/install/[lib64/R/]etc/Makeconf).
However, if like me, you still have some problems to manage and use libraries later, you can also set libraries with the ldpaths file [1]. This file contains the R_LD_LIBRARY_PATH used by R. This variable is the equivalent of the well known LD_LIBRARY_PATH on unix [2].
I just added some content (just before the comment on MacOS / Darwin) to this file (/path/R/install/[lib64/R/]etc/ldpaths):
if test -n "${LD_LIBRARY_PATH}"; then
R_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${R_LD_LIBRARY_PATH}"
fi
## This is DYLD_FALLBACK_LIBRARY_PATH on Darwin (OS X) and
Then, you will be able to manage your libraries dynamically
e.g. using "environment modules" or "lmod".
Note that you can change many other environment and R variables with all the file which are in that config/etc directory (Renviron, repositories, javaconf, Rprofile.site ...).
[1] https://support.rstudio.com/hc/en-us/community/posts/200645248-Setting-up-LD-LIBRARY-PATH-for-a-rsession
[2] http://www.tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Resources