How to compile several files to the same ones - google-closure-compiler

I know that Google Closure Compiler allows me to compile several files into a single one like the following:
java -jar compiler.jar --js assets/js/file1.js
assets/js/file2.js --js_output_file assets/js/file.min.js
But I need to compile files and put it to the same name in the same folder like this:
java -jar compiler.jar --js assets/js/file1.js
--js_output_file assets/js/file1.js
java -jar compiler.jar --js assets/js/file2.js
--js_output_file assets/js/file2.js
But it doesn't work. The files get corrupted. Can you help me?

First and most importantly, your compile script is set up to overwrite your source files. Are you really, absolutely positive that this is what you intend to do? Compilation is a lossy transformation: it destroys comments (including type annotations), renames everything, refactors aggressively, inlines everywhere, and generally purees your hard work into an unmaintainable mess.
java -jar compiler.jar --js assets/js/file1.js
--js_output_file assets/js/file1.js
java -jar compiler.jar --js assets/js/file2.js
--js_output_file assets/js/file2.js
If I am to take you at your word and you have actually done the above, this would unfortunately explain your "my files are now corrupted" question. I hope you have a backup.
More generally, grok the Compiler Manual. All of it, but especially the section on inconsistent property names. If the compiler is not informed about how your source files relate to eachother, it is impossible for closure to rename their contents consistently.
If you intend to create pre-compiled .dll style shared objects, this is not supported by closure because of the name-fragmentation issues documented in the manual. Also, there's no need to pre-compile, compilation is reasonably fast as-is. Share your source files instead.
Please, please make yourself a build directory and pipe your compiler output away from your source code. Code never builds perfectly on the first pass. Even if the code in question is a simple math utility, you'll want to build and test more than a few times.
In summary:
(1) read entire manual, (2) write Externs or try goog.require, (3) pre-compilation is overrated, (4) never ever ever overwrite source files ever, (5) keep frequent backups.

Simply use multiple "--js" params in command line:
java -jar compiler.jar --js 1.js --js 2.js --js 3.js --js_output_file all.js

Related

The logic of the ocaml compile process

