Vim run project specific make with key command? - vim

I'm working on a compiled project in Vim (Typescript). make % will build an individual file. I use this to check for errors. This is great for error checking, but it creates compiled files next to the source files that I don't need.
For my actual build process, I have a single command that compiles everything. This is in a Makefile.
I'd like to be able to map a key command to "build my whole project" in a generic way, so if I'm editing any .ts file underneath my project directory, it runs that specific command.
How can I do this?

The trick would be to actually use a Makefile:
all: complete.exe
complete.exe: *.ts
somecompilation-command $^ -o $#
This way, you can just leave makeprg at 'make':
:set makeprg&
And happily do:
:mak

Related

MakeFile is not glowing like it is Executable

This is the code that i have written in my makefile. For some reason it is not letting me execute the make function. When i type "make findName", i get "make: 'findName' is up to date."
findName: findName.cpp
g++ -g findName.cpp -o findName;
clean:
/bin/rm -f findName *.o
backup:
#tar -zcvf bbrown.assignment4_1.tar.gz *.cpp *.h makeFile readme # will make a tar.gz
tar -cvf bbrown.findName.tar *.cpp *.sh makeFile readme
A message like "make: 'target' is up to date." means that make has decided it doesn't need to run any commands, based on the timestamps of files involved. The make program considers files (and phony targets) to have a tree of prerequisites, and commands associated with creating a file will only be run if the file doesn't exist or has an older timestamp than one of its prerequisites. In big projects, this helps avoid completely rebuilding everything which could take a lot of time, when only a few source files have actually changed: make will determine which commands are actually needed. But this does require setting up the Makefile with accurate prerequisites.
Your Makefile specifies that file findName has one prerequisite: findName.cpp. If make successfully creates findName, then you do nothing else but just type make again, you'll see the "up to date" message: this is a feature. If you edit and save findName.cpp and then run make, it should repeat the g++ command.
But suppose you also have some header files you're including from findName.cpp, say findName.h. If you edit and save findName.h and then run make, you'll get "up to date", since make didn't know to findName.h has effects on findName. You would need to add the prerequisite to fix this:
findName: findName.cpp findName.h
g++ -g findName.cpp -o findName
There are various ways to automatically deal with header dependencies like that, but they get into more advanced use of make, and/or using other build tools.

SCons -- target that "deletes" a file?

Is there a simple way in SCons to create a target which is considered up-to-date if the named file is verified not to exist? (And of course, to have a builder which deletes the file if it does exist...)
For instance:
b_file = env.Command("files", ["file1", "file2", "file3"],
"build-files -o $TARGET $SOURCES")
env.Depends(b_file,env.FileMustNotExist("file4"))
The idea would be that before building "files", SCons would make sure not only that "file1", "file2", and "file3" are present, but that "file4" does not exist.
I know that for this particular case I could approximate what I want by adding "rm -f file4; " to the beginning of the command, but that's not exactly the same. In particular, if I add the "rm" command to the builder, and then create "file4" outside of SCons, re-running SCons won't delete "file4" unless one of the other sources has changed.
I'd want something such that creating "file4" and re-running SCons would result in simply deleting "file4" and indicating that "files" is now built.
To my knowledge this is not foreseen in the design, and therefore not possible. Note how SCons is a file-oriented build system, so its main task is to create files...and not deleting them.
In newer versions there is the Pseudo target, which is intended for build actions that don't create an actual output file...but it's not able to delete files, if I remember correctly.
So, it looks as if the "rm -f file" strategy is still the best way to go. You might want to use Python's os.path.isfile and os.unlink though, to stay compatible over the different platforms.

how to specify in a makefile where to send the results too

