Understand gnu makefile declaration - gnu-make

What does the following declaration mean. More specifically the ':P' part.
How do I read similar declarations in gnu makefile.
BUILD_TOOL = ${toolname:P}

That's a BSD make feature:
:P The path of the node which has the same name as the variable
is the value. If no such node exists or its path is null, then
the name of the variable is used. In order for this modifier to
work, the name (node) must at least have appeared on the rhs of
a dependency.
There is nothing similar to that in GNU make; you'll have to set the variable directly and use it in both places (target and variable etc.)

Related

Looking for idea on overwrite a function during frama-c

I'm looking for idea on how to overwrite a function without modify the source. Like if I have foo() in the original source, I want to overwrite it with my own version with the same function name by adding it in a C file, which may also contains other overwrite functions. Sort of like strong/weak compilation. Currently I have to go in the source files and ifdef with __FRAMAC__. I don't want to touch the source files. Is there some kernel option to not use the second instance of foo() function?
Your question does not specify whether you want to replace a function declaration or a function definition. Since they are handled differently by Frama-C, I'm going to detail both.
Duplicate definitions at the kernel level
Currently, at the parsing level, there is no option in Frama-C to completely ignore the definition of a function that is present in one of the files given for parsing. The Frama-C AST will incorporate the definition of all functions it finds.
There is no exact equivalent for strong/weak symbols.
If a second definition for the same function is found, one of the following will happen:
If both definitions occur in the same compilation unit, there is an error.
If each definition happens in a different compilation unit, Frama-C will try to find a plausible solution:
If both occurrences have the same signature, Frama-C will emit a warning such as:
[kernel] b.c:2: Warning:
dropping duplicate def'n of func f at b.c:2 in favor of that at a.c:1
In this case, you just need to ensure the definition you want appears later in the list of sources to be parsed.
If the occurrences have different signatures, but one of the functions is never actually used, you may have a warning such as:
[kernel:linker:drop-conflicting-unused] Warning:
Incompatible declaration for f:
different number of arguments
First declaration was at a.c:1
Current declaration is at b.c:2
Current declaration is unused, silently removing it
However, if both occurrences are used, then you have an error:
[kernel] User Error: Incompatible declaration for f:
different type constructors: int vs. int *
First declaration was at a.c:1
Current declaration is at b.c:2
Duplicate declarations at the kernel level
Considering function declarations, Frama-C will, in accordance with the C standard, accept as many of them as are given, provided they are compatible. If they have ACSL specifications, those specifications will be merged.
Multiple incompatible declarations are handled as before, with warnings or errors depending on whether both versions are used (in which case Frama-C is unable to choose).
Plugin-specific options
Plug-ins may have specific options to override the default behavior of functions in the AST. For instance, Eva has option -eva-use-spec <fns>, which tells the analysis to ignore the definitions of functions <fns>, using only their specifications instead.

Common Lisp: relative path to absolute