I wrote a small project in OCaml.
I have two folders:
./myUnionFind. inside there is a file myUnionFind.ml.
./percolation. inside there are two files: myPercolation.ml and percolation_stats.ml.
myUnionFind.ml works as a module.
myPercolation.ml works as a module too, but it uses MyUnionFind module defined in myUnionFind.ml.
percolation_stats.ml uses myPercolation.ml.
together with above all, I also use Batteries.
I want to compile them all to work and get a executable file run.
But how?
I have tried the following:
inside folder ./percolation, I did ocamlfind ocamlc -package batteries -linkpkg ../myUnionFind/myUnionFind.ml myPercolation.ml percolation_stats.ml -o run
It failed, and said File "myPercolation.ml", line 1, characters 0-16:
Error: Unbound module MyUnionFind, but I did include that folder ../myUnionFind, right?
Also, if I just want to compile ./myUnionFind/myUnionFind.ml once, how can I do so that not every time, myUnionFind.ml gets compiled again and again?
Inside myUnionFind, you should compile myUnionfind.ml to a compiled unit:
cd myUnionFind
ocamlc -c myUnionFind.ml
This will generate myUnionFind.cmo, which stores the compiled implementation, and myUnionFind.cmi, which stores the compiled interface. Other modules using MyUnionFind will need to access the cmi at type-checking type.
Inside percolation, you can compile myPercolation.ml to a module by doing
cd percolation
ocamlc -I ../myUnionFind -c myPercolation.ml
Again, you get both a .cmo and a .cmi. Note that the compiler has looked up myUnionFind.cmi automatically in the search path, and found it because of the -I option.
You can then compile percolation_stats (relying on both previous compilation units)
ocamlc -I ../myUnionFind -c percolation_stats.ml
You finally link the three resulting .cmo together to build an executable:
ocamlc ../myUnionFind.cmo myPercolation.cmo percolation_stats.cmo -o run
(If you use batteries, wrap each command with ocamlfind ocamlc -package batteries, but only the linking command with linkpkg).
To make this process simpler:
ocamlbuild is good at finding and compiling all the files of your current project to produce an executable. In the percolation directory, ocamlbuild percolation_stats.byte can produce an executable with all the stuff present
but if you want to use myUnionFind as an external library, the best thing to do would be to install it with findlib, to make it easy to find and specify from percolation; for information on how to create a findlib package (it's very simple), please see this older answer
once myUnionFind is a findlib package, the single command ocamlbuild -use-ocamlfind -pkgs batteries,my-union-find percolation_stats.byte (or .native) should be enough to get an executable

source_dirs doesn't work in .gpr scipt

I've inherited an Ada/C++ project and I'm trying to use gprbuild to automate the build process (which was previously done with a set of about 12 .bat files). I'm totally new to Ada and gprbuild, but have actually made pretty good progress. I can compile the .exe's that I need, but not the library. I am not at liberty to completely share the .gpr file, but the relevant parts look like this:
[snip]
for Source_Dirs use (
"c_plus_plus_files",
"ada_files",
"..\another_project\some_other_ada_files",
"..\another_project\even_more_ada_files"
);
[snip]
for Source_Files use (
"my_ada_file.ads",
"another_ada_file.ads",
"one_more_ada_file.adb",
"c_plus_plus_file.cpp"
);
[snip]
When I run "gprbuild -P my_project.gpr" it in turn runs "gcc -c gnat5 one_more_ada_file.adb" and complains that it cannot find a certain file that one_more_ada_file.adb depends on. The dependency is in ..\another_project\even_more_ada_files, so I would expect it to be found. But if I copy the dependency into the same folder as one_more_ada_file.adb, the error goes away.
Because of how the VCS is setup and how we're sharing code between two projects, I'd much rather figure out what's wrong with how I'm using "for source_dirs use" than to keep multiple copies of all the ada files.
Again, I'm an Ada/GPS newb, so if I'm leaving out relevant information, please let me know.
Update: It appears that the specific problem isn't that source_dirs isn't doing anything at all, but that it doesn't handle having two source dirs where .ads files in one dir depend on .ads files in the other. That is, even within my "other" project above, an .ads file in some_other_ada_files that depends on an .ads file in even_more_ada_files doesn't get compiled with the gcc -c -gnat05 command when I run gprbuild (error: the file in even_more_ada_files not found), but it does get compiled if I run the gcc command by hand (or in a .bat script) with two -I flags, one for each directory.
When dealing with multiple projects, you should normally create a .gpr-file for each project, and let your projects depend on the other projects as needed.
Thus:
project another_project is
for Source_Dirs use
("some_other_ada_files",
"even_more_ada_files");
end another_project;
and then:
with "..\another_project\another_project.gpr"
project The_Project is
for Source_Dirs use
("c_plus_plus_files",
"ada_files");
end The_Project;

How to let autotools compile a QT module with qmake

In my project I have made configure.ac and Makefile.am files correctly so my components compile and dynamically link to the appropriate libraries. One of these components links to a library that uses QT, so the appropriate Makefile must be generated out of the .pro file prior compilation on the target system.
For this I think that I need to find a way to tell my make scripts, through Makefile.am perhaps, that this library must be compiled on its own by first running qmake and the generated Makefile in that directory.
Is this even possible? If so, how do I do it?
Researching on my own I have found an apparently abandoned project called “AutoTroll” which is supposed to automatically alter files of autotools in order to add compatibility with Qt4. I have tried to make it work with no luck. It lacks a proper documentation also.
Without this tool, compiling Qt4 modules with autotools requires a lot of hacking and interventions, making it really hard and even more for a cross-platform application.
I have switched to CMake. CMake’s setup is far easier than autotools’ and it supports Qt4 modules out of the box.
We do this, its not that difficult. In configure.ac:
QT_QMAKE
[
echo $QMAKE -o Makefile.myapp $(realpath $(dirname $0))/myapp.pro
$QMAKE -o Makefile.myapp $(realpath $(dirname $0))/myapp.pro
]
Then (Assuming your macros are located in the standard m4 directory), make a file called qt_qmake.m4 there.
AC_DEFUN([OTT_QT_QMAKE],[
if test -z "$QMAKE"; then
QMAKE=$(which qmake)
$QMAKE -v > /dev/null 2>&1
if test $? -ne 0; then
AC_MSG_ERROR([qmake executable not found!])
fi
fi
AC_SUBST(QMAKE)
])
Then in Makefile.am:
ACLOCAL_AMFLAGS=-Im4
all-am:
make -f Makefile.myapp all
install-am:
make -f Makefile.myapp install
qmake_all:
make -f Makefile.myapp qmake_all
clean-am:
make -f Makefile.myapp clean
That should align with the targets that QTCreator uses, and allows you to "bootstrap" qmake using autotools to make a config.h for instance, or global qmake include file to make shadow builds easier. Theres a lot I'm leaving out if you want to have version checking,etc... but it should get you started. If you built qt yourself, or have it not in your path, ie redhat (/usr/lib{64}/qt5/bin/qmake), you can just use the QMAKE variable to point to it. QT is smart enough with that to take it from there usually. I know its not the most elegant solution, but its worked for us cross-linux for almost a decade.

Java compile error. servlet-api.jar

I created simple Java Servlet: WelcomeServlet.java.
Than, I tried compile this file via:
javac WelcomeServlet.java
In result I see compile error:
package javax.servlet doesn't exit
I try find solution for this error with Google. And I find first part of answer: java compiler doesnt see servlet-api.jar file.
I know, that Apache Tomcat in it lib folder contains servlet-api.jar file.
So, I have this file, but where I must copy this file??
I try different folders:
echo %JAVA_HOME%
C:\Program Files\Java\jdk1.6.0_26
%PATH% contains this line: C:\Program Files\Java\jdk1.6.0_26\bin
So, I copy in:
%JAVA_HOME%\bin
%JAVA_HOME%\lib
%JAVA_HOME%\jre\lib
And in result same error.
And only after I copy servlet-api.jar in directory:
%JAVA_HOME%\jre\lib\ext
compilation complite sucessful.
My question: Why? Why I must copy in folder %JAVA_HOME%\jre\lib\ext ??
Where This moment describe in documentation?
And other question we have some official docs or specifications that describe folder structure for jdk folder??
You'll need to specify the directory or directories you want the compiler to search by using the -classpath command line option when running javac. The reason the compiler found your .jar in %JAVA_HOME%\jre\lib\ext is because it searches the extension directories by default.
This is for Java 1.5, but I believe it is more or less still correct:
http://docs.oracle.com/javase/1.5.0/docs/tooldocs/findingclasses.html
The link Shaun provides is a more complete answer. But in short, using the classpath is the best way to introduce 3rd party or external (to the JDK/JRE) libraries. The classpath is a concept much like the %PATH% or the $PATH variables, but specifies locations for java to use for lookup rather than the shell to use for lookup of executables.
The classpath provides the java compiler or java virtual machine a list of items to use when searching for resources. This "path" may include directories or files. It will typically include jar files and sometimes locations of configuration files. Many Java based lookup schemes for files configuration or otherwise use some variant of what is accomplished by [Class#getResourceAsStream()][1]'s use of walking the Classpath.
I have rarely seen an incident where putting a jar file in the lib/ext location was preferred to utilizing the Classpath.
The classpath is typically an environment variable (%CLASSPATH% or $CLASSPATH) or specified on the command line when running java or javac (e.g. -cp or -classpath see the help from the executable you are running).
Build tools such as Ant and Maven will also provide abstractions to defining the list of jars to be utilized by your applications and are highly recommended to be used for any length of repetitive change code, build, test, run cycles.

Using the --module option in Closure Compiler to create multiple output files

I'm creating a fairly large library of JavaScript, using Closure Compiler for both its wonderful compression as well as the type-checking and warning systems.
I want to create multiple output files though, because the files are loaded asynchronously (and some files are only loaded on-demand).
Poking around the source code, I've found the --module flag, as well as some related flags. The source code says the following about the option:
A javascript module specification. The format is <name>:<num-js-files>[:[<dep>,...][:]]]. Module names must be unique. Each dep is the name of a module that this module depends on. Modules must be listed in dependency order, and js source files must be listed in the corresponding order. Where --module flags occur in relation to --js flags is unimportant
... and that's all I can find. I'd love to learn more about how to use this option, does anyone have any experience here? Alternatively, if there's another way to create multiple output files, I'm all ears.
java -jar compiler.jar ^
--chunk jq:1: --js jquery-1.6.2.js ^
--chunk t:1:jq: --js test.js ^
--compilation_level ADVANCED_OPTIMIZATIONS
This example will compile out 2 files for you:
jq.js
t.js
jq.js will be jquery 1.6.2 with advanced minification, and t.js will use that minified version of JQuery properly.
I wish there was a JavaFiddle I could post this to to demonstrate it.
Older version
This original answer was for an older version of Closure Compiler. I've left it intact below in case you're in an environment that needs to keep the older version in place.
How to handle multiple output files, aka modules:
http://groups.google.com/group/closure-compiler-discuss/browse_thread/thread/ec7f6809b19b019e/25a94f3994173840
Copy/pasting:
java -jar Build\Tools\compiler.jar ^
--compilation_level=ADVANCED_OPTIMIZATIONS ^
--externs Build\jQuery.externs.js ^
--js Build\Output\Compiling.js ^
--js Script/Themes.lang.js ^
--js Script/Themes.js ^
--module Core:3 ^
--js UI/ThemeChooser/ThemeChooser_en.htm.js ^
--js UI/ThemeChooser/ThemeChooser.js ^
--module UI_ThemeChooser:2:Core ^
--js UI/VerticalTabs/VerticalTabs_en.htm.js ^
--js UI/VerticalTabs/VerticalTabs.js ^
--module UI_VerticalTabs:2:Core ^
--js Pager/Pager_en.htm.js ^
--js Pager/jquery.Pager.js ^
--js Pager/Pager.js ^
--module Pager:3:VerticalTabs ^
--module_output_path_prefix .\Compiled\
And as he notes, --js_output_file is irrelevant when outputting modules.
Note: Apparently the Closure Compiler has changed the arg "--module" to "--chunk". An editor suggested the change; for the newer version I kept the change, for the older version I kept the older argument name, since there are always people out there using older versions of build tools, and that kind of small breaking change can really screw ya up.

Resources