Right now I have a makefile that build the .tex file (latex) in the same directory as it and spits out a pdf version of that file and also a bunch of baggage with it. I was wondering how to specify in the make file where to send the result. I want to send the results to my desktop directory. Is this at all possible? Also I used the clean function to get rid of the auto-generated garbage files but it still spits them out. any help on that?
PDFLATEX=/usr/texbin/pdflatex
SOURCE=report_Template.tex
RESULT=report_Template.pdf
$(RESULT): $(SOURCE)
$(PDFLATEX) $(SOURCE)
$(PDFLATEX) $(SOURCE)
clean:
rm -f $(RESULT) *.aux *.log *.toc *.out *~
This isn't something make has anything to do with. The commands you run put their output where you tell them to.
It appears that pdflatex creates the output next to the input so in whatever directory you run it (and the makefile) from.
You can add a cp to the end of that rule to copy the file wherever you want and/or see if pdflatex has an argument that can be given for output filename.
That being said if your make target rule doesn't create the target filename exactly that's a poor rule and might cause you trouble in larger make setups. (This is what .PHONY rules are for in part.)
clean is not magic. It is simply a target like any other. You need to run it for it to do anything.

Managing multiple makefiles in vim

I would like to effectively manage different project in Vim. When it is time to rebuild I have several Makefiles in different locations. In Vim if I use :make it will try to compile the Makefile in my current location.
I can use or :make -f URL-MAKEFILE but it's too much work. Is there a way or a plugin to build all those separate makefile in an efficient way without me remebering all Makefile url?
You can instruct vim to find a "Makefile" file upwards in your directory structure, then call :make with it
:exec ":make -f " . findfile("Makefile", ".;")
That way it will call the Makefile related to the project tree of the buffer currently open.
However, I'd advise not to use make -f path_to_makefile that much, because it launches the make command inside the directory where you are. Usually Makefiles are written to be used at the top of your project tree (and then eventually call more Makefile in the subdirectories), so it's more natural to call "make -C path_to_top_of_tree"
To find the first directory upward with a Makefile in it then call :make -C with it:
:exec ":make -C " . fnamemodify(findfile("Makefile", ".;"), ":h")
Don't know if there is a such plugin, but you can create a kind of a shortcuts for your URLs.
Create main makefile and add targets such:
.PHONY : shortcut
make -f URL target
Afterwards you can just call :make shortcut
I'm maintaining multiple projects, each one having its own makefile with one of the numerous local_vimrc scripts.
Actually I'm also encapsulating the update of the &makeprg option with my BuildToolsWrapper plugin (prefer Vim-Addons-Manager to install it). It goes further and enables me to choose the compilation directory and other options (which is quite useful when the makefile has been generated with CMake). See the two *.vim files here to see how I configure my projects.

Update include path in linux

I have few header files in /my/path/to/file folder. I know how to include these files in new C program but everytime I need to type full path to header file before including it. Can I set some path variable in linux such that it automatically looks for header files ?
You could create a makefile. A minimal example would be:
INC_PATH=/my/path/to/file
CFLAGS=-I$(INC_PATH)
all:
gcc $(CFLAGS) -o prog src1.c src2.c
From here you could improve this makefile in many ways. The most important, probably, would be to state compilation dependencies (so only modified files are recompiled).
As a reference, here you have a link to the GNU make documentation.
If you do not want to use makefiles, you can always set an environment variable to make it easier to type the compilation command:
export MY_INC_PATH=/my/path/to/file
Then you could compile your program like:
gcc -I${MY_INC_PATH} -o prog src1.c src2.c ...
You may want to define MY_INC_PATH variable in the file .bashrc, or probably better, create a file in a handy place containing the variable definition. Then, you could use source to set that variable in the current shell:
source env.sh
I think, however, that using a makefile is a much preferable approach.
there is a similar question and likely better solved (if you are interested in a permanent solution): https://stackoverflow.com/a/558819/1408096
Try setting C_INCLUDE_PATH (for C header files) or CPLUS_INCLUDE_PATH (for C++ header files).
Kudos:jcrossley3
I'm not in Linux right now and I can't be bothered to reboot to check if everything's right, but have you tried making symbolic links? For example, if you are on Ubuntu:
$ cd /usr/include
$ sudo ln -s /my/path/to/file mystuff
So then when you want to include stuf, you can use:
#include <mystuff/SpamFlavours.h>

Resources