compile and join coffeescript files - coffeescript

I have the following structure:
/lib
/ myfile.js.cofee
/ secondfile.js
/src
and i would like to compile them into
/lib
/ myfile.js.cofee
/ secondfile.js
/src
/ awesomefile.min.js
I have read about Cakefiles, but i'm not sure how to exactly do this.
Thanks,
Mike

If you happen to be using something based on connect (e.g. express), I'd recommend using connect-assets. If not, then grunt may be a good bet, as was previously suggested. If you'd like to do this yourself using a Cakefile, here is one approach you could use:
Note that the convention is to build from src to lib (which is the reverse of what you stated in the question). I'll use that convention below, but you can easily switch it back if needed.
$ npm install snockets
place the following in src/awesomefile.coffee:
#= require secondfile.js
#= require myfile.js.coffee
create a Cakefile with the following:
fs = require 'fs'
Snockets = require 'snockets'
NAME = 'awesomefile'
INPUT_FILE = "src/#{NAME}.coffee"
OUTPUT_FILE = "lib/#{NAME}.min.js"
task 'build', 'Build lib/ from src/', ->
snockets = new Snockets()
js = snockets.getConcatenation INPUT_FILE, async: false, minify: true
fs.writeFileSync OUTPUT_FILE, js
task 'clean', "remove #{OUTPUT_FILE}", ->
fs.unlinkSync OUTPUT_FILE
Now you can just do:
$ cake build
and that will create a lib/awesomefile.min.js.
You can have the files in src track their own dependencies, or you can list the order to be included in a single file like I've done above. For more, you can check out the snockets repository. Also note that the compiling chapter chapter of The Little Book on CoffeeScript is a good resource for learning about cake files.

Might not be the exact answer you expected.
Grunt.js at www.gruntjs.com is a very helpful buildtool and certainly includes a lot of stuff that you need to do on a daily basis with a webproject.

Related

What is the best practice for installing external dependencies in a Coq project?

I understand what I believe is the essence of the official utilties doc https://coq.inria.fr/refman/practical-tools/utilities.html#building-a-coq-project:
one creates a _CoqProject with arguments to coqc and the file names to compile (hopefully in an order that takes into account dependencies)
then one make an automatic CoqMakefile with coq_makefile -f _CoqProject -o CoqMakefile
Then you use their recommended Makefile to run the automatically generated make file.
But then if we need other dependencies, it doesn't say how to install them (or uninstall) them. What is the standard way to do that?
My guess is that one likely adds a target to your Makefile at the end of it and do some sort of opam install?
e.g.
# KNOWNTARGETS will not be passed along to CoqMakefile
KNOWNTARGETS := CoqMakefile
# KNOWNFILES will not get implicit targets from the final rule, and so
# depending on them won't invoke the submake. TODO: Not sure what this means
# Warning: These files get declared as PHONY, so any targets depending
# on them always get rebuilt -- or better said, any rules which those names will have their cmds be re-ran (which is
# usually rebuilding functions since that is what make files are for)
KNOWNFILES := Makefile _CoqProject
# Runs invoke-coqmakefile rule if you do run make by itself. Sets the default goal to be used if no targets were specified on the command line.
.DEFAULT_GOAL := invoke-coqmakefile
# Depends on two files to run this, itself and our _CoqProject
CoqMakefile: Makefile _CoqProject
$(COQBIN)coq_makefile -f _CoqProject -o CoqMakefile
# Note make knows what is the make file in this case thanks to -f CoqMakefile
invoke-coqmakefile: CoqMakefile install_external_dependencies
$(MAKE) --no-print-directory -f CoqMakefile $(filter-out $(KNOWNTARGETS),$(MAKECMDGOALS))
#
.PHONY: invoke-coqmakefile $(KNOWNFILES)
####################################################################
## Your targets here ##
####################################################################
# This should be the last rule, to handle any targets not declared above
%: invoke-coqmakefile
#true
# I know this is not a good coq dependency example but just to make it concrete wrote some opam command
install_external_dependencies:
opam install coq-serapi
I think I wrote the install_external_dependencies in the right place but I'm not sure. Is that correct? Anyone has a real example?
For all the code see: https://github.com/brando90/ultimate-utils/tree/master/tutorials_for_myself/my_makefile_playground/beginner_coq_project_with_makefiles/debug_proj
related: question on official tutorial for building coq projects https://coq.discourse.group/t/official-place-to-learn-how-to-setup-coq-make-files-for-beginner/1682
Btw,
I don't understand the last like in the makefile yet.
# This should be the last rule, to handle any targets not declared above
%: invoke-coqmakefile
#true
i.e.
%true in the make file template coq gave us.
% in the name of the rule.
What does that line do?
Update
I'm seeking an end-to-end small demo of how to install all dependencies with whatever the recommended approach when using _CoqProject and coq_makefile as shown in the utilities doc https://coq.inria.fr/refman/practical-tools/utilities.html. The ideal answer would contain a single script to install and compile everything in one go -- say in a install_project_name.sh. Including opam switches etc.
Related:
How does one install a new version of Coq when it cannot find the repositories in a new Mac M1 machine?
Installing packages for Coq using OPAM
https://coq.discourse.group/t/official-place-to-learn-how-to-setup-coq-make-files-for-beginner/1682
The simplest setup is to install external dependencies manually with opam.
opam install packages-needed-by-my-project
Then they will be immediately available to build your own project.
The next level of organization is to package up your project. Refer to the following Coq community resources:
Coq community templates
Recommended Project Structure
The main thing immediately relevant to your question is to have a *.opam file at the root of your project which lists its dependencies (possibly with version requirements). Then you can install them using opam install . --deps-only.
The Makefile part of your question is about a bit of overengineering for passing options seamlessly to CoqMakefile. I'm not sure how it works off-hand, but it's not important anyway, especially because Dune is superseding make as the recommended build system for Coq project.

