How to display dependencies given in a makefile as a tree?
Clash Royale CLAN TAG#URR8PPP
Problem
I want to see the dependencies for one or more targets of a makefile. So I am looking for a program that can parse makefiles and then will represent the dependencies in some tree-like format (indentation, ascii-art, ...) or as a graph (dot, ...).
Similar
There are programs that do this for other situations:
pactree or debtree can display the dependencies for software packages in the respective format in a tree like ascii format or as adot
graph,gcc -M source_file.c
displays the dependencies of the C source file as a make rule,
pstree displays an ascii representation of the process tree.
Progress
Searching the web I found little help. That lead me to try
make --always-make --silent --dry-run some_target |
grep --extended-regexp 'Considering target file|Trying rule prerequisite'
but it looks like I have to hack some more parsing code in perl or python in order to represent this as a nice tree/graph. And I do not yet know if I will really get the full and correct graph this way.
Requirements
It would be nice to limit the graph in some ways (no builtin rule, only a given target, only some depth) but for the most part I am just looking for a tool that will give me the dependencies in some "reasonable", human-viewable format (like the programs under "Similar" do).
Questions
- Are there any programs that can do this?
- Will I get the full and correct information from
make -dnq ...
? - Is there a better way to get this info?
- Do scripts/attempts for parsing this info already exist?
text-processing make gnu-make
add a comment |
Problem
I want to see the dependencies for one or more targets of a makefile. So I am looking for a program that can parse makefiles and then will represent the dependencies in some tree-like format (indentation, ascii-art, ...) or as a graph (dot, ...).
Similar
There are programs that do this for other situations:
pactree or debtree can display the dependencies for software packages in the respective format in a tree like ascii format or as adot
graph,gcc -M source_file.c
displays the dependencies of the C source file as a make rule,
pstree displays an ascii representation of the process tree.
Progress
Searching the web I found little help. That lead me to try
make --always-make --silent --dry-run some_target |
grep --extended-regexp 'Considering target file|Trying rule prerequisite'
but it looks like I have to hack some more parsing code in perl or python in order to represent this as a nice tree/graph. And I do not yet know if I will really get the full and correct graph this way.
Requirements
It would be nice to limit the graph in some ways (no builtin rule, only a given target, only some depth) but for the most part I am just looking for a tool that will give me the dependencies in some "reasonable", human-viewable format (like the programs under "Similar" do).
Questions
- Are there any programs that can do this?
- Will I get the full and correct information from
make -dnq ...
? - Is there a better way to get this info?
- Do scripts/attempts for parsing this info already exist?
text-processing make gnu-make
1
The crucial thing to understand here is: Dependencies do NOT form a tree. They form a directed and (hopefully!) acyclic graph—also known as a DAG. Try sketching out the dependency graph for the following and you'll see it: A depends on B; A also depends on C; B depends on D; C depends on D.
– Wildcard
May 16 '16 at 19:24
@Wildcard I know but for my purpose it is enough to represent the dependencies as a tree. I am fine with duplicating subgraphs (and cutting at circles) to make it a tree. Sorry for not being explicit. For you example I would be fine with the output ofprintf 'An Bn Dn Cn Dn'
. (Who said I can't put newlines in comments? :)
– Lucas
May 16 '16 at 19:56
How would that be distinguishable from "A depends on B; B depends on D; D depends on C; A depends on D"? You can impose a total ordering on any DAG (since any DAG also represents a partial ordering), but you can't turn a DAG into a tree. This is basic graph theory. I would be interested to see your algorithm for creating a tree representation of a DAG which could then be displayed. Without such an underlying algorithm, any tool which sought to display dependencies as a tree would of necessity be extremely hacky and error-prone.
– Wildcard
May 16 '16 at 20:02
Maybe I was not explicit enough again but I thought the examples I give under Similar made it clear. I am not interested in graph theory (in this question at least). All I want for this is a visual representation that looks similar to a tree (especially if it should be displayed on a terminal, fordot
order graphs are obviously fine.) I will update the question a little to make it clearer (I hope).
– Lucas
May 16 '16 at 20:10
1
RANT: I'm honestly a little frustrated that make doesn't offer something like this out-of-the-box. Make is one of THE most wide-spread build systems in the world, and this feature would be so immensely useful that it is hard to grasp that during the God knows how many decades that make has existed no one added such a feature. Outputting this information in a clearly defined textual format would be totally sufficient. I understand that make is open source and I could always add this feature myself. And believe me, if make wasn't basically a black box to me, I would! RANT over.
– antred
Jul 27 '17 at 11:22
add a comment |
Problem
I want to see the dependencies for one or more targets of a makefile. So I am looking for a program that can parse makefiles and then will represent the dependencies in some tree-like format (indentation, ascii-art, ...) or as a graph (dot, ...).
Similar
There are programs that do this for other situations:
pactree or debtree can display the dependencies for software packages in the respective format in a tree like ascii format or as adot
graph,gcc -M source_file.c
displays the dependencies of the C source file as a make rule,
pstree displays an ascii representation of the process tree.
Progress
Searching the web I found little help. That lead me to try
make --always-make --silent --dry-run some_target |
grep --extended-regexp 'Considering target file|Trying rule prerequisite'
but it looks like I have to hack some more parsing code in perl or python in order to represent this as a nice tree/graph. And I do not yet know if I will really get the full and correct graph this way.
Requirements
It would be nice to limit the graph in some ways (no builtin rule, only a given target, only some depth) but for the most part I am just looking for a tool that will give me the dependencies in some "reasonable", human-viewable format (like the programs under "Similar" do).
Questions
- Are there any programs that can do this?
- Will I get the full and correct information from
make -dnq ...
? - Is there a better way to get this info?
- Do scripts/attempts for parsing this info already exist?
text-processing make gnu-make
Problem
I want to see the dependencies for one or more targets of a makefile. So I am looking for a program that can parse makefiles and then will represent the dependencies in some tree-like format (indentation, ascii-art, ...) or as a graph (dot, ...).
Similar
There are programs that do this for other situations:
pactree or debtree can display the dependencies for software packages in the respective format in a tree like ascii format or as adot
graph,gcc -M source_file.c
displays the dependencies of the C source file as a make rule,
pstree displays an ascii representation of the process tree.
Progress
Searching the web I found little help. That lead me to try
make --always-make --silent --dry-run some_target |
grep --extended-regexp 'Considering target file|Trying rule prerequisite'
but it looks like I have to hack some more parsing code in perl or python in order to represent this as a nice tree/graph. And I do not yet know if I will really get the full and correct graph this way.
Requirements
It would be nice to limit the graph in some ways (no builtin rule, only a given target, only some depth) but for the most part I am just looking for a tool that will give me the dependencies in some "reasonable", human-viewable format (like the programs under "Similar" do).
Questions
- Are there any programs that can do this?
- Will I get the full and correct information from
make -dnq ...
? - Is there a better way to get this info?
- Do scripts/attempts for parsing this info already exist?
text-processing make gnu-make
text-processing make gnu-make
edited May 16 '16 at 20:17
Lucas
asked May 16 '16 at 16:51
LucasLucas
1,998717
1,998717
1
The crucial thing to understand here is: Dependencies do NOT form a tree. They form a directed and (hopefully!) acyclic graph—also known as a DAG. Try sketching out the dependency graph for the following and you'll see it: A depends on B; A also depends on C; B depends on D; C depends on D.
– Wildcard
May 16 '16 at 19:24
@Wildcard I know but for my purpose it is enough to represent the dependencies as a tree. I am fine with duplicating subgraphs (and cutting at circles) to make it a tree. Sorry for not being explicit. For you example I would be fine with the output ofprintf 'An Bn Dn Cn Dn'
. (Who said I can't put newlines in comments? :)
– Lucas
May 16 '16 at 19:56
How would that be distinguishable from "A depends on B; B depends on D; D depends on C; A depends on D"? You can impose a total ordering on any DAG (since any DAG also represents a partial ordering), but you can't turn a DAG into a tree. This is basic graph theory. I would be interested to see your algorithm for creating a tree representation of a DAG which could then be displayed. Without such an underlying algorithm, any tool which sought to display dependencies as a tree would of necessity be extremely hacky and error-prone.
– Wildcard
May 16 '16 at 20:02
Maybe I was not explicit enough again but I thought the examples I give under Similar made it clear. I am not interested in graph theory (in this question at least). All I want for this is a visual representation that looks similar to a tree (especially if it should be displayed on a terminal, fordot
order graphs are obviously fine.) I will update the question a little to make it clearer (I hope).
– Lucas
May 16 '16 at 20:10
1
RANT: I'm honestly a little frustrated that make doesn't offer something like this out-of-the-box. Make is one of THE most wide-spread build systems in the world, and this feature would be so immensely useful that it is hard to grasp that during the God knows how many decades that make has existed no one added such a feature. Outputting this information in a clearly defined textual format would be totally sufficient. I understand that make is open source and I could always add this feature myself. And believe me, if make wasn't basically a black box to me, I would! RANT over.
– antred
Jul 27 '17 at 11:22
add a comment |
1
The crucial thing to understand here is: Dependencies do NOT form a tree. They form a directed and (hopefully!) acyclic graph—also known as a DAG. Try sketching out the dependency graph for the following and you'll see it: A depends on B; A also depends on C; B depends on D; C depends on D.
– Wildcard
May 16 '16 at 19:24
@Wildcard I know but for my purpose it is enough to represent the dependencies as a tree. I am fine with duplicating subgraphs (and cutting at circles) to make it a tree. Sorry for not being explicit. For you example I would be fine with the output ofprintf 'An Bn Dn Cn Dn'
. (Who said I can't put newlines in comments? :)
– Lucas
May 16 '16 at 19:56
How would that be distinguishable from "A depends on B; B depends on D; D depends on C; A depends on D"? You can impose a total ordering on any DAG (since any DAG also represents a partial ordering), but you can't turn a DAG into a tree. This is basic graph theory. I would be interested to see your algorithm for creating a tree representation of a DAG which could then be displayed. Without such an underlying algorithm, any tool which sought to display dependencies as a tree would of necessity be extremely hacky and error-prone.
– Wildcard
May 16 '16 at 20:02
Maybe I was not explicit enough again but I thought the examples I give under Similar made it clear. I am not interested in graph theory (in this question at least). All I want for this is a visual representation that looks similar to a tree (especially if it should be displayed on a terminal, fordot
order graphs are obviously fine.) I will update the question a little to make it clearer (I hope).
– Lucas
May 16 '16 at 20:10
1
RANT: I'm honestly a little frustrated that make doesn't offer something like this out-of-the-box. Make is one of THE most wide-spread build systems in the world, and this feature would be so immensely useful that it is hard to grasp that during the God knows how many decades that make has existed no one added such a feature. Outputting this information in a clearly defined textual format would be totally sufficient. I understand that make is open source and I could always add this feature myself. And believe me, if make wasn't basically a black box to me, I would! RANT over.
– antred
Jul 27 '17 at 11:22
1
1
The crucial thing to understand here is: Dependencies do NOT form a tree. They form a directed and (hopefully!) acyclic graph—also known as a DAG. Try sketching out the dependency graph for the following and you'll see it: A depends on B; A also depends on C; B depends on D; C depends on D.
– Wildcard
May 16 '16 at 19:24
The crucial thing to understand here is: Dependencies do NOT form a tree. They form a directed and (hopefully!) acyclic graph—also known as a DAG. Try sketching out the dependency graph for the following and you'll see it: A depends on B; A also depends on C; B depends on D; C depends on D.
– Wildcard
May 16 '16 at 19:24
@Wildcard I know but for my purpose it is enough to represent the dependencies as a tree. I am fine with duplicating subgraphs (and cutting at circles) to make it a tree. Sorry for not being explicit. For you example I would be fine with the output of
printf 'An Bn Dn Cn Dn'
. (Who said I can't put newlines in comments? :)– Lucas
May 16 '16 at 19:56
@Wildcard I know but for my purpose it is enough to represent the dependencies as a tree. I am fine with duplicating subgraphs (and cutting at circles) to make it a tree. Sorry for not being explicit. For you example I would be fine with the output of
printf 'An Bn Dn Cn Dn'
. (Who said I can't put newlines in comments? :)– Lucas
May 16 '16 at 19:56
How would that be distinguishable from "A depends on B; B depends on D; D depends on C; A depends on D"? You can impose a total ordering on any DAG (since any DAG also represents a partial ordering), but you can't turn a DAG into a tree. This is basic graph theory. I would be interested to see your algorithm for creating a tree representation of a DAG which could then be displayed. Without such an underlying algorithm, any tool which sought to display dependencies as a tree would of necessity be extremely hacky and error-prone.
– Wildcard
May 16 '16 at 20:02
How would that be distinguishable from "A depends on B; B depends on D; D depends on C; A depends on D"? You can impose a total ordering on any DAG (since any DAG also represents a partial ordering), but you can't turn a DAG into a tree. This is basic graph theory. I would be interested to see your algorithm for creating a tree representation of a DAG which could then be displayed. Without such an underlying algorithm, any tool which sought to display dependencies as a tree would of necessity be extremely hacky and error-prone.
– Wildcard
May 16 '16 at 20:02
Maybe I was not explicit enough again but I thought the examples I give under Similar made it clear. I am not interested in graph theory (in this question at least). All I want for this is a visual representation that looks similar to a tree (especially if it should be displayed on a terminal, for
dot
order graphs are obviously fine.) I will update the question a little to make it clearer (I hope).– Lucas
May 16 '16 at 20:10
Maybe I was not explicit enough again but I thought the examples I give under Similar made it clear. I am not interested in graph theory (in this question at least). All I want for this is a visual representation that looks similar to a tree (especially if it should be displayed on a terminal, for
dot
order graphs are obviously fine.) I will update the question a little to make it clearer (I hope).– Lucas
May 16 '16 at 20:10
1
1
RANT: I'm honestly a little frustrated that make doesn't offer something like this out-of-the-box. Make is one of THE most wide-spread build systems in the world, and this feature would be so immensely useful that it is hard to grasp that during the God knows how many decades that make has existed no one added such a feature. Outputting this information in a clearly defined textual format would be totally sufficient. I understand that make is open source and I could always add this feature myself. And believe me, if make wasn't basically a black box to me, I would! RANT over.
– antred
Jul 27 '17 at 11:22
RANT: I'm honestly a little frustrated that make doesn't offer something like this out-of-the-box. Make is one of THE most wide-spread build systems in the world, and this feature would be so immensely useful that it is hard to grasp that during the God knows how many decades that make has existed no one added such a feature. Outputting this information in a clearly defined textual format would be totally sufficient. I understand that make is open source and I could always add this feature myself. And believe me, if make wasn't basically a black box to me, I would! RANT over.
– antred
Jul 27 '17 at 11:22
add a comment |
3 Answers
3
active
oldest
votes
Try makefile2graph from the same author there is a a similar tool MakeGraphDependencies written in java
instead of c
.
make -Bnd | make2graph | dot -Tsvg -o out.svg
Then use some vector graphics editor to highlight connections you need.
1
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
add a comment |
I have found a kind of hack to at least output clearly structured information about which target depends on which prerequisites. The downside is, it's quite intrusive. In other words, you need to change your makefile to wrap the build recipes of all your targets into a little conditional function. I'll post a brief example:
getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))
VARIABLE_TARGET_NAME = foobar.txt
all : TopLevelTarget
TopLevelTarget : Target_A Target_D
$(call getRecipe,
@echo Building target $@)
Target_A : Target_B
$(call getRecipe,
@echo Building target $@)
Target_D : Target_C
$(call getRecipe,
@echo Building target $@)
Target_B : $(VARIABLE_TARGET_NAME)
$(call getRecipe,
@echo Building target $@)
Target_C :
$(call getRecipe,
@echo Building target $@)
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@)
In this example, I'm using the hand-rolled getRecipe function to wrap each individual target's recipe and then decide whether to actually run that recipe or simply output which target is being built and which prerequisites it depends on. The latter happens only if the variable DEPENDENCY_GRAPH
is set (e.g. as an environment variable). In the example, the build recipe is nothing more than an echo saying that the target is being built, but you could obviously replace this with a command of your choice.
With DEPENDENCY_GRAPH
set to 1, this results in the output:
Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"
which should be easy enough to parse and then convert into a dot-graph.
With DEPENDENCY_GRAPH
not set at all or set to 0, the output is:
Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget
or, in other words, the normal build recipe is used instead. I haven't tested yet whether this works reliably with complicated recipes. One problem I've already run into is that it doesn't work at all with multi-line recipes.
For instance, in the last target's build recipe, if in addition to saying that the target is being built I actually wanted to touch
the file:
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@
touch $@)
make
seems to think that the touch $@
part is merely part of the echo in the previous line:
Building target foobar.txt touch foobar.txt
If I leave off the trailing backslash in the previous line, make
complains *** unterminated call to function
call': missing )'. Stop.
If anyone has an idea how to get make
to play nice, I'm all ears. :)
EDIT: The other problem with this approach is that this will only work if no build results already exist, as make
obviously doesn't execute the build recipe of a target it considers up-to-date.
add a comment |
I used remake --profile (a drop-in replacement for make
), it generated a dependency tree in a callgrind format.
Then gprof2dot can generate an image of the target tree.
Do I understand the documentation wrong or doesremake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?
– Lucas
Jan 22 at 22:27
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Oh yea, something likeremake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.
– Lucas
Jan 22 at 22:33
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f283478%2fhow-to-display-dependencies-given-in-a-makefile-as-a-tree%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try makefile2graph from the same author there is a a similar tool MakeGraphDependencies written in java
instead of c
.
make -Bnd | make2graph | dot -Tsvg -o out.svg
Then use some vector graphics editor to highlight connections you need.
1
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
add a comment |
Try makefile2graph from the same author there is a a similar tool MakeGraphDependencies written in java
instead of c
.
make -Bnd | make2graph | dot -Tsvg -o out.svg
Then use some vector graphics editor to highlight connections you need.
1
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
add a comment |
Try makefile2graph from the same author there is a a similar tool MakeGraphDependencies written in java
instead of c
.
make -Bnd | make2graph | dot -Tsvg -o out.svg
Then use some vector graphics editor to highlight connections you need.
Try makefile2graph from the same author there is a a similar tool MakeGraphDependencies written in java
instead of c
.
make -Bnd | make2graph | dot -Tsvg -o out.svg
Then use some vector graphics editor to highlight connections you need.
edited Mar 23 '18 at 14:05
Sergei
1706
1706
answered May 16 '16 at 18:56
xaexae
1,40376
1,40376
1
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
add a comment |
1
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
1
1
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
I've tried that tool. Doesn't even begin to work (at least not for any of the make incarnations I tried it with). Most of the time it just poops out with some memory access violation.
– antred
Jul 27 '17 at 10:56
add a comment |
I have found a kind of hack to at least output clearly structured information about which target depends on which prerequisites. The downside is, it's quite intrusive. In other words, you need to change your makefile to wrap the build recipes of all your targets into a little conditional function. I'll post a brief example:
getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))
VARIABLE_TARGET_NAME = foobar.txt
all : TopLevelTarget
TopLevelTarget : Target_A Target_D
$(call getRecipe,
@echo Building target $@)
Target_A : Target_B
$(call getRecipe,
@echo Building target $@)
Target_D : Target_C
$(call getRecipe,
@echo Building target $@)
Target_B : $(VARIABLE_TARGET_NAME)
$(call getRecipe,
@echo Building target $@)
Target_C :
$(call getRecipe,
@echo Building target $@)
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@)
In this example, I'm using the hand-rolled getRecipe function to wrap each individual target's recipe and then decide whether to actually run that recipe or simply output which target is being built and which prerequisites it depends on. The latter happens only if the variable DEPENDENCY_GRAPH
is set (e.g. as an environment variable). In the example, the build recipe is nothing more than an echo saying that the target is being built, but you could obviously replace this with a command of your choice.
With DEPENDENCY_GRAPH
set to 1, this results in the output:
Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"
which should be easy enough to parse and then convert into a dot-graph.
With DEPENDENCY_GRAPH
not set at all or set to 0, the output is:
Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget
or, in other words, the normal build recipe is used instead. I haven't tested yet whether this works reliably with complicated recipes. One problem I've already run into is that it doesn't work at all with multi-line recipes.
For instance, in the last target's build recipe, if in addition to saying that the target is being built I actually wanted to touch
the file:
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@
touch $@)
make
seems to think that the touch $@
part is merely part of the echo in the previous line:
Building target foobar.txt touch foobar.txt
If I leave off the trailing backslash in the previous line, make
complains *** unterminated call to function
call': missing )'. Stop.
If anyone has an idea how to get make
to play nice, I'm all ears. :)
EDIT: The other problem with this approach is that this will only work if no build results already exist, as make
obviously doesn't execute the build recipe of a target it considers up-to-date.
add a comment |
I have found a kind of hack to at least output clearly structured information about which target depends on which prerequisites. The downside is, it's quite intrusive. In other words, you need to change your makefile to wrap the build recipes of all your targets into a little conditional function. I'll post a brief example:
getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))
VARIABLE_TARGET_NAME = foobar.txt
all : TopLevelTarget
TopLevelTarget : Target_A Target_D
$(call getRecipe,
@echo Building target $@)
Target_A : Target_B
$(call getRecipe,
@echo Building target $@)
Target_D : Target_C
$(call getRecipe,
@echo Building target $@)
Target_B : $(VARIABLE_TARGET_NAME)
$(call getRecipe,
@echo Building target $@)
Target_C :
$(call getRecipe,
@echo Building target $@)
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@)
In this example, I'm using the hand-rolled getRecipe function to wrap each individual target's recipe and then decide whether to actually run that recipe or simply output which target is being built and which prerequisites it depends on. The latter happens only if the variable DEPENDENCY_GRAPH
is set (e.g. as an environment variable). In the example, the build recipe is nothing more than an echo saying that the target is being built, but you could obviously replace this with a command of your choice.
With DEPENDENCY_GRAPH
set to 1, this results in the output:
Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"
which should be easy enough to parse and then convert into a dot-graph.
With DEPENDENCY_GRAPH
not set at all or set to 0, the output is:
Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget
or, in other words, the normal build recipe is used instead. I haven't tested yet whether this works reliably with complicated recipes. One problem I've already run into is that it doesn't work at all with multi-line recipes.
For instance, in the last target's build recipe, if in addition to saying that the target is being built I actually wanted to touch
the file:
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@
touch $@)
make
seems to think that the touch $@
part is merely part of the echo in the previous line:
Building target foobar.txt touch foobar.txt
If I leave off the trailing backslash in the previous line, make
complains *** unterminated call to function
call': missing )'. Stop.
If anyone has an idea how to get make
to play nice, I'm all ears. :)
EDIT: The other problem with this approach is that this will only work if no build results already exist, as make
obviously doesn't execute the build recipe of a target it considers up-to-date.
add a comment |
I have found a kind of hack to at least output clearly structured information about which target depends on which prerequisites. The downside is, it's quite intrusive. In other words, you need to change your makefile to wrap the build recipes of all your targets into a little conditional function. I'll post a brief example:
getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))
VARIABLE_TARGET_NAME = foobar.txt
all : TopLevelTarget
TopLevelTarget : Target_A Target_D
$(call getRecipe,
@echo Building target $@)
Target_A : Target_B
$(call getRecipe,
@echo Building target $@)
Target_D : Target_C
$(call getRecipe,
@echo Building target $@)
Target_B : $(VARIABLE_TARGET_NAME)
$(call getRecipe,
@echo Building target $@)
Target_C :
$(call getRecipe,
@echo Building target $@)
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@)
In this example, I'm using the hand-rolled getRecipe function to wrap each individual target's recipe and then decide whether to actually run that recipe or simply output which target is being built and which prerequisites it depends on. The latter happens only if the variable DEPENDENCY_GRAPH
is set (e.g. as an environment variable). In the example, the build recipe is nothing more than an echo saying that the target is being built, but you could obviously replace this with a command of your choice.
With DEPENDENCY_GRAPH
set to 1, this results in the output:
Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"
which should be easy enough to parse and then convert into a dot-graph.
With DEPENDENCY_GRAPH
not set at all or set to 0, the output is:
Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget
or, in other words, the normal build recipe is used instead. I haven't tested yet whether this works reliably with complicated recipes. One problem I've already run into is that it doesn't work at all with multi-line recipes.
For instance, in the last target's build recipe, if in addition to saying that the target is being built I actually wanted to touch
the file:
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@
touch $@)
make
seems to think that the touch $@
part is merely part of the echo in the previous line:
Building target foobar.txt touch foobar.txt
If I leave off the trailing backslash in the previous line, make
complains *** unterminated call to function
call': missing )'. Stop.
If anyone has an idea how to get make
to play nice, I'm all ears. :)
EDIT: The other problem with this approach is that this will only work if no build results already exist, as make
obviously doesn't execute the build recipe of a target it considers up-to-date.
I have found a kind of hack to at least output clearly structured information about which target depends on which prerequisites. The downside is, it's quite intrusive. In other words, you need to change your makefile to wrap the build recipes of all your targets into a little conditional function. I'll post a brief example:
getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))
VARIABLE_TARGET_NAME = foobar.txt
all : TopLevelTarget
TopLevelTarget : Target_A Target_D
$(call getRecipe,
@echo Building target $@)
Target_A : Target_B
$(call getRecipe,
@echo Building target $@)
Target_D : Target_C
$(call getRecipe,
@echo Building target $@)
Target_B : $(VARIABLE_TARGET_NAME)
$(call getRecipe,
@echo Building target $@)
Target_C :
$(call getRecipe,
@echo Building target $@)
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@)
In this example, I'm using the hand-rolled getRecipe function to wrap each individual target's recipe and then decide whether to actually run that recipe or simply output which target is being built and which prerequisites it depends on. The latter happens only if the variable DEPENDENCY_GRAPH
is set (e.g. as an environment variable). In the example, the build recipe is nothing more than an echo saying that the target is being built, but you could obviously replace this with a command of your choice.
With DEPENDENCY_GRAPH
set to 1, this results in the output:
Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"
which should be easy enough to parse and then convert into a dot-graph.
With DEPENDENCY_GRAPH
not set at all or set to 0, the output is:
Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget
or, in other words, the normal build recipe is used instead. I haven't tested yet whether this works reliably with complicated recipes. One problem I've already run into is that it doesn't work at all with multi-line recipes.
For instance, in the last target's build recipe, if in addition to saying that the target is being built I actually wanted to touch
the file:
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,
@echo Building target $@
touch $@)
make
seems to think that the touch $@
part is merely part of the echo in the previous line:
Building target foobar.txt touch foobar.txt
If I leave off the trailing backslash in the previous line, make
complains *** unterminated call to function
call': missing )'. Stop.
If anyone has an idea how to get make
to play nice, I'm all ears. :)
EDIT: The other problem with this approach is that this will only work if no build results already exist, as make
obviously doesn't execute the build recipe of a target it considers up-to-date.
edited Mar 17 '18 at 23:50
Rui F Ribeiro
40k1479135
40k1479135
answered Jul 27 '17 at 12:54
antredantred
1213
1213
add a comment |
add a comment |
I used remake --profile (a drop-in replacement for make
), it generated a dependency tree in a callgrind format.
Then gprof2dot can generate an image of the target tree.
Do I understand the documentation wrong or doesremake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?
– Lucas
Jan 22 at 22:27
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Oh yea, something likeremake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.
– Lucas
Jan 22 at 22:33
add a comment |
I used remake --profile (a drop-in replacement for make
), it generated a dependency tree in a callgrind format.
Then gprof2dot can generate an image of the target tree.
Do I understand the documentation wrong or doesremake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?
– Lucas
Jan 22 at 22:27
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Oh yea, something likeremake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.
– Lucas
Jan 22 at 22:33
add a comment |
I used remake --profile (a drop-in replacement for make
), it generated a dependency tree in a callgrind format.
Then gprof2dot can generate an image of the target tree.
I used remake --profile (a drop-in replacement for make
), it generated a dependency tree in a callgrind format.
Then gprof2dot can generate an image of the target tree.
answered Jan 22 at 19:46
Victor SergienkoVictor Sergienko
22025
22025
Do I understand the documentation wrong or doesremake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?
– Lucas
Jan 22 at 22:27
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Oh yea, something likeremake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.
– Lucas
Jan 22 at 22:33
add a comment |
Do I understand the documentation wrong or doesremake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?
– Lucas
Jan 22 at 22:27
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Oh yea, something likeremake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.
– Lucas
Jan 22 at 22:33
Do I understand the documentation wrong or does
remake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?– Lucas
Jan 22 at 22:27
Do I understand the documentation wrong or does
remake --profile
only output the dependency graph for the target it executes? Or can it somehow output the graph for all targets?– Lucas
Jan 22 at 22:27
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Only the one it runs, I’m afraid. But you can run them all with —dry-run
– Victor Sergienko
Jan 22 at 22:28
Oh yea, something like
remake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.– Lucas
Jan 22 at 22:33
Oh yea, something like
remake --targets -r | grep -v %| grep -v 't*.'|xargs remake -n --profile -B
looks promising.– Lucas
Jan 22 at 22:33
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f283478%2fhow-to-display-dependencies-given-in-a-makefile-as-a-tree%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
The crucial thing to understand here is: Dependencies do NOT form a tree. They form a directed and (hopefully!) acyclic graph—also known as a DAG. Try sketching out the dependency graph for the following and you'll see it: A depends on B; A also depends on C; B depends on D; C depends on D.
– Wildcard
May 16 '16 at 19:24
@Wildcard I know but for my purpose it is enough to represent the dependencies as a tree. I am fine with duplicating subgraphs (and cutting at circles) to make it a tree. Sorry for not being explicit. For you example I would be fine with the output of
printf 'An Bn Dn Cn Dn'
. (Who said I can't put newlines in comments? :)– Lucas
May 16 '16 at 19:56
How would that be distinguishable from "A depends on B; B depends on D; D depends on C; A depends on D"? You can impose a total ordering on any DAG (since any DAG also represents a partial ordering), but you can't turn a DAG into a tree. This is basic graph theory. I would be interested to see your algorithm for creating a tree representation of a DAG which could then be displayed. Without such an underlying algorithm, any tool which sought to display dependencies as a tree would of necessity be extremely hacky and error-prone.
– Wildcard
May 16 '16 at 20:02
Maybe I was not explicit enough again but I thought the examples I give under Similar made it clear. I am not interested in graph theory (in this question at least). All I want for this is a visual representation that looks similar to a tree (especially if it should be displayed on a terminal, for
dot
order graphs are obviously fine.) I will update the question a little to make it clearer (I hope).– Lucas
May 16 '16 at 20:10
1
RANT: I'm honestly a little frustrated that make doesn't offer something like this out-of-the-box. Make is one of THE most wide-spread build systems in the world, and this feature would be so immensely useful that it is hard to grasp that during the God knows how many decades that make has existed no one added such a feature. Outputting this information in a clearly defined textual format would be totally sufficient. I understand that make is open source and I could always add this feature myself. And believe me, if make wasn't basically a black box to me, I would! RANT over.
– antred
Jul 27 '17 at 11:22