May be it is a really dumb question, but after playing around with all built-in pathname-family functions and cl-fad/pathname-utils packages I still can't figure out how to convert a relative path to absolute (with respect to $PWD):
; let PWD be "/very/long/way"
(abspath "../road/home"); -> "/very/long/road/home"
Where the hypothetical function abspath works just like os.path.abspath() in Python.
The variable *DEFAULT-PATHNAME-DEFAULTS* usually contains your initial working directory, you can merge the pathname with that;
(defun abspath (pathname)
(merge-pathnames pathname *default-pathname-defaults*))
And since this is the default for the second argument to merge-pathnames, you can simply write:
(defun abspath (pathname)
(merge-pathnames pathname))
UIOP
Here is what the documentation of UIOP says about cl-fad :-)
UIOP completely replaces it with better design and implementation
A good number of implementations ship with UIOP (used by ASDF3), so it's basically already available when you need it (see "Using UIOP" in the doc.). One of the many functions defined in the library is uiop:parse-unix-namestring, which understands the syntax of Unix filenames without checking if the path designates an existing file or directory. However the double-dot is parsed as :back or :up which is not necessarily supported by your implementation. With SBCL, it is the case and the path is simplified. Note that pathnames allows to use both :back and :up components; :back can be simplified easily by looking at the pathname only (it is a syntactic up directory), whereas :up is the semantic up directory, meaning that it depends on the actual file system. You have a better chance to obtain a canonical file name if the file name exists.
Truename
You can also call TRUENAME, which will probably get rid of the ".." components in your path. See also 20.1.3 Truenames which explains that you can point to the same file by using different pathnames, but that there is generally one "canonical" name.
Here's the final solution (based on the previous two answers):
(defun abspath
(path-string)
(uiop:unix-namestring
(uiop:merge-pathnames*
(uiop:parse-unix-namestring path-string))))
uiop:parse-unix-namestring converts the string argument to a pathname, replacing . and .. references; uiop:merge-pathnames* translates a relative pathname to absolute; uiop:unix-namestring converts the pathname back to a string.
Also, if you know for sure what kind of file the path points to, you can use either:
(uiop:unix-namestring (uiop:file-exists-p path))
or
(uiop:unix-namestring (uiop:directory-exists-p path))
because both file-exists-p and directory-exists-p return absolute pathnames (or nil, if file does not exist).
UPDATE:
Apparently in some implementations (like ManKai Common Lisp) uiop:merge-pathnames* does not prepend the directory part if the given pathname lacks ./ prefix (for example if you feed it #P"main.c" rather than #P"./main.c"). So the safer solution is:
(defun abspath
(path-string &optional (dir-name (uiop:getcwd)))
(uiop:unix-namestring
(uiop:ensure-absolute-pathname
(uiop:merge-pathnames*
(uiop:parse-unix-namestring path-string))
dir-name)))

How to limit recursion depth while expanding variable in GNU makefile?

I need macro (variable) for GNU makefile, that searches file/directory by given mask at some of toplevel directories. For example, current working directory is /home/sysop/powerup/native/apps/toopl. Also exists directory /home/sysop/powerup/native/SDK/build. I want to find location of SDK/build directory relative to current one. So, I wrote recursive macros for that:
upfind = $(if $(wildcard $(1)),$(1),$(if $(filter $(abspath $(1)),$(abspath ../$(1))),$(error "can't find $(1)"),$(call upfind,../$(1))))
And I now can use it in following way:
relpath = $(call upfind, ../SDK/build)
And this assigns value "../../SDK/build" to relpath variable.
All fine, but I need propagate such macro to multiple makefiles, so I'am looking way to minimize it (upfind macro). I hope, anybody suggests me how to rewrite this macro in more compact way. For example, it's enought to limit recursion at some level, using of $(abspath) macro isn't necessary. But how can I determine recursion level or measure argument ($(1))length?
Not sure what you are asking here, so this probably isn't an answer.
The recursion limit is simple enough.
First, a bit of tidying:
assert-root = $(if $(filter $(abspath $1),$(abspath ../$1)),$(error Can't find $1))
upfind = $(if $(wildcard $1),$1,${assert-root}$(call upfind,../$1))
(Note how $assert-root is not called, it simply inherits the exisiting $1.)
Makes it a bit clearer how we can limit recursion depth: just pass an ever-lengthening $2.
maxup := 3
assert-depth = $(if $(filter ${maxup},$(words $2)),$(error Can't find [$1] within ${maxup} parents))
upfind = $(if $(wildcard $1),$1,${assert-depth}$(call upfind,../$1,_ $2))
Do both at the same time if you like
upfind = $(if $(wildcard $1),$1,${assert-depth}${assert-root}$(call upfind,../$1,_ $2))

Ada object declarations "Unsigned Not Declared in System"

In some code that I inherited, I get the compile error "Unsigned" not declared in "System".
I'm trying to compile this using GNAT, but ultimately the code must compile with the original tools, which I don't have ready access to. So I'd like to understand how to resolve this from within the development environment (including the project file), and not modify the existing code.
I checked the file system.ads, and Unsigned is not defined there. Am I referring to the wrong libraries? How would I resolve this with the self imposed constraint mentioned above (to compile in the original environment)?
unsigned is the name of a predefined type in C. If what you need it an Ada type that matches the C type, what you need is Interfaces.C.unsigned. An older Ada implementation (before Interfaces.C was introduced by the 1995 standard) might have defined System.Unsigned for this purpose.
It would help to know what Ada implementation the code was originally written for.
You should examine the code to see whether it uses that type to interface to C code. If not (i.e., if it's just being used as a general unsigned integer type), you might instead consider defining your own modular type.
If I understand correctly, you need the code to compile both in the original environment and with GNAT. That might be difficult. One approach would be to define a new package with two different versions, one for the original environment and one for GNAT (or, ideally, for any modern Ada implementation). For example:
-- version for original environment
with System;
package Foo is
subtype Unsigned is System.Unsigned;
end foo;
and:
-- version for GNAT
with Interfaces.C;
package Foo is
subtype Unsigned is Interfaces.C.Unsigned;
end Foo;
Picking a better name than Foo is left as an exercise, as is determining automatically which version to use.
You could rebuild the GNAT runtime system (RTS) with a slightly modified system.ads.
There’s a Makefile.adalib in the system RTS (well, there is in GNAT GPL 2014) which lets you do this. It’s at the last directory indicated in the “Object Search Path” section of the output of gnatls -v.
The RTS source is similarly indicated in the “Source Search Path” section.
Create a directory say unsigned with subdirectories adainclude, adalib.
Copy the RTS source into unsigned/adainclude, and edit system.ads to include
type Unsigned is mod 2 ** 32;
(I’m guessing a bit, but this is probably what you want!)
Then, in unsigned/adalib,
make -f Makefile.adalib ADA_INCLUDE_PATH=../adainclude ROOT=/opt/gnat-gpl-2014
(ROOT is where you have the compiler installed; it will be different on your system, it’s one above the bin directory in which gnatls and friends are installed).
There will be several errors during this, all caused (when I tried it) by units that use System.Unsigned_Types;. Work round this by inserting this immediately after the package body in the .adb:
subtype Unsigned is System.Unsigned_Types.Unsigned;
The files I had to change were
s-expmod.adb
s-expuns.adb
s-imgbiu.adb
s-imgrea.adb
s-imguns.adb
s-imgwiu.adb
s-valint.adb
s-valuns.adb
s-vercon.adb
It may be best at this stage to remove all the .ali and .a files from unsigned/adalib and repeat, to get a clean build.
Now, you should be able to use System.Unsigned by
gnatmake --RTS=/location/of/unsigned t.adb
In my case, t.adb contained
with System;
with Ada.Text_IO; use Ada.Text_IO;
procedure T is
begin
Put_Line ("first: " & System.Unsigned'First'Img);
Put_Line ("last: " & System.Unsigned'Last'Img);
Put_Line ("42: " & System.Unsigned'Value ("42")'Img);
Put_Line ("16#42#:" & System.Unsigned'Value ("16#42#")'Img);
end T;
and the output was
$ ./t
first: 0
last: 4294967295
42: 42
16#42#: 66

How to denote that a command line argument is optional when printing usage

Assume that I have a script that can be run in either of the following ways.
./foo arg1 arg2
./foo
Is there a generally accepted way to denote that arg1 and arg2 aren't mandatory arguments when printing the correct usage of the command?
I've sometimes noticed usage printed with the arguments wrapped in brackets like in the following usage printout.
Usage: ./foo [arg1] [arg2]
Do these brackets mean that the argument is optional or is there another generally accepted way to denote that an argument is optional?
I suppose this is as much a standard as anything.
The Open Group Base Specifications Issue 7
IEEE Std 1003.1, 2013 Edition
Copyright © 2001-2013 The IEEE and The Open Group
Ch. 12 - Utility Conventions
Although it doesn't seem to mention many things I have commonly seen over the years used to denote various meanings:
square brackets [optional option]
angle brackets <required argument>
curly braces {default values}
parenthesis (miscellaneous info)
Edit: I should add, that these are just conventions. The important thing is to pick a convention which is sensible, clearly state your convention, and stick to it consistently. Be flexible and create conventions which seem to be most frequently encountered on your target platform(s). They will be the easiest for users to adapt to.
I personally have not seen a 'standard' that denotes that a switch is optional (like how there's a standard that defines how certain languages are written for example), as it really is personal choice, but according to IBM's docs and the Wiki, along with numerous shell scripts I've personally seen (and command line options from various programs), and the IEEE, the 'defacto' is to treat square bracketed ([]) parameters as optional parameters. Example from Linux:
ping (output trimmed...)
usage: ping [-c count] [-t ttl] host
where [-c count] and [-t ttl] are optional parameters but host is not (as defined in the help).
I personally follow the defacto as well by using [] to mean they are optional parameters and make sure to note that in the usage of that script/program.
I should note that a computer standard should define how something happens and its failure paths (either true fail or undefined behavior). Something along the lines of the command line interpreter _shall_ treat arguments as optional when enclosed in square brackets, and _shall_ treat X as Y when Z, etc.. Much like the ISO C standard says how a function shall be formed for it to be valid (otherwise it fails). Given that there are no command line interpreters, from ASH to ZSH and everything in between, that fail a script for treating [] as anything but optional, one could say there is not a true standard.
Yes, the square brackets indicate optional arguments in Unix man pages.
From "man man":
[-abc] any or all arguments within [ ] are optional.
I've never wondered if they're formally specified somewhere, I've always just assumed they come from conventions used in abstract algebra, in particular, in BNF grammars.

Resources