How do I link a static lib to a yocto autotools project in Eclipse

I have created a Yocto autotools project in Eclipse (based on a Hello World project).
I wanted to separate my code into a number of libs and then link them in a form of static libs (.a) to my project.
Now I have one app and a number of static libs. However, no matter what I try I can't get my code to compile. Each separate lib compiles and produces a .a file, but my app doesn't.
After searching the web I have a possible solution - add a direct link to my static libs:
MyApp_CPPFLAGS="-I$LOCATION"
MyApp_LDADD="/home/xxx/workspace/MyApp/Encoding2/Debug/libEncoding2.a"
This is my Makefile.am file, where libEncoding2.a exist in that path.
The error I get is:
make[2]: *** No rule to make target `"/home/xxx/workspace/MyApp/Encoding2/Debug/libEncoding2.a"', needed by `MyApp'. Stop.
I already built the lib so I am not sure why a make try is even needed.
Any help will be appreciated.
Because you use static library in your recipes, you can make a soft link to the library in your project source folder, i.e., hello-world-0.1, using following command to link to your static library
ln -s /home/xxx/workspace/MyApp/Encoding2/Debug/libEncoding2.a
and then edit your bb file, hello-world_0.1.bb, adding the source path to your URL
SRC_URI = " \
file://libEncoding2.a \
file://hello-world.c \
"
and in the do_compile block, using follow command to compile your project
do_compile() {
${CC} hello-world.c libEncoding.a -o hello-world
}
do_install() {
install -d ${D}${bindir}/Hello
install -m 0755 enet ${D}${bindir}/Hello
}
After you bitbake your project
bitbake hello-world
and run mkefidisk.sh, you can find the hello-world in /usr/bin/Hello/hello-world. Hope this hint can help you.
BTW, I am not familiar with autotools, I just use make to bitbake the recipes. And your static library should also be created in Yocto not in Eclipse I think. So I think your path for the static library maybe not correct, it should locate in ~/yocto/build/tmp/... or some where like this. In my case, it was located in ln -s ~/yocto/build/tmp/sysroots/intel-corei7-64/usr/lib/libEncoding.a depends on your target environment.
Depending on whether you're using libtool or not, you should have either a noinst_LTLIBRARIES or noinst_LIBRARIES list of targets, respectively. This should only include the name of your library (libEncoding2.la or libEncoding2.a.)
You should never use a full path for this, and you should not quote Make variables, so what you were looking for is
MyApp_CPPFLAGS = -I$LOCATION
MyApp_LDADD = libEncoding2.la # or .a
And that would work.
But on the other hand it seems like you should take some time to understand how autotools work, as it might not be what you're looking for. With a grain of salt you can take my Autotools Mythbuster as a starting point.

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

