What's "auto" value in "AC_ARG_ENABLE"? - configure

I've been checking whether which files of some open source components are used during compile.
But, I don't know well about autotools, autoconf, etc.. so, I want to know the "auto" value means in AC_ARG_ENABLE(). Here is an example.
AC_ARG_ENABLE(launchd, AS_HELP_STRING(--description--),enable_launchd=$enableval,enable_launchd=auto)
If "--enable-launchd" option is given, run the command "enable_launchd=$enableval", right??
But if not, run the command "enable_lauchd=auto".
What is a value of the "auto"?

If "--enable-launchd" option is given, run the command
"enable_launchd=$enableval", right??
Right.
But if not, run the command
"enable_lauchd=auto".
Yes.
What is a value of the "auto"?
"auto" has no significance in that command other than as itself. It is the value assigned to variable enable_launchd.
You may well find that configure.ac later checks for that value and performs additional processing if it is seen, or you might find that it just emits it as-is into an external file.

Related

Unset is not useful? (Korn shell)

I'm reading this:
You can delete a variable with the command unset varname. Normally this is not useful, since all variables that don't exist are assumed to be null, i.e., equal to empty string "". But if you use the option nounset which causes the shell to indicate an error when it encounters an undefined variable, then you may be interested in unset.
My first question is: I cannot see why the use of unset be not useful; if I want to put my variable to null I can use it (or set variable="" or variable=). On the other hand, if I have a variable that doesn't exist, I don't know why I should have to use it..
My second question is: Why may I be interested in unset in that case?
There is a relevant difference between unset and empty variables.
When you can't tell in front which variables will be used, you can process the output of set (examples: https://stackoverflow.com/a/43419722/3220113 and https://stackoverflow.com/a/28104421/3220113 ).
You might have a situaton where you have sourced a read-only config file, but you do not want all lines set in your environment. In that case you might want to unset the settings you do not need.
When you write some utility that uses some variables, you do not want to leave garbage in the environment. Next to using local variables using unset is another possibility.
I think I have found the answer to my question.
1) If you need to remove the definition and the content of a variable you can use unset command. However, unless you turn on the nounset set option, Korn Shell will allow using variables which don't exist, and it will default the content of such a variable as an empty string. That's why you normally don't use unset: because you normally leave the nounset option off and test variables via conditional logic. Hence in these cases, i.e. the inhibition of the use of a variable, it is not useful. (Obviously, it remains useful for deleting variables - as noted by #Walter A, i.e. "" is not unset, the complete removal of the variable.)
2) That said, it follows that if you use the nounset, unset command makes sense. Indeed, if you unset a variable, the shell will disallow using it.

Defining recursively expanded variable with same name as environment variable

I'm trying to lazily evaluate configuration option. I want to issue a Make error only if the variable is actually used (substituted).
Consider the following Makefile:
VAR = $(error "E")
NFS_DIR = NFS_DIR is $(VAR)
T = $(NFS_DIR) is 1
all:
echo Test
If I run it with my environment (which has /srv/nfs value), the output is following:
➜ ~ make
echo Test
Makefile:3: *** "E". Stop.
So the recursive definition acts like simple definition.
If I clear the environment, it works as expected:
➜ ~ env -i make
echo Test
Test
I couldn't find any mention that recursively-expanded variable, when defined with same name as environment variable, will act like simply-expanded variable.
So the questions are:
Why the observed behavior?
How to implement the desired behavior?
Update: to clarify — I don't want to use ?= since the options are configuration options I want them to come strictly from Makefile and not from environment.
Any variable which is in the environment when make starts, will be exported to the environment of any command make runs (as part of a recipe, etc.) In order for make to send the value of the variable to the command, make first has to expand it. It's not acting like a simply-expanded variable. It's just that running a command forces the expansion.
This is kind of a nasty side-effect but I'm not sure there's anything that can be done directly: this behavior is traditional and mandated by POSIX and lots of makefiles would break if it were changed.
You have two choices I can think of. The first is to use the unexport make command to tell make to not send that variable in the command's environment.
The second is to change the name of the variable in make to something that is not a valid environment variable: make will only export variables whose names are legal shell variables (contain only alphanumeric plus _). So using a name like VAR-local instead of VAR would do it.
The question appear to be extremely clear in the title but the actual request get lost in details so the only other reply left it mostly unanswered. Directly answering to the question in the title, which is very interesting, to define a variable in a Makefile with same name as environment variable you can get its value with printenv:
PATH=${shell printenv PATH}:/opt/bin
echo:
echo $(PATH)
Other techniques to achieve the same result without relying on evaluation with external commands are welcome.

Using Shell to Check Whether a File Exists, and only if it does, Execute a Set of Commands

