mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
7db55c0ba1
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.
82 lines
1.4 KiB
Bash
Executable File
82 lines
1.4 KiB
Bash
Executable File
#!/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
|