Execute probes only when necessary
In many cases, it's enough to check whether a test program compiles.
This allows to simplify the probe code and speeds up the configuration
process.
diff --git a/src/Charmonizer/Core/HeaderChecker.c b/src/Charmonizer/Core/HeaderChecker.c
index 5b1c90b..a2b46db 100644
--- a/src/Charmonizer/Core/HeaderChecker.c
+++ b/src/Charmonizer/Core/HeaderChecker.c
@@ -132,18 +132,13 @@
int
chaz_HeadCheck_defines_symbol(const char *symbol, const char *includes) {
- /*
- * Casting function pointers to object pointers like 'char*' is a C
- * extension, so for a bullet-proof check, a separate test for functions
- * might be necessary.
- */
static const char defines_code[] =
CHAZ_QUOTE( %s )
CHAZ_QUOTE( int main() { )
CHAZ_QUOTE( #ifdef %s )
CHAZ_QUOTE( return 0; )
CHAZ_QUOTE( #else )
- CHAZ_QUOTE( return *(char*)&%s; )
+ CHAZ_QUOTE( return (int)&%s; )
CHAZ_QUOTE( #endif )
CHAZ_QUOTE( } );
long needed = sizeof(defines_code)
diff --git a/src/Charmonizer/Probe/Floats.c b/src/Charmonizer/Probe/Floats.c
index e2f8d41..229a9d4 100644
--- a/src/Charmonizer/Probe/Floats.c
+++ b/src/Charmonizer/Probe/Floats.c
@@ -71,34 +71,30 @@
const char*
chaz_Floats_math_library(void) {
+ /*
+ * The cast to a specific function pointer type is required because
+ * C++ overloads sqrt.
+ */
static const char sqrt_code[] =
CHAZ_QUOTE( #include <math.h> )
- CHAZ_QUOTE( #include <stdio.h> )
CHAZ_QUOTE( typedef double (*sqrt_t)(double); )
- CHAZ_QUOTE( int main(void) { )
- CHAZ_QUOTE( printf("%p\n", (sqrt_t)sqrt); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+ CHAZ_QUOTE( int main() { return (int)(sqrt_t)sqrt; } );
chaz_CFlags *temp_cflags = chaz_CC_get_temp_cflags();
- char *output = NULL;
- size_t output_len;
+ int success;
- output = chaz_CC_capture_output(sqrt_code, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_link(sqrt_code)) {
/* Linking against libm not needed. */
- free(output);
return NULL;
}
chaz_CFlags_add_external_lib(temp_cflags, "m");
- output = chaz_CC_capture_output(sqrt_code, &output_len);
+ success = chaz_CC_test_link(sqrt_code);
chaz_CFlags_clear(temp_cflags);
- if (output == NULL) {
+ if (!success) {
chaz_Util_die("Don't know how to use math library.");
}
- free(output);
return "m";
}
diff --git a/src/Charmonizer/Probe/FuncMacro.c b/src/Charmonizer/Probe/FuncMacro.c
index 762602c..ff4f4dd 100644
--- a/src/Charmonizer/Probe/FuncMacro.c
+++ b/src/Charmonizer/Probe/FuncMacro.c
@@ -22,63 +22,13 @@
#include <stdio.h>
#include <stdlib.h>
-/* Probe for ISO func macro. */
-static int
-chaz_FuncMacro_probe_iso() {
- static const char iso_func_code[] =
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( printf("%s", __func__); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
- size_t output_len;
- char *output;
- int success = false;
-
- output = chaz_CC_capture_output(iso_func_code, &output_len);
- if (output != NULL && strncmp(output, "main", 4) == 0) {
- success = true;
- }
- free(output);
-
- return success;
-}
-
-static int
-chaz_FuncMacro_probe_gnu() {
- /* Code for verifying GNU func macro. */
- static const char gnu_func_code[] =
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( printf("%s", __FUNCTION__); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
- size_t output_len;
- char *output;
- int success = false;
-
- output = chaz_CC_capture_output(gnu_func_code, &output_len);
- if (output != NULL && strncmp(output, "main", 4) == 0) {
- success = true;
- }
- free(output);
-
- return success;
-}
-
/* Attempt to verify inline keyword. */
-static char*
-chaz_FuncMacro_try_inline(const char *keyword, size_t *output_len) {
- static const char inline_code[] =
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( static %s int foo() { return 1; } )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( printf("%%d", foo()); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+static int
+chaz_FuncMacro_try_inline(const char *keyword) {
+ static const char inline_code[] = "static %s int f() { return 1; }";
char code[sizeof(inline_code) + 30];
sprintf(code, inline_code, keyword);
- return chaz_CC_capture_output(code, output_len);
+ return chaz_CC_test_compile(code);
}
static void
@@ -94,12 +44,9 @@
for (i = 0; i < num_inline_options; i++) {
const char *inline_option = inline_options[i];
- size_t output_len;
- char *output = chaz_FuncMacro_try_inline(inline_option, &output_len);
- if (output != NULL) {
+ if (chaz_FuncMacro_try_inline(inline_option)) {
has_inline = true;
chaz_ConfWriter_add_def("INLINE", inline_option);
- free(output);
break;
}
}
@@ -117,11 +64,11 @@
chaz_ConfWriter_start_module("FuncMacro");
/* Check for func macros. */
- if (chaz_FuncMacro_probe_iso()) {
+ if (chaz_CC_test_compile("const char *f() { return __func__; }")) {
has_funcmac = true;
has_iso_funcmac = true;
}
- if (chaz_FuncMacro_probe_gnu()) {
+ if (chaz_CC_test_compile("const char *f() { return __FUNCTION__; }")) {
has_funcmac = true;
has_gnuc_funcmac = true;
}
diff --git a/src/Charmonizer/Probe/Integers.c b/src/Charmonizer/Probe/Integers.c
index 7411880..c680141 100644
--- a/src/Charmonizer/Probe/Integers.c
+++ b/src/Charmonizer/Probe/Integers.c
@@ -42,12 +42,7 @@
static const char chaz_Integers_stdint_type_code[] =
CHAZ_QUOTE( #include <stdint.h> )
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() )
- CHAZ_QUOTE( { )
- CHAZ_QUOTE( printf("%%d", (int)sizeof(%s)); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+ CHAZ_QUOTE( %s i; );
static const char chaz_Integers_type64_code[] =
CHAZ_QUOTE( #include <stdio.h> )
@@ -58,14 +53,7 @@
CHAZ_QUOTE( } );
static const char chaz_Integers_literal64_code[] =
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( #define big 9000000000000000000%s )
- CHAZ_QUOTE( int main() )
- CHAZ_QUOTE( { )
- CHAZ_QUOTE( int truncated = (int)big; )
- CHAZ_QUOTE( printf("%%d\n", truncated); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+ CHAZ_QUOTE( int f() { return (int)9000000000000000000%s; } );
void
chaz_Integers_run(void) {
@@ -151,10 +139,8 @@
/* Determine whether the intptr_t type is available (it's optional in
* C99). */
sprintf(code_buf, chaz_Integers_stdint_type_code, "intptr_t");
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(code_buf)) {
has_intptr_t = true;
- free(output);
}
/* Figure out which integer types are available. */
@@ -198,34 +184,26 @@
}
else if (has_64) {
sprintf(code_buf, chaz_Integers_literal64_code, "LL");
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(code_buf)) {
strcpy(i64_t_postfix, "LL");
- free(output);
}
else {
sprintf(code_buf, chaz_Integers_literal64_code, "i64");
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(code_buf)) {
strcpy(i64_t_postfix, "i64");
- free(output);
}
else {
chaz_Util_die("64-bit types, but no literal syntax found");
}
}
sprintf(code_buf, chaz_Integers_literal64_code, "ULL");
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(code_buf)) {
strcpy(u64_t_postfix, "ULL");
- free(output);
}
else {
sprintf(code_buf, chaz_Integers_literal64_code, "Ui64");
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(code_buf)) {
strcpy(u64_t_postfix, "Ui64");
- free(output);
}
else {
chaz_Util_die("64-bit types, but no literal syntax found");
diff --git a/src/Charmonizer/Probe/LargeFiles.c b/src/Charmonizer/Probe/LargeFiles.c
index e1541c9..fe5e1fa 100644
--- a/src/Charmonizer/Probe/LargeFiles.c
+++ b/src/Charmonizer/Probe/LargeFiles.c
@@ -231,35 +231,13 @@
static int
chaz_LargeFiles_probe_lseek(chaz_LargeFiles_unbuff_combo *combo) {
static const char lseek_code[] =
- CHAZ_QUOTE( %s )
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( int fd; )
- CHAZ_QUOTE( fd = open("_charm_lseek", O_WRONLY | O_CREAT, 0666); )
- CHAZ_QUOTE( if (fd == -1) { return -1; } )
- CHAZ_QUOTE( %s(fd, 0, SEEK_SET); )
- CHAZ_QUOTE( printf("%%d", 1); )
- CHAZ_QUOTE( if (close(fd)) { return -1; } )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+ CHAZ_QUOTE( %s )
+ CHAZ_QUOTE( void f() { %s(0, 0, SEEK_SET); } );
char code_buf[sizeof(lseek_code) + 100];
- char *output = NULL;
- size_t output_len;
- int success = false;
/* Verify compilation. */
sprintf(code_buf, lseek_code, combo->includes, combo->lseek_command);
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
- success = true;
- free(output);
- }
-
- if (!chaz_Util_remove_and_verify("_charm_lseek")) {
- chaz_Util_die("Failed to remove '_charm_lseek'");
- }
-
- return success;
+ return chaz_CC_test_compile(code_buf);
}
static int
@@ -268,28 +246,15 @@
* fine as long as it compiles. */
static const char pread64_code[] =
CHAZ_QUOTE( %s )
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( int fd = 20; )
+ CHAZ_QUOTE( void f() { )
CHAZ_QUOTE( char buf[1]; )
- CHAZ_QUOTE( printf("1"); )
- CHAZ_QUOTE( %s(fd, buf, 1, 1); )
- CHAZ_QUOTE( return 0; )
+ CHAZ_QUOTE( %s(0, buf, 1, 1); )
CHAZ_QUOTE( } );
char code_buf[sizeof(pread64_code) + 100];
- char *output = NULL;
- size_t output_len;
- int success = false;
/* Verify compilation. */
sprintf(code_buf, pread64_code, combo->includes, combo->pread64_command);
- output = chaz_CC_capture_output(code_buf, &output_len);
- if (output != NULL) {
- success = true;
- free(output);
- }
-
- return success;
+ return chaz_CC_test_compile(code_buf);
}
static void
@@ -297,7 +262,7 @@
static chaz_LargeFiles_unbuff_combo unbuff_combos[] = {
{ "#include <unistd.h>\n#include <fcntl.h>\n", "lseek64", "pread64" },
{ "#include <unistd.h>\n#include <fcntl.h>\n", "lseek", "pread" },
- { "#include <io.h>\n#include <fcntl.h>\n", "_lseeki64", "NO_PREAD64" },
+ { "#include <io.h>\n#include <stdio.h>\n", "_lseeki64", "NO_PREAD64" },
{ NULL, NULL, NULL }
};
int i;
diff --git a/src/Charmonizer/Probe/Strings.c b/src/Charmonizer/Probe/Strings.c
index aed53b6..fdb9a13 100644
--- a/src/Charmonizer/Probe/Strings.c
+++ b/src/Charmonizer/Probe/Strings.c
@@ -16,6 +16,7 @@
#include "Charmonizer/Core/Compiler.h"
#include "Charmonizer/Core/ConfWriter.h"
+#include "Charmonizer/Core/HeaderChecker.h"
#include "Charmonizer/Probe/Strings.h"
#include <stdlib.h>
@@ -46,23 +47,6 @@
CHAZ_QUOTE( printf("%d", result); )
CHAZ_QUOTE( return 0; )
CHAZ_QUOTE( } );
- static const char detect__scprintf_code[] =
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( int result; )
- CHAZ_QUOTE( result = _scprintf("%s", "12345"); )
- CHAZ_QUOTE( printf("%d", result); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
- static const char detect__snprintf_code[] =
- CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( char buf[6]; )
- CHAZ_QUOTE( int result; )
- CHAZ_QUOTE( result = _snprintf(buf, 6, "%s", "12345"); )
- CHAZ_QUOTE( printf("%d", result); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
char *output = NULL;
size_t output_len;
@@ -81,15 +65,11 @@
/* Test for _scprintf and _snprintf found in the MSVCRT.
*/
- output = chaz_CC_capture_output(detect__scprintf_code, &output_len);
- if (output != NULL) {
+ if (chaz_HeadCheck_defines_symbol("_scprintf", "#include <stdio.h>")) {
chaz_ConfWriter_add_def("HAS__SCPRINTF", NULL);
- free(output);
}
- output = chaz_CC_capture_output(detect__snprintf_code, &output_len);
- if (output != NULL) {
+ if (chaz_HeadCheck_defines_symbol("_snprintf", "#include <stdio.h>")) {
chaz_ConfWriter_add_def("HAS__SNPRINTF", NULL);
- free(output);
}
}
diff --git a/src/Charmonizer/Probe/VariadicMacros.c b/src/Charmonizer/Probe/VariadicMacros.c
index d6f2d9f..0fd7bdd 100644
--- a/src/Charmonizer/Probe/VariadicMacros.c
+++ b/src/Charmonizer/Probe/VariadicMacros.c
@@ -26,48 +26,35 @@
/* Code for verifying ISO-style variadic macros. */
static const char chaz_VariadicMacros_iso_code[] =
CHAZ_QUOTE( #include <stdio.h> )
- CHAZ_QUOTE( #define ISO_TEST(fmt, ...) \\ )
- " printf(fmt, __VA_ARGS__) \n"
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( ISO_TEST("%d %d", 1, 1); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+ "#define ISO_TEST(fmt, ...) printf(fmt, __VA_ARGS__)\n"
+ CHAZ_QUOTE( void f() { ISO_TEST("%d %d", 1, 1); } );
/* Code for verifying GNU-style variadic macros. */
static const char chaz_VariadicMacros_gnuc_code[] =
CHAZ_QUOTE( #include <stdio.h> )
CHAZ_QUOTE( #define GNU_TEST(fmt, args...) printf(fmt, ##args) )
- CHAZ_QUOTE( int main() { )
- CHAZ_QUOTE( GNU_TEST("%d %d", 1, 1); )
- CHAZ_QUOTE( return 0; )
- CHAZ_QUOTE( } );
+ CHAZ_QUOTE( void f() { GNU_TEST("%d %d", 1, 1); } );
void
chaz_VariadicMacros_run(void) {
- char *output;
- size_t output_len;
int has_varmacros = false;
chaz_ConfWriter_start_module("VariadicMacros");
/* Test for ISO-style variadic macros. */
- output = chaz_CC_capture_output(chaz_VariadicMacros_iso_code, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(chaz_VariadicMacros_iso_code)) {
has_varmacros = true;
chaz_ConfWriter_add_def("HAS_VARIADIC_MACROS", NULL);
chaz_ConfWriter_add_def("HAS_ISO_VARIADIC_MACROS", NULL);
- free(output);
}
/* Test for GNU-style variadic macros. */
- output = chaz_CC_capture_output(chaz_VariadicMacros_gnuc_code, &output_len);
- if (output != NULL) {
+ if (chaz_CC_test_compile(chaz_VariadicMacros_gnuc_code)) {
if (has_varmacros == false) {
has_varmacros = true;
chaz_ConfWriter_add_def("HAS_VARIADIC_MACROS", NULL);
}
chaz_ConfWriter_add_def("HAS_GNUC_VARIADIC_MACROS", NULL);
- free(output);
}
chaz_ConfWriter_end_module();