Cross-posted from StackOverflow]
I am trying to define a build system command which specifies some target derived directly from the current file open in the editor, but using a project-relative path rather than the absolute path to the file.
How is it possible to use snippet variables in a build rule to describe the relative path to the current $file
from the project root?
[size=150]Example[/size]
For example, assume a simple Makefile which defines rules for *.o
in terms of *.c
, and a project containing such source files spread over multiple subdirectories.
It is useful to be able to define a build command which runs make
with a target derived from the current file, like:
make ${file/\\.c/\\.o/}
but Makefile targets nearly always use relative paths, while $file
and other such variables have absolute paths (or no path prefix at all). Because of this, the above command will not match any known rules in the Makefile, while $file_name
, alone, does not include any local directories between the Makefile and the target (${project_path}/abc/def.c
just becomes def.c
not the complete local path abc/def.c
which make
would understand).
How is it possible to expand a variable to get the project-relative path of the current $file
?
[size=150]A failed attempt[/size]
It does not seem possible to nest variables inside the regex terms of another variable expansion. For example, this does not work:
# delete the project path prefix of $file by replacing it with "":
${file/${project_path}//}
let alone this:
# delete the project path prefix of $file by replacing it with "",
# then replace .c with .o to get the target:
${${file/${project_path}//}/.c/.o/}
Aside
I realize in the simple case of compiling trivial C files to corresponding objects, I could rewrite the compile rule directly as a build system command operating directly on the absolute file paths. This is what most of the built-in build systems do. But assume that my build rules are complex and involve multiple steps, but that I still have a bunch of related targets corresponding to each input file I might be editing. (The actual case I’m working on is not, in fact, C compilation to object files.)