gcc/contrib/relpath.sh

82 lines
1.4 KiB
Bash
Raw Permalink Normal View History

libstdc++: add module std [PR106852] This patch introduces an installed source form of module std and std.compat. To help a build system find them, we install a libstdc++.modules.json file alongside libstdc++.so, which tells the build system where the files are and any special flags it should use when compiling them (none, in this case). The format is from a proposal in SG15. The build system can find this file with 'gcc -print-file-name=libstdc++.modules.json'. It seems preferable to use a relative path from this file to the sources so that moving the installation doesn't break the reference, but I didn't see any obvious way to compute that without relying on coreutils, perl, or python, so I wrote a POSIX shell script for it. The .. canonicalization bits aren't necessary since I discovered $(abspath), but I guess I might as well leave them in. Currently this installs the sources under $(gxx_include_dir)/bits/, i.e. /usr/include/c++/15/bits. So with my -fsearch-include-path change, std.cc can be compiled with g++ -fsearch-include-path bits/std.cc. Note that if someone actually tries to #include <bits/std.cc> it will fail with "error: module control-line cannot be in included file". Any ideas about a more user-friendly way to express "compile module std" are welcome. The sources currently have the extension .cc, like other source files. std.cc started with m.cencora's implementation in PR114600. I've made some adjustments, but more is probably desirable, e.g. of the <algorithm> handling of namespace ranges, and to remove exports of templates that are only specialized in a particular header. I've filled in a bunch of missing exports, and added some FIXMEs where I noticed bits that are not implemented yet. Since bits/stdc++.h also intends to include the whole standard library, I include it rather than duplicate it. But stdc++.h comments out <execution>, due to TBB issues; I include it separately and suppress TBB usage, so module std won't currently provide parallel execution. It seemed most convenient for the two files to be monolithic so we don't need to worry about include paths. So the C library names that module std.compat exports in both namespace std and :: are a block of code that is appended to both files, adjusted based on whether the macro STD_COMPAT is defined before the block. In this implementation std.compat imports std; it would also be valid for it to duplicate everything in std. I see the libc++ std.compat also imports std. As discussed in the PR, module std is supported in C++20 mode even though it was added in C++23. Changes to test module std will follow in a separate patch. In my testing I've noticed a few compiler bugs that break various testcases, so I don't expect to enable module std testing by default at first. PR libstdc++/106852 libstdc++-v3/ChangeLog: * include/bits/version.def: Add __cpp_lib_modules. * include/bits/version.h: Regenerate. * src/c++23/Makefile.am: Add modules std and std.compat. * src/c++23/Makefile.in: Regenerate. * src/c++23/std-clib.cc.in: New file. * src/c++23/std.cc.in: New file. * src/c++23/std.compat.cc.in: New file. * src/c++23/libstdc++.modules.json.in: New file. contrib/ChangeLog: * relpath.sh: New file.
2024-10-10 21:27:50 +00:00
#!/bin/sh
if [ "$1" = "--help" -o $# -ne 2 -o -f "$1" ]; then
echo Usage: relpath.sh FROM TO
echo Print the relative path from FROM to TO
echo FROM must be a directory, but need not exist
exit 0
fi
from="${1%%/}"
to="${2%%/}"
# The parent directory of a pathname, handling ..
parent() {
name=$(basename "$1")
path=$(dirname "$1")
top=$(basename "$path")
if [ "$top" = ".." ]; then
path=$(parent "$path")
fi
if [ "$name" = ".." ]; then
path=$(parent "$path")
fi
echo $path
}
# Canonicalize a directory that contains '..'.
canonicalize() {
path=$1
suffix=
while ! [ -d "$path" ]; do
name=$(basename "$path")
path=$(parent "$path")
suffix="/$name$suffix"
done
if [ -d "$path" ]; then
echo $(cd "$path"; pwd)$suffix
else
echo $1
fi
}
case "$to$from" in
*..* )
from=$(canonicalize "$from")
to=$(canonicalize "$to")
;;
esac
case "$to$from" in
*..* )
echo unable to canonicalize .. >&2
exit 1
;;
esac
back=
while [ "${to#$from}" = "$to" ]; do
#echo $from too long
from=$(dirname $from);
back=../$back
if [ "$from" = "/" ]; then
echo $to
exit 0
elif [ "$from" = . ]; then
echo no common ancestor between $1 and $2 >&2
exit 1
fi
done
to=${to#$from}
to=${to##/}
back=${back%%/}
if [ -n "$to" ] && [ -n "$back" ]; then
echo $back/$to
elif [ -n "$back$to" ]; then
echo $back$to
else
echo .
fi