versions.awk 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # Combine version map fragments into version scripts for our shared objects.
  2. # Copyright (C) 1998-2019 Free Software Foundation, Inc.
  3. # Written by Ulrich Drepper <drepper@cygnus.com>, 1998.
  4. # This script expects the following variables to be defined:
  5. # defsfile name of Versions.def file
  6. # buildroot name of build directory with trailing slash
  7. # move_if_change move-if-change command
  8. # Read definitions for the versions.
  9. BEGIN {
  10. lossage = 0;
  11. nlibs=0;
  12. while (getline < defsfile) {
  13. if (/^[a-zA-Z0-9_.]+ \{/) {
  14. libs[$1] = 1;
  15. curlib = $1;
  16. while (getline < defsfile && ! /^}/) {
  17. if ($2 == "=") {
  18. renamed[curlib "::" $1] = $3;
  19. }
  20. else
  21. versions[curlib "::" $1] = 1;
  22. }
  23. }
  24. }
  25. close(defsfile);
  26. tmpfile = buildroot "Versions.tmp";
  27. # POSIX sort needed.
  28. sort = "sort -t. -k 1,1 -k 2n,2n -k 3 > " tmpfile;
  29. }
  30. # Remove comment lines.
  31. /^ *#/ {
  32. next;
  33. }
  34. # This matches the beginning of the version information for a new library.
  35. /^[a-zA-Z0-9_.]+/ {
  36. actlib = $1;
  37. if (!libs[$1]) {
  38. printf("no versions defined for %s\n", $1) > "/dev/stderr";
  39. ++lossage;
  40. }
  41. next;
  42. }
  43. # This matches the beginning of a new version for the current library.
  44. /^ [A-Za-z_]/ {
  45. if (renamed[actlib "::" $1])
  46. actver = renamed[actlib "::" $1];
  47. else if (!versions[actlib "::" $1] && $1 != "GLIBC_PRIVATE") {
  48. printf("version %s not defined for %s\n", $1, actlib) > "/dev/stderr";
  49. ++lossage;
  50. }
  51. else
  52. actver = $1;
  53. next;
  54. }
  55. # This matches lines with names to be added to the current version in the
  56. # current library. This is the only place where we print something to
  57. # the intermediate file.
  58. /^ / {
  59. sortver=actver
  60. # Ensure GLIBC_ versions come always first
  61. sub(/^GLIBC_/," GLIBC_",sortver)
  62. printf("%s %s %s\n", actlib, sortver, $0) | sort;
  63. }
  64. function closeversion(name, oldname) {
  65. if (firstinfile) {
  66. printf(" local:\n *;\n") > outfile;
  67. firstinfile = 0;
  68. }
  69. # This version inherits from the last one only if they
  70. # have the same nonnumeric prefix, i.e. GLIBC_x.y and GLIBC_x.z
  71. # or FOO_x and FOO_y but not GLIBC_x and FOO_y.
  72. pfx = oldname;
  73. sub(/[0-9.]+/,".+",pfx);
  74. if (oldname == "" || name !~ pfx) print "};" > outfile;
  75. else printf("} %s;\n", oldname) > outfile;
  76. }
  77. function close_and_move(name, real_name) {
  78. close(name);
  79. system(move_if_change " " name " " real_name " >&2");
  80. }
  81. # Now print the accumulated information.
  82. END {
  83. close(sort);
  84. if (lossage) {
  85. system("rm -f " tmpfile);
  86. exit 1;
  87. }
  88. oldlib = "";
  89. oldver = "";
  90. real_first_ver_header = buildroot "first-versions.h"
  91. first_ver_header = real_first_ver_header "T"
  92. printf("#ifndef _FIRST_VERSIONS_H\n") > first_ver_header;
  93. printf("#define _FIRST_VERSIONS_H\n") > first_ver_header;
  94. real_ldbl_compat_header = buildroot "ldbl-compat-choose.h"
  95. ldbl_compat_header = real_ldbl_compat_header "T"
  96. printf("#ifndef _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header;
  97. printf("#define _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header;
  98. printf("#ifndef LONG_DOUBLE_COMPAT\n") > ldbl_compat_header;
  99. printf("# error LONG_DOUBLE_COMPAT not defined\n") > ldbl_compat_header;
  100. printf("#endif\n") > ldbl_compat_header;
  101. printf("version-maps =");
  102. while (getline < tmpfile) {
  103. if ($1 != oldlib) {
  104. if (oldlib != "") {
  105. closeversion(oldver, veryoldver);
  106. oldver = "";
  107. close_and_move(outfile, real_outfile);
  108. }
  109. oldlib = $1;
  110. real_outfile = buildroot oldlib ".map";
  111. outfile = real_outfile "T";
  112. firstinfile = 1;
  113. veryoldver = "";
  114. printf(" %s.map", oldlib);
  115. }
  116. if ($2 != oldver) {
  117. if (oldver != "") {
  118. closeversion(oldver, veryoldver);
  119. veryoldver = oldver;
  120. }
  121. printf("%s {\n global:\n", $2) > outfile;
  122. oldver = $2;
  123. }
  124. printf(" ") > outfile;
  125. for (n = 3; n <= NF; ++n) {
  126. printf(" %s", $n) > outfile;
  127. sym = $n;
  128. sub(";", "", sym);
  129. first_ver_macro = "FIRST_VERSION_" oldlib "_" sym;
  130. if (!(first_ver_macro in first_ver_seen) \
  131. && oldver ~ "^GLIBC_[0-9]" \
  132. && sym ~ "^[A-Za-z0-9_]*$") {
  133. ver_val = oldver;
  134. gsub("\\.", "_", ver_val);
  135. printf("#define %s %s\n", first_ver_macro, ver_val) > first_ver_header;
  136. first_ver_seen[first_ver_macro] = 1;
  137. if (oldlib == "libc" || oldlib == "libm") {
  138. printf("#if LONG_DOUBLE_COMPAT (%s, %s)\n",
  139. oldlib, ver_val) > ldbl_compat_header;
  140. printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) a\n",
  141. oldlib, sym) > ldbl_compat_header;
  142. printf("#else\n") > ldbl_compat_header;
  143. printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) b\n",
  144. oldlib, sym) > ldbl_compat_header;
  145. printf("#endif\n") > ldbl_compat_header;
  146. }
  147. }
  148. }
  149. printf("\n") > outfile;
  150. }
  151. printf("\n");
  152. printf("#endif /* first-versions.h */\n") > first_ver_header;
  153. printf("#endif /* ldbl-compat-choose.h */\n") > ldbl_compat_header;
  154. closeversion(oldver, veryoldver);
  155. close_and_move(outfile, real_outfile);
  156. close_and_move(first_ver_header, real_first_ver_header);
  157. close_and_move(ldbl_compat_header, real_ldbl_compat_header);
  158. #system("rm -f " tmpfile);
  159. }