I have a few lines of code in Stata. I'd like the lines to be executed only if the .txt file to which the lines refer exist a priori. I am wondering whether there is a shell command that I can use for this that I can embed in an if statement.
For example might something like the following exist and be possible:
insheet using "file.txt" if ('file.txt')
My intent is to say insheet the file file.txt only if it exists. My concern is that the program would otherwise stop, fail, die, or whatever you call it due to a syntax error if I have that insheet statement but the file does not exist.
Immediate answer is No. There is nothing like that syntax for several reasons.
The if qualifier tests whether some condition is true separately for each observation and whether a file exists is not an appropriate condition for testing observation by observation.
The quite different if command tests once and once only whether something is true and might seem more appropriate. In practice it is not used for this purpose, but to learn more, see help ifcmd.
Stata has no special syntax based on paired identical single quotes ' '.
However, Stata provides a separate construct here
confirm file file.txt
In practice that is going to stop a do-file or program whenever the file does not exist and the file does not exist. A general scheme to catch the error is something like
capture confirm file file.txt
if _rc == 0 insheet using file.txt
else {
<code if the file does not exist>
}
capture is to be thought of as eating the return code from the confirm command. In general the return code _rc from any command is 0 if the command was valid and executed and some non-zero value otherwise. Sometimes one tests for a specific non-zero code. Experiment shows that file not found is return code 601. The main reason for looking up error codes (in [P] error) is to deliver official-looking error messages, but in practice knowing the zero/non-zero rule is the main detail under this heading.
The example here uses == to test for equality.
Note that insheet using file.txt is not strictly a syntax error if the file does not exist. As far as Stata's language is concerned, that is legal syntax. However, that is a fine distinction: it is an error in every ordinary sense.
(LATER) It would be possible to short-circuit the entire process
capture insheet using file.txt
if _rc != 0 {
<code if the file does not exist>
}
as in this case the non-existence of the file is the presumed explanation for any failure of the insheet command. If, however, the insheet call were more complicated, with a varlist and/or options, then failure of the command could arise for other reasons. So in general separating out a check for the existence of the file seems a better strategy.
The confirm command has what you're looking for.
capture confirm file "file.txt"
if !_rc { # if the file exists, confirm will return error code 0
insheet using "file.txt"
}
Alternatively, you could put a capture before the insheet command, which will catch the syntax error. Check the [P] manual for more on capture and confirm.

How to get Aruba to expand wildcards

I'm writing a simple command line gem.
The library that does the actual work was developed with rspec and so far that works.
I'm trying to test the command line portion with Aruba/Cucumber, but I've come across some strange behaviour.
Just to test this, I've got a the binary file to puts ARGV, and I've got test files in tmp/aruba
When I run bundle exec gem_name tmp/aruba/*.* I am presented with the list of shell expanded file names.
Now my features file has:
Given files to work on # I set up files in tmp/aruba in this step
When I run `gem_name *.*` # standard step
Then the output should contain "Wibble"
The last step is obviously going to fail, but it shows me a diff between what it expects and the actual output. Rather than seeing a list of shell expanded filenames, all I get is "*.*"
So I'm left in the position of having an app that actually works as expected, but I can't get the tests to pass. I could take the "." and generate the list of files from there, but then I'm writing extra production code just to get the app to work under test - which I don't think is the correct way to go about it. And all because shell expansion isn't happening.
If you look at my profile, you'll see that Ruby isn't my main bag, feel free to point me at any resources that I may have missed about this, but is this just me missing something, or expected behaviour that somebody knows how to work around?
After a little digging in the Aruba source I figured out that the When I run step ends up in a code block like this:
def run!(&block)
#process = ChildProcess.build(*shellwords(#cmd))
...
begin
#process.start
...
Further digging into ChildProcess ends up here:
def launch_process
...
begin
exec(*#args)
...
And therein lies the problem. exec does not do shell expansion when the argument list is split into multiple array elements:
If exec is given a single argument, that argument is
taken as a line that is subject to shell expansion before being
executed. If multiple arguments are given, the second and
subsequent arguments are passed as parameters to command with no
shell expansion.
However playing with shellwords a bit we find:
Shellwords.shellwords('gem_name *.*')
=> ["gem_name", "*.*"] # No good
Shellwords.shellwords('"gem_name *.*"')
=> ["gem_name *.*"] # Aha!
Therefore the solution might be as simple as:
When I run `"gem_name *.*"`
If that doesn't work then you are pretty much out of luck. I would suggest you expand the file names manually since you're not really testing shell expansion here - we know that works: you are testing multiple arguments.
Therefore you should instead do:
When I run `gem_name your_file1 your_file2 your_file3`

Calling make from a bash script won't make

I'm writing a shell script which iterates over a set of variables, edits a source file line by line according to the current iteration value, then remakes, and finally calls the just compiled binary. After execution the old line is restored.
Here is a snippet:
#!/bin/sh
for i in 0..4; do
perl -i -pe "s/.*/{SUBS[$i]}/ if $. == ${LINE[$i]}" ${SOURCE}
make
./bin/myTool
perl -i -pe "s/.*/\/\/{SUBS[$i]}/ if $. == ${LINE[$i]}" ${SOURCE}
done
Basically I have about 10 mutually exclusive #define in a C++ source file, and I'm experimenting the effects of each. Since I'm lazy I'd like to make it an automated process, and here I stuck.
Sometimes it happens that the shell says:
`make: Nothing to be done for 'all'`
Now, I tried to diff the file before and after every perlinstruction and the files do appear correct... I can't figure why this happens and how to make it behave correct.
Any idea?
Thank you in advance.
It's probably looping too quickly for make to tell each iteration apart. Either remove the make products or add a delay of 2 seconds at the beginning or end of the loop.
Make only checks if the target timestamp is younger than the source timestamp. That's the only way it can know what needs to be updated. So, if you loop iterations take less than a second then make won't know that anything has changed.
You can either clean up at the top of each iteration or add a delay as Ignacio Vazquez-Abrams has noted.

Resources