Re: Conditional recipe execution
>> * I need to split an input file into several smaller files. > > I don't see any way that $(eval ...) is needed or helpful for any of > those things. Can a make variable be set by this function within a recipe? >> I imagine that conditional evaluation of recipes will be possible somehow, >> wont it? > > I don't know what you mean by this question; if you mean that a recipe > should make a decision and do different things, then typically you would > use _shell_ conditional statements for this: How should it be achieved that a recipe will only be executed for its first run despite of the detail that multiple targets were specified for a specific rule? > There are other possibilities, but without a specific use-case we can't > say which one(s) are appropriate. Would use cases around the standard command "split" be concrete enough for further clarification? https://en.wikipedia.org/wiki/Split_%28Unix%29 Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
On Mon, 2015-01-19 at 00:08 +0100, SF Markus Elfring wrote: > >> * I need to split an input file into several smaller files. > > > > I don't see any way that $(eval ...) is needed or helpful for any of > > those things. > > Can a make variable be set by this function within a recipe? Yes, I've already said it can. But I can see no way that this ability is helpful or needed in the situations you listed. If you give examples of what you're actually trying to do, instead of just providing very general questions and abstract situations, then we can use concrete examples to explain. > How should it be achieved that a recipe will only be executed for its first > run despite of the detail that multiple targets were specified for > a specific rule? > > There are other possibilities, but without a specific use-case we can't > > say which one(s) are appropriate. > > Would use cases around the standard command "split" be concrete enough > for further clarification? > https://en.wikipedia.org/wiki/Split_%28Unix%29 No. You need to describe your situation. Use words, but with detail. "I have a command foo that takes as input bar and generates as output baz. Then I have another command that takes baz as input and generates a widget, and I need to figure out how to ...", etc. If you have implemented a rule and it doesn't work, then paste the rule into your email and cut/paste the output you're getting, and describe why that output is wrong / what you wanted to happen instead. If it's very complicated, then write a small example makefile that does the same type of thing and shows the same problem, and put that in your email. Just writing down what you're trying to do like this in an email can often help you figure things out for yourself, before you even send it. It sounds to me like you what you mean is you have a single recipe which generates multiple output files and you want those files to be prerequisites of other targets. There are two possibilities. The best case is that the generated files and the input file(s) are all related to each other through some aspect of the filename: in that case you can use pattern rules and everything is simple. So for example the "bison" parser generator takes a file "foo.y" and generates "foo.tab.h" and "foo.tab.c": the names of the output files are related to the name of the input file through the "foo" prefix. In this case you can use: %.tab.h %.tab.c : %.y command ... replacing the common part with "%" as a wildcard. Now listing "foo.tab.c" or "foo.tab.h" as a prerequisite will cause this rule to be run one time, with "foo.y" as the prerequisite and make knows both files are generated by a single invocation. The other possibility is that the names of the generated files have no relationship to the names of the input files. In this case you'll have to use a "sentinel file": output list: .sentinel ; .sentinel: input files command ... touch $@ ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
>> Would use cases around the standard command "split" be concrete enough >> for further clarification? >> https://en.wikipedia.org/wiki/Split_%28Unix%29 > > No. I am bit surprised that you find such a tool as an unclear example at the moment. I am using my Python script which I developed as a contribution for a discussion around the topic 'Splitting search results from a "find -print0'. http://lists.gnu.org/archive/html/coreutils/2015-01/msg00023.html > You need to describe your situation. Use words, but with detail. I would like to perform some file searches. The found files should be analysed by dedicated programs. A couple of programs which I use for corresponding data processing are still single-threaded. But I want to get all processor cores working on the search result. So I split it into smaller files which I can give to each core as a work unit. Is this approach just an ordinary parallel work flow? > It sounds to me like you what you mean is you have a single recipe which > generates multiple output files and you want those files to be > prerequisites of other targets. Yes, exactly. > There are two possibilities. The best case is that the generated files > and the input file(s) are all related to each other through some aspect > of the filename: I have found that there are some software development challenges to consider for safe parallel data processing. > in that case you can use pattern rules and everything is simple. I noticed a situation where such "a special case" needs to be detected. A recipe was executed multiple times by the tool "make" for each passed target. > So for example the "bison" parser generator takes a file "foo.y" and > generates "foo.tab.h" and "foo.tab.c": the names of the output files are > related to the name of the input file through the "foo" prefix. This is another well-known use case. > Now listing "foo.tab.c" or "foo.tab.h" as a prerequisite will cause this > rule to be run one time, with "foo.y" as the prerequisite and make knows > both files are generated by a single invocation. Are there any cases left over where the make tool will interpret a rule specification in the way that "a single invocation" is not sufficient? > The other possibility is that the names of the generated files have no > relationship to the names of the input files. There is a relationship of course. But make file pattern operators can be inappropriate in some cases of my build scripts. > In this case you'll have to use a "sentinel file": > > output list: .sentinel ; I would interpret this specification as a rule with an empty recipe. How does this approach help? Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
> You need to describe your situation. Use words, but with detail. I have adjusted my build scripts. Now I wonder about another error message for a recipe. parallel-inc.make:95: *** unterminated call to function 'info': missing ')'. Stop. Corresponding excerpt Lines 91 - 101: … $(RESULT_FUNCTIONS_WITH_PREFIX1_PARALLEL) \ $(RESULT_SQL_DATABASE_NOTIFICATION8): \ initialise_database \ $(RESULT_SQL_DATABASE_NOTIFICATION4) $(info $(if $(LET_RUN_DATA_EXPORT1_PARALLEL),\ $(eval LET_RUN_DATA_EXPORT1_PARALLEL::=)@$(RM) '$(RESULT_SQL_DATABASE_NOTIFICATION8)' $(DATABASE_CLI) -c \ '$(SQL_SELECT_START)_parallel1 where static = 0 $(SQL_SELECT_END)' \ '$(DATABASE_NAME)' \ > '$(RESULT_FUNCTIONS_WITH_PREFIX_PARALLEL)' \ && $(TOUCH) '$(RESULT_SQL_DATABASE_NOTIFICATION8)')) … How should such a test rule be improved? Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
On Fri, 2015-01-23 at 20:38 +0100, SF Markus Elfring wrote: > > You need to describe your situation. Use words, but with detail. > > I have adjusted my build scripts. Now I wonder about another > error message for a recipe. > > parallel-inc.make:95: *** unterminated call to function 'info': missing ')'. > Stop. I think the message is pretty clear: you're missing the end parenthesis ")" to the info function which starts at line 95: > $(info $(if $(LET_RUN_DATA_EXPORT1_PARALLEL),\ > $(eval LET_RUN_DATA_EXPORT1_PARALLEL::=)@$(RM) > '$(RESULT_SQL_DATABASE_NOTIFICATION8)' You can see that you open both an $(info ... and $(if ... function here, and you don't close either of them (missing end-parens). What are you confused about? ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
>> parallel-inc.make:95: *** unterminated call to function 'info': missing ')'. >> Stop. > > I think the message is pretty clear: you're missing the end parenthesis > ")" to the info function which starts at line 95: I read my make rule in the way that the closing parentheses is really not on the line 95. But it should be found on the line 101. …_NOTIFICATION8)')) > You can see that you open both an $(info ... and $(if ... function here, > and you don't close either of them (missing end-parens). The editor from the tool "KDevelop 4.7.0-2.1" gives me an other indication for the affected file. Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
On Fri, 2015-01-23 at 21:56 +0100, SF Markus Elfring wrote: > >> parallel-inc.make:95: *** unterminated call to function 'info': > missing ')'. Stop. > > > > I think the message is pretty clear: you're missing the end parenthesis > > ")" to the info function which starts at line 95: > > I read my make rule in the way that the closing parentheses > is really not on the line 95. The error doesn't mean that the closing parentheses is missing from line 95, it means that the open parenthesis that it didn't match was the "info" function on line 95. > But it should be found on the line 101. > …_NOTIFICATION8)')) If you want that then you need a backslash at the end of line 96, to continue the logical line: > > $(info $(if $(LET_RUN_DATA_EXPORT1_PARALLEL),\ > > $(eval LET_RUN_DATA_EXPORT1_PARALLEL::=)@$(RM) > > '$(RESULT_SQL_DATABASE_NOTIFICATION8)' Make never looks across logical lines to complete variable or function so you have to combine them into a single logical line with backslashes. ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
> The error doesn't mean that the closing parentheses is missing from line 95, I understand this information part. > it means that the open parenthesis that it didn't match was the > "info" function on line 95. I find this detail hard to believe. I hope that the current KDevelop editor does not misguide me. The parentheses pairs are found there as expected. Do you read the shown rule example eventually in the way that its recipe does not end with "…_NOTIFICATION8)'))"? > If you want that then you need a backslash at the end of line 96, to > continue the logical line: I find that a backslash would not be needed at this place if would like to keep the "RM command" on a separate logical line. >>> $(info $(if $(LET_RUN_DATA_EXPORT1_PARALLEL),\ >>> $(eval LET_RUN_DATA_EXPORT1_PARALLEL::=)@$(RM) >>> '$(RESULT_SQL_DATABASE_NOTIFICATION8)' > > Make never looks across logical lines to complete variable or function > so you have to combine them into a single logical line with backslashes. Do I expect more functionality here than what is actually provided so far? Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
On Fri, 2015-01-23 at 22:24 +0100, SF Markus Elfring wrote: > > it means that the open parenthesis that it didn't match was the > > "info" function on line 95. > > I find this detail hard to believe. > > I hope that the current KDevelop editor does not misguide me. The parentheses > pairs are found there as expected. Then KDevelop is wrong. It appears that KDevelop's "makefile" editing mode doesn't properly handle backslash continuations. > Do you read the shown rule example eventually in the way that its recipe > does not end with "…_NOTIFICATION8)'))"? The _RULE_ does end with it, because the rule includes all the recipe lines that appear after the target. But variable/function invocations cannot span different lines of a recipe. They all must be contained within the same logical line, as I mentioned before. This is trivial to try out for yourself (like most things in make); just write a simple makefile: $ cat > Makefile < > If you want that then you need a backslash at the end of line 96, to > > continue the logical line: > > I find that a backslash would not be needed at this place if would like to > keep the "RM command" on a separate logical line. It is definitely needed. As I've said, it is not possible for a single variable or function reference to span multiple logical lines. If you want to do this you have to use define/endef to create a variable that contains newlines, then use the variable in the recipe; see example below. I'm really not at all sure why you're using $(info ...) here... it won't actually do anything if you do that. define RUN_PARALLEL $(eval LET_RUN_DATA_EXPORT1_PARALLEL::=)@$(RM) '$(RESULT_SQL_DATABASE_NOTIFICATION8)' $(DATABASE_CLI) -c \ '$(SQL_SELECT_START)_parallel1 where static = 0 $(SQL_SELECT_END)' \ '$(DATABASE_NAME)' \ > '$(RESULT_FUNCTIONS_WITH_PREFIX_PARALLEL)' \ && $(TOUCH) '$(RESULT_SQL_DATABASE_NOTIFICATION8)' endef $(RESULT_FUNCTIONS_WITH_PREFIX1_PARALLEL) \ $(RESULT_SQL_DATABASE_NOTIFICATION8): \ initialise_database \ $(RESULT_SQL_DATABASE_NOTIFICATION4) $(info $(if $(LET_RUN_DATA_EXPORT1_PARALLEL),$(RUN_PARALLEL))) ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
> It appears that KDevelop's "makefile" editing mode doesn't properly > handle backslash continuations. This tool might still have got few open issues around improved handling of the make file syntax. But I find that its visual feedback was appropriate for parentheses pairs at least. >> Do you read the shown rule example eventually in the way that its recipe >> does not end with "…_NOTIFICATION8)'))"? > > The _RULE_ does end with it, because the rule includes all the recipe > lines that appear after the target. Thanks for your acknowledgement. > But variable/function invocations cannot span different lines of a recipe. > They all must be contained within the same logical line, as I mentioned > before. My knowledge was incomplete on this detail. I did not get the information from the description (in the manual) for the used conditional function that it does not support the inclusion of several logical lines so far. I am sorry if did not pay enough attention on this aspect. >> I find that a backslash would not be needed at this place if would like to >> keep the "RM command" on a separate logical line. > > It is definitely needed. As I've said, it is not possible for a single > variable or function reference to span multiple logical lines. Are there any chances to lift this restriction for make functions? > If you want to do this you have to use define/endef to create a variable > that contains newlines, then use the variable in the recipe; > see example below. I hoped somehow that another level of data indirection could be avoided. > I'm really not at all sure why you're using $(info ...) here... The error message looked "a bit nicer" than a complaint on a shorter "if". > it won't actually do anything if you do that. It prints the generated recipe at least after the addition of the backslash you recommended, doesn't it? It seems that I had just another inappropriate expectation for the handling of a line continuation here. I thank you very much for this quick clarification. Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
On Fri, 2015-01-23 at 23:17 +0100, SF Markus Elfring wrote: > >> I find that a backslash would not be needed at this place if would like to > >> keep the "RM command" on a separate logical line. > > > > It is definitely needed. As I've said, it is not possible for a single > > variable or function reference to span multiple logical lines. > > Are there any chances to lift this restriction for make functions? It's very unlikely. The entire implementation of the parser in make at its most basic level is completely line-oriented. It would be quite a bit of code change to change this behavior. > > If you want to do this you have to use define/endef to create a variable > > that contains newlines, then use the variable in the recipe; > > see example below. > > I hoped somehow that another level of data indirection could be avoided. To be honest, based on what I've seen, you could do with a few more levels of indirection. The rules you've presented here are (to me) almost impossible to read. Abstracting some of these longer and more complex contents into other variable assignments might help make the structure of the makefile more clear. Maybe. In any event you don't have a choice, if you want to keep this behavior. > > I'm really not at all sure why you're using $(info ...) here... > > The error message looked "a bit nicer" than a complaint on a shorter "if". > > > it won't actually do anything if you do that. > > It prints the generated recipe at least after the addition of the backslash > you recommended, doesn't it? It prints the recipe, but cannot run the recipe, because the result of expanding the $(info ...) function is the empty string. So after make expands the recipe everything printed by $(info ...) is gone (it went to stdout) and make won't actually run those commands. ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
>> I hoped somehow that another level of data indirection could be avoided. > > To be honest, based on what I've seen, you could do with a few more > levels of indirection. My knowledge around GNU make usage is evolving. > The rules you've presented here are (to me) almost impossible to read. Interesting … > Abstracting some of these longer and more complex contents into other > variable assignments might help make the structure of the makefile > more clear. I guess that this view can also become a matter of taste. I could develop a complete make function library to achieve a better design. Can it eventually become harder then to understand the relationships within a bigger build script collection? Would to like to point to any examples which demonstrate the kind of software abstraction level that you would prefer? >> It prints the generated recipe at least after the addition of the backslash >> you recommended, doesn't it? > > It prints the recipe, I needed this debug output for a moment. > but cannot run the recipe, because the result of expanding the $(info ...) > function is the empty string. I know that. I found that it would help a bit in our clarification of implementation details. Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make
Re: Conditional recipe execution
> But a quick check of your link above shows no comments or anything > in the makefile describing what it does, Thanks for your look at my example. > and I don't really understand the purpose behind all these recipes > which consist of if-statements where the body of the recipe is made empty > if variables are not set. It is my approach for recipe execution guards. I hope that such conditions are sufficient to let the affected recipes only run for a single target despite of the specification of several output files there. Some targets will not usually work together with the make command-line option "-j" if a corresponding value was passed that is greater than one for such a parameter. > I will also mention that I see you using various bash-specific shell > features (e.g., 'XY=$${XY/|/ }'), but I don't see any setting of "SHELL > = /bin/bash" in your makefile; unless you do this then your makefiles > will fail on any system where /bin/sh (which is the default setting for > SHELL in make) is not bash; Thanks for your reminder. Are there any more programs which support text replacement within content from "shell variables" directly? Regards, Markus ___ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make