CoffeeScript build setup that supports unit testing?

I want to use CoffeeScript for building what will essentially be a JavaScript library.
I would just like to be able to
define some classes, with inheritance
keep my code in several files
write some unit tests (QUnit or whatever works, preferably writing tests in CoffeeScript)
(ideally) have the project watched and built automatically while I work
This seems reasonable, no? My plan is just having the unit tests run against the compiled JavaScript, in a browser, although if I can run them straight in node.js that's even better.
Currently I'm trying to do this with CoffeeToaster and QUnit, using two different CoffeeToaster configurations, one with tests and one without. It is working, but perhaps somebody has a better suggestion? Should I ditch CoffeeToaster and do it with Cake? Or get another unit testing framework? Can anybody point me to a tutorial for this? I'm making a clientside JS lib, so I don't want to involve Rails etc.
I'm currently using:
Mocha as the test runner and should.js for assertions;
Mockery to intercept certain require calls for isolated testing with mocks/stubs of required libraries;
*JSCoverage for instrumenting the code for code coverage reports.
My code lives in src/ and I write my tests in CoffeeScript. I use make to build and test the code.
make build compiles the CoffeeScript in src/ to JavaScript in lib/.
make test builds the code and then runs the tests in test/.
make monitor watches and runs the tests as soon as they change. Unfortunately it doesn't recompile the code. I use a Vim keybinding to call make, which also triggers Mocha to re-run the tests.
Edit: If this bothers you, you could run coffee --watch -o lib/ -c src/.
make coverage generates a code coverage report and puts it in lib-cov/report.html.
My Makefile looks somewhat like this:
COFFEE = ./node_modules/.bin/coffee --compile
MOCHA = NODE_ENV=test ./node_modules/.bin/mocha
MOCHA_OPTS = \
--compilers coffee:coffee-script \
--require should \
--colors
REPORTER = spec
build:
#$(COFFEE) --output lib/ src/
test: build
#$(MOCHA) --reporter $(REPORTER) $(MOCHA_OPTS)
monitor:
#$(MOCHA) --reporter min $(MOCHA_OPTS) \
--watch --growl
coverage: instrument
#MYLIB_COV=1 $(MOCHA) $(MOCHA_OPTS) \
--reporter html-cov > lib-cov/report.html
instrument: build
#rm -rf ./lib-cov
#jscoverage ./lib ./lib-cov
.PHONY: build test monitor coverage instrument
You could probably use the above with very little modification.
To generate the coverage report with make coverage, the tests must be run against the instrumented code in lib-cov/ instead of the code in lib/. To make this possible, three things are needed:
The Makefile should set an environment variable, like MYLIB_COV (change the name as you like).
Your index.js should look at this environment variable and require either lib/ or lib-cov/ accordingly:
// index.js
module.exports = process.env.MYLIB_COV
? require('./lib-cov/mylib')
: require('./lib/mylib');
If you need exports from multiple source files, you can combine them here. If you have something other than index.js as 'main' in your package.json, don't forget to change it.
Your tests should require '../':
# test/test.user.coffee
describe 'User', ->
User = {}
before ->
{User} = require '../'
describe '#equals()', ->
describe 'when users have the same username and host', ->
it 'should return true', ->
user1 = new User 'user', 'some.host.foo'
user2 = new User 'user', 'some.host.foo'
user1.equals(user2).should.be.true
# etc.
I'll leave it as an exercise to the reader to find out whether they need Mockery and how to use it if they do. I will point out, though, that the require call in the test snippet above is done inside before for a reason.
Happy coding!

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.