Browse Source

ENH: Improve robustness of compiler INFO strings

Compiler INFO strings built at preprocessing time encode information
that must appear as a string literal in the resulting binary.  We must
make sure the strings appear in the final binary no matter what compiler
and flags are used.  The previous implementation worked in most places
but failed with the GNU linker's --gc-sections option which managed to
discard the string.  Instead we make the program return value depend on
an element of the string indexed by a runtime program parameter, which
absolutely requires the string to be present.
Brad King 17 years ago
parent
commit
b8fc8b324d

+ 10 - 10
Modules/CMakeCCompilerABI.c

@@ -12,17 +12,17 @@
 
 
 /*--------------------------------------------------------------------------*/
 /*--------------------------------------------------------------------------*/
 
 
-/* Make sure the information strings are referenced.  */
-#define REQUIRE(x) (&x[0] != &require)
-
-int main()
+#ifdef __CLASSIC_C__
+int main(argc, argv) int argc; char *argv[];
+#else
+int main(int argc, char *argv[])
+#endif
 {
 {
-  const char require = 0;
-  return
-    (
-      REQUIRE(info_sizeof_dptr)
+  int require = 0;
+  require += info_sizeof_dptr[argc];
 #if defined(ABI_ID)
 #if defined(ABI_ID)
-      && REQUIRE(info_abi)
+  require += info_abi[argc];
 #endif
 #endif
-      );
+  (void)argv;
+  return require;
 }
 }

+ 15 - 6
Modules/CMakeCCompilerId.c.in

@@ -2,15 +2,9 @@
 # error "A C++ compiler has been selected for C."
 # error "A C++ compiler has been selected for C."
 #endif
 #endif
 
 
-/* Provide main() so the program can link.  */
 #if defined(__18CXX)
 #if defined(__18CXX)
 # define ID_VOID_MAIN
 # define ID_VOID_MAIN
 #endif
 #endif
-#ifdef ID_VOID_MAIN
-void main() {}
-#else
-int main() { return 0; }
-#endif
 
 
 #if defined(__INTEL_COMPILER) || defined(__ICC)
 #if defined(__INTEL_COMPILER) || defined(__ICC)
 # define COMPILER_ID "Intel"
 # define COMPILER_ID "Intel"
@@ -82,3 +76,18 @@ int main() { return 0; }
 char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
 char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
 
 
 @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
 @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef ID_VOID_MAIN
+void main() {}
+#else
+int main(int argc, char* argv[])
+{
+  int require = 0;
+  require += info_compiler[argc];
+  require += info_platform[argc];
+  (void)argv;
+  return require;
+}
+#endif

+ 6 - 10
Modules/CMakeCXXCompilerABI.cpp

@@ -8,17 +8,13 @@
 
 
 /*--------------------------------------------------------------------------*/
 /*--------------------------------------------------------------------------*/
 
 
-/* Make sure the information strings are referenced.  */
-#define REQUIRE(x) (&x[0] != &require)
-
-int main()
+int main(int argc, char* argv[])
 {
 {
-  const char require = 0;
-  return
-    (
-      REQUIRE(info_sizeof_dptr)
+  int require = 0;
+  require += info_sizeof_dptr[argc];
 #if defined(ABI_ID)
 #if defined(ABI_ID)
-      && REQUIRE(info_abi)
+  require += info_abi[argc];
 #endif
 #endif
-      );
+  (void)argv;
+  return require;
 }
 }

+ 11 - 3
Modules/CMakeCXXCompilerId.cpp.in

@@ -5,9 +5,6 @@
 # error "A C compiler has been selected for C++."
 # error "A C compiler has been selected for C++."
 #endif
 #endif
 
 
-/* Provide main() so the program can link.  */
-int main() { return 0; }
-
 #if defined(__COMO__)
 #if defined(__COMO__)
 # define COMPILER_ID "Comeau"
 # define COMPILER_ID "Comeau"
 
 
@@ -70,3 +67,14 @@ int main() { return 0; }
 char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
 char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
 
 
 @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
 @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+  int require = 0;
+  require += info_compiler[argc];
+  require += info_platform[argc];
+  (void)argv;
+  return require;
+}

+ 7 - 6
Modules/CheckTypeSizeC.c.in

@@ -29,15 +29,16 @@ const char info_sizeof[] =  {'I', 'N', 'F', 'O', ':', 's','i','z','e','o','f','[
   ('0' +  (SIZE    % 10)), 
   ('0' +  (SIZE    % 10)), 
   ']','\0'};
   ']','\0'};
 
 
-
 #ifdef __CLASSIC_C__
 #ifdef __CLASSIC_C__
-int main(){
-  int ac;
-  char*av[];
+int main(argc, argv) int argc; char *argv[];
 #else
 #else
-int main(int ac, char*av[]){
+int main(int argc, char *argv[])
 #endif
 #endif
-  return (&info_sizeof[0] != &info_sizeof[0]);
+{
+  int require = 0;
+  require += info_sizeof[argc];
+  (void)argv;
+  return require;
 }
 }
 
 
 #else  /* CHECK_TYPE_SIZE_TYPE */
 #else  /* CHECK_TYPE_SIZE_TYPE */

+ 8 - 5
Modules/TestEndianess.c.in

@@ -10,11 +10,14 @@ const cmakeint16 info_little[] =  {0x4854, 0x5349, 0x4920, 0x2053, 0x494c, 0x545
 const cmakeint16 info_big[] =     {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000};
 const cmakeint16 info_big[] =     {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000};
 
 
 #ifdef __CLASSIC_C__
 #ifdef __CLASSIC_C__
-int main(){
-  int ac;
-  char*av[];
+int main(argc, argv) int argc; char *argv[];
 #else
 #else
-int main(int ac, char*av[]){
+int main(int argc, char *argv[])
 #endif
 #endif
-   return (&info_little[0] != &info_big[0]);
+{
+  int require = 0;
+  require += info_little[argc];
+  require += info_big[argc];
+  (void)argv;
+  return require;
 }
 }