Support recursive execution of nmake Detect 'make' utility using Marvin's code from LUCY-249.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/a9dcde34 Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/a9dcde34 Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/a9dcde34 Branch: refs/heads/c-bindings-cfc Commit: a9dcde34ed8d8a73589b569203e97daf70a3f843 Parents: a4d59e2 Author: Nick Wellnhofer <[email protected]> Authored: Tue Feb 12 20:45:59 2013 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Tue Feb 12 21:10:23 2013 +0100 ---------------------------------------------------------------------- charmonizer/src/Charmonizer/Core/Make.c | 145 ++++++++++++++++++++++++-- charmonizer/src/Charmonizer/Core/Make.h | 9 ++ charmonizer/src/Charmonizer/Probe.c | 2 + 3 files changed, 148 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/a9dcde34/charmonizer/src/Charmonizer/Core/Make.c ---------------------------------------------------------------------- diff --git a/charmonizer/src/Charmonizer/Core/Make.c b/charmonizer/src/Charmonizer/Core/Make.c index 267d39a..6e48370 100644 --- a/charmonizer/src/Charmonizer/Core/Make.c +++ b/charmonizer/src/Charmonizer/Core/Make.c @@ -41,6 +41,110 @@ struct chaz_MakeFile { size_t num_cleanups; }; +/* Static vars. */ +static struct { + char *make_command; + int is_gnu_make; + int is_nmake; +} chaz_Make = { + NULL, + 0, 0 +}; + +/* Detect make command. + * + * The argument list must be a NULL-terminated series of different spellings + * of `make`, which will be auditioned in the order they are supplied. Here + * are several possibilities: + * + * make + * gmake + * nmake + * dmake + */ +static int +chaz_Make_detect(const char *make1, ...); + +static int +chaz_Make_audition(const char *make); + +void +chaz_Make_init(void) { + const char *make; + + chaz_Make_detect("make", "gmake", "nmake", "dmake", NULL); + make = chaz_Make.make_command; + + if (make) { + if (strcmp(make, "make") == 0 || strcmp(make, "gmake") == 0) { + /* TODO: Add a feature test for GNU make. */ + chaz_Make.is_gnu_make = 1; + } + else if (strcmp(make, "nmake") == 0) { + chaz_Make.is_nmake = 1; + } + } +} + +void +chaz_Make_clean_up(void) { + free(chaz_Make.make_command); +} + +const char* +chaz_Make_get_make(void) { + return chaz_Make.make_command; +} + +static int +chaz_Make_detect(const char *make1, ...) { + va_list args; + const char *candidate; + int found = 0; + const char makefile_content[] = "foo:\n\techo \"foo!\"\n"; + chaz_Util_write_file("_charm_Makefile", makefile_content); + + /* Audition candidates. */ + found = chaz_Make_audition(make1); + va_start(args, make1); + while (!found && (NULL != (candidate = va_arg(args, const char*)))) { + found = chaz_Make_audition(candidate); + } + va_end(args); + + chaz_Util_remove_and_verify("_charm_Makefile"); + + return found; +} + +static int +chaz_Make_audition(const char *make) { + int succeeded = 0; + const char pattern[] = "%s -f _charm_Makefile"; + size_t size = strlen(make) + sizeof(pattern) + 10; + char *command = (char*)malloc(size); + sprintf(command, pattern, make); + + chaz_Util_remove_and_verify("_charm_foo"); + chaz_OS_run_redirected(command, "_charm_foo"); + if (chaz_Util_can_open_file("_charm_foo")) { + size_t len; + char *content = chaz_Util_slurp_file("_charm_foo", &len); + if (NULL != strstr(content, "foo!")) { + succeeded = 1; + } + free(content); + } + chaz_Util_remove_and_verify("_charm_foo"); + + if (succeeded) { + chaz_Make.make_command = chaz_Util_strdup(make); + } + + free(command); + return succeeded; +} + chaz_MakeFile* chaz_MakeFile_new() { chaz_MakeFile *makefile = (chaz_MakeFile*)malloc(sizeof(chaz_MakeFile)); @@ -298,20 +402,45 @@ chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command) { void chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, const char *target) { + const char *make = chaz_Make.make_command; char *command; - if (!target) { + if (chaz_Make.is_gnu_make) { + if (!target) { + size_t size = strlen(dir) + 20; + command = (char*)malloc(size); + sprintf(command, "$(MAKE) -C %s", dir); + } + else { + size_t size = strlen(dir) + strlen(target) + 20; + command = (char*)malloc(size); + sprintf(command, "$(MAKE) -C %s %s", dir, target); + } + chaz_MakeRule_add_command(rule, command); + free(command); + } + else if (chaz_Make.is_nmake) { command = (char*)malloc(strlen(dir) + 20); - sprintf(command, "make -C %s", dir); + sprintf(command, "cd %s", dir); + chaz_MakeRule_add_command(rule, command); + free(command); + + if (!target) { + chaz_MakeRule_add_command(rule, "$(MAKE)"); + } + else { + size_t size = strlen(target) + 20; + command = (char*)malloc(size); + sprintf(command, "$(MAKE) %s", target); + chaz_MakeRule_add_command(rule, command); + free(command); + } + + chaz_MakeRule_add_command(rule, "cd $(MAKEDIR)"); } else { - command = (char*)malloc(strlen(dir) + strlen(target) + 20); - sprintf(command, "make -C %s %s", dir, target); + chaz_Util_die("Couldn't find a supported 'make' utility."); } - - chaz_MakeRule_add_command(rule, command); - - free(command); } void http://git-wip-us.apache.org/repos/asf/lucy/blob/a9dcde34/charmonizer/src/Charmonizer/Core/Make.h ---------------------------------------------------------------------- diff --git a/charmonizer/src/Charmonizer/Core/Make.h b/charmonizer/src/Charmonizer/Core/Make.h index cfcb42a..2fe1cf6 100644 --- a/charmonizer/src/Charmonizer/Core/Make.h +++ b/charmonizer/src/Charmonizer/Core/Make.h @@ -31,6 +31,15 @@ typedef struct chaz_MakeRule chaz_MakeRule; typedef void (*chaz_Make_list_files_callback_t)(char *file, void *context); void +chaz_Make_init(void); + +void +chaz_Make_clean_up(void); + +const char* +chaz_Make_get_make(void); + +void chaz_Make_list_files(const char *dir, const char *ext, chaz_Make_list_files_callback_t callback, void *context); http://git-wip-us.apache.org/repos/asf/lucy/blob/a9dcde34/charmonizer/src/Charmonizer/Probe.c ---------------------------------------------------------------------- diff --git a/charmonizer/src/Charmonizer/Probe.c b/charmonizer/src/Charmonizer/Probe.c index c072e7e..c1475db 100644 --- a/charmonizer/src/Charmonizer/Probe.c +++ b/charmonizer/src/Charmonizer/Probe.c @@ -118,6 +118,7 @@ chaz_Probe_init(struct chaz_CLIArgs *args) { chaz_CC_init(args->cc, args->cflags); chaz_ConfWriter_init(); chaz_HeadCheck_init(); + chaz_Make_init(); /* Enable output. */ if (args->charmony_h) { @@ -147,6 +148,7 @@ chaz_Probe_clean_up(void) { /* Dispatch various clean up routines. */ chaz_ConfWriter_clean_up(); chaz_CC_clean_up(); + chaz_Make_clean_up(); if (chaz_Util_verbosity) { printf("Cleanup complete.\n"); } }
