I relatively new to writing make files and could use some pointers. What I'm trying to achieve is probably fairly basic but after searching the web I fail to understand how.
I would like to compile a set of object files from a src directory into a build directory and my naive idea were to define the set of source files as a macro, use macro modifiers to create a macro for the object files (so that these are properly compared to the source files when recompiling. My current scheme fro creating the object files macro looks as:
SRCDIR = /some/dir/
BUILDDIR = /some/dir/
CSRC = \
$(SRCDIR)f1.c \
$(SRCDIR)f2.c \
OSRC = $(CSRC,.c=.o,F,<$(BUILDDIR))
all:
#echo $(OSRC)
where the all rule is simply put in to check if the object files macro is set properly. Unfortunately it is not, instead it is empty. Replacing
OSRC = $(CSRC,.c=.o,F,<$(BUILDDIR))
by
OSRC = $(CSRC:.c=.o)
does give me a macro of object files but not with the proper directories. Thus insight on how to modify my file to get what I want would be appreciated. (I'm using GNU Make 3.82)
I'm not sure where you got $(CSRC,.c=.o,F,<$(BUILDDIR)); there's nothing even remotely like that syntax in GNU make.
The statement $(CSRC:.c=.o) replaces all the .c suffixes with .o, but that doesn't help you because you also want to replace the directory.
You should use the $(patsubst ...) function:
OSRC = $(patsubst $(SRCDIR)%.c,$(BUILDDIR)%.o,$(CSRC))
Related
I've been using a macro library so that I can use macros without compiling them first. The problem is that when I change the macro and save it, then refresh my filename for the macro lib, this is not enough to update and use the new macro?
Anyone have any ideas why it is still using and compiling the old macro before it was saved?
The first time a macro is called, if it hasn't already been defined, SAS will check your autocall path and iterate through those locations trying to find it.
When it finds the macro in your autocall library it compiles it and saves the compiled version to your work folder. Subsequent calls to the macro will result in SAS using the compiled version of the macro.
In order for it to be refreshed (if you have made changes since it was compiled) you need to open the code to the macro and submit it again. That will redefine/recompile it for you.
Alternatively, you could also find the catalog in your work folder that contains the compiled versions of the macros and delete it from there (typically work.sasmacr).
Robert explains why you see the behavior.
I use the following to easily reinclude a changed macro. This assumes you have a FILENAME called MACROREF defined to the folder in question.
%include MACROREF(my_macro);
Obviously change the my_macro to the macro you need to be compiled.
filename macroref "c:\temp";
%include MACROREF(MacroOne);
If you have a folder full of macros (as stated in the comments) you can include the whole folder.
%include "%sysfunc(pathname(MACROREF))/*.sas";
This will recompile the whole folder. Just don't have any non-macro sas files in that folder, otherwise you are running them too.
If I start a custom toplevel in Emacs/tuareg with the tuareg-run-caml function, I need to give the path to the toplevel and the various -I options it requires to find the CMI files. This typing is tedious, is there a more convenient way to start a custom toplevel?
One approach is to add a .ocamlinit in the project directory that uses #directory to add whatever paths are necessary to the toplevel. You can also use this to install printers, add shorter names for commonly used modules, run test code, etc.
Note that you probably want that project specific .ocamlinit to execute ~/.ocamlinit, since things like opam tend to put bits and pieces in there. It might look something like this:
#use "/home/foo/.ocamlinit"
#directory "_build"
open Printf
module V = VeryLongModuleName
Note that #use expects a hard-coded path. This unfortunately interferes with distributing the file.
I further automate this by having an emacs command to start a toplevel that searches the current directory for a file called *.top to execute, falling back to ocaml if none is found. As ocamlbuild provides a fairly simple method of building these files, this avoids much of the tedium of getting a project loaded into a useable toplevel.
I am extending an existing open-source project, which already has a very advanced Lexer/Parser/TreeParser in ANTLR. I would like to adhere to the current directory structure, so I created my own directory where I would like to put my new (already written) grammar files. They are importing these three original grammar files and to compile the code, I can use java org.antlr.Tool, where I can specify one directory to search for imported grammars with -lib option argument.
My problem is that these three original imported grammar files have some imports themselves and again in different directory. To illustrate (inheritance/importing going to top):
Abstract syntax directory: lexer parser tree parser
Original syntax directory: lexer parser tree parser
My new syntax directory: lexer parser tree parser
This is the hierarchy. The trouble I am encountering is how to specify "Abstract syntax directory" and also "Original syntax directory" at once with the -lib option on the command line for the ANTLR tool (or any other solution which would allow me to compile my grammar importing the original one with the given directories structure).
I tried -lib directory1 directory2, that just appears to ignore the directory2 (and then tries to compile it, which it cannot, because it is a directory, not an ANTLR grammar). I tried specifying "-lib directory1 -lib directory2", the "-lib directory2" just overwrites the "-lib directory1" then.
It is what I believe a fairly basic need to specify multiple directories to search in, in any more complicated system of grammars, therefore I am sure I missed something. I just cannot google anything useful out.
IF you need any more details, I am happy to provide them, it is my master thesis extending an open source project, so I do not need to keep anything secret. :) If it is not possible, I can live without it, but would really like to keep the consistency of the original project.
Looking at the source of the org.antlr.Tool class:
else if (args[i].equals("-lib")) {
if (i + 1 >= args.length) {
System.err.println("missing library directory with -lib option; ignoring");
}
else {
i++;
libDirectory = args[i];
if (libDirectory.endsWith("/") || libDirectory.endsWith("\\")) {
libDirectory = libDirectory.substring(0,libDirectory.length()-1);
}
File outDir = new File(libDirectory);
if (!outDir.exists()) {
ErrorManager.error(ErrorManager.MSG_DIR_NOT_FOUND,libDirectory);
libDirectory = ".";
}
}
}
it appears just one -lib directory is being read.
I'm assuming your (implied) question is hereby answered (that it is not possible to point to more than 1 -lib directory).
I have a src/templates/ directory full of mustache templates. How would I combine and minify the contents of those, so they're available for use in my CoffeeScript app?
I'm already following the directions at https://github.com/jashkenas/coffee-script/wiki/%5BHowTo%5D-Compiling-and-Setting-Up-Build-Tools for combining and minifying my CoffeeScript src into js.
First off, I'll assume that your templates are being exported to the global object (e.g. each one does window.userpane = rather than just userpane =). That's the most important thing. If you're doing that, and you're concatenating and compiling successfully, then the only thing left is to have automatic minification after each concatenation.
Short answer: There's no good tool for this yet. Your best option is to extend your existing Cakefile with a line like
fs.watchFile 'concatenated.js', ->
exec 'uglifyjs concatenated.js'
(To install UglifyJS, run npm install uglify-js.)
Now, this won't solve the problem of ensuring that your scripts are concatenated in a sensible order. (For instance, if you have window.templates = {} in file A and templates.userpane = in file B, then it's very important that file A be concatenated before file B.) For that, you should keep an eye on Sprockets, which lets you indicate at the top of each JS file what its dependencies are, then combine them in an order that respects those dependencies. The creator of Sprockets, Sam Stephenson, is an active member of the CoffeeScript community, and first-class support for CoffeeScript in Sprockets is coming in Sprockets 2 (repo here).
Update: Here's a Cake task to do the actual reading and concatenating of everything in the template directory:
templateJs = ''
files = fs.readdirSync 'template'
for file in files
contents = fs.readFileSync file, 'utf8'
name = file.replace /\..*/, '' # remove extension
templateJs += "window.#{name} = '#{contents}';"
Then prepend your concatenated JS with templateJs. Note that this assumes that there are no single quotes (') in the template. Either put backslashes in front of them or consistently use double quotes.
I have an application (Templify) that creates a templatized directory structure, but it seems to not be able to rename the "__NAME__" with what I've identified as the target.
This is fine if I can find a clean way to rename all files & directories with my replacement text.
I found a rename.pl method that renames files, and I found some code that removes underscores in file names and replaces it with spaces... but when I modify the code to put in my search terms, it never seems to work.
So, basically, I need to replace "__NAME__" with something like "Project-Name".
I'm happy to modify the search strings for each future reuse, but I'd love to figure out how to create a file to which I can pass ARGS.
I'm on XP and can use cygwin (cygwin doesn't seem to have 'rename' which makes it hard to locate linux-type solutions with using the function called 'rename'....)
I did find this which is easy to use for files in the current directory, but I don't know enough to tell it to recurse into sub-directories.
Any help would be great.
Thanks,
Scott
From cygwin:
find /cygdrive/c/mytree -type f | perl -ne 'rename $_, $1/Project-Name if m[^(.*)/__NAME__$]'
Or using python:
import os
for root, dirs, files in os.walk("C:\\mytree"):
for filename in files:
if filename == "__NAME__":
os.rename(os.path.join(root, filename), os.path.join(root, "Project-Name"))