You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2015/07/25 17:32:58 UTC
[1/4] lucy git commit: Fix C installation script
Repository: lucy
Updated Branches:
refs/heads/0.4 7beddbcfb -> e43b48311
Fix C installation script
Support symbolic links in man page destination directory.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/1aecf7a9
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/1aecf7a9
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/1aecf7a9
Branch: refs/heads/0.4
Commit: 1aecf7a9055e57b978895d7cc38053b22ddfe7d6
Parents: 7beddbc
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 11 17:56:27 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Jul 24 21:03:58 2015 +0200
----------------------------------------------------------------------
c/install.sh | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/1aecf7a9/c/install.sh
----------------------------------------------------------------------
diff --git a/c/install.sh b/c/install.sh
index 94f28d7..eab7673 100755
--- a/c/install.sh
+++ b/c/install.sh
@@ -99,7 +99,14 @@ for src in `find ../core -name '*.cf[hp]'`; do
done
# Install man pages.
-cp -R autogen/man "$prefix"
+mkdir -p "$prefix/man"
+# Resolve symbolic links.
+man_dir=$(cd "$prefix/man" && pwd -P)
+if [ -n "$man_dir" ]; then
+ cp -R autogen/man "$man_dir"
+else
+ echo "Warning: Invalid directory $prefix/man"
+fi
# Create pkg-config file.
mkdir -p "$prefix/lib/pkgconfig"
[4/4] lucy git commit: Fix build with --clownfish-prefix on Windows
Posted by nw...@apache.org.
Fix build with --clownfish-prefix on Windows
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/e43b4831
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/e43b4831
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/e43b4831
Branch: refs/heads/0.4
Commit: e43b48311f187ea832a3c4dc6df5f11cc02128dc
Parents: 8572510
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 25 15:30:43 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 25 15:30:43 2015 +0200
----------------------------------------------------------------------
common/charmonizer.c | 44 ++++++++++++++++++++++----------------------
common/charmonizer.main | 38 ++++++++++++++++++--------------------
2 files changed, 40 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/e43b4831/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/common/charmonizer.c b/common/charmonizer.c
index 516a04f..75490ac 100644
--- a/common/charmonizer.c
+++ b/common/charmonizer.c
@@ -784,7 +784,7 @@ chaz_MakeFile_add_lemon_grammar(chaz_MakeFile *makefile,
* @param obj The object file.
* @param cflags Compiler flags.
*/
-void
+chaz_MakeRule*
chaz_MakeFile_override_cflags(chaz_MakeFile *makefile, const char *obj,
chaz_CFlags *cflags);
@@ -4881,7 +4881,7 @@ chaz_MakeFile_add_lemon_grammar(chaz_MakeFile *makefile,
return rule;
}
-void
+chaz_MakeRule*
chaz_MakeFile_override_cflags(chaz_MakeFile *makefile, const char *obj,
chaz_CFlags *cflags) {
const char *obj_ext = chaz_CC_obj_ext();
@@ -4920,6 +4920,8 @@ chaz_MakeFile_override_cflags(chaz_MakeFile *makefile, const char *obj,
free(command);
free(src);
+
+ return rule;
}
void
@@ -8046,6 +8048,8 @@ S_write_makefile(struct chaz_CLI *cli) {
"Json", "JsonParser", NULL);
char *test_lucy_exe = chaz_Util_join("", "t", dir_sep, "test_lucy",
exe_ext, NULL);
+ char *test_lucy_obj = chaz_Util_join("", "t", dir_sep, "test_lucy",
+ obj_ext, NULL);
char *autogen_inc_dir
= chaz_Util_join(dir_sep, "autogen", "include", NULL);
@@ -8217,35 +8221,29 @@ S_write_makefile(struct chaz_CLI *cli) {
test_cflags = chaz_CC_new_cflags();
chaz_CFlags_enable_optimization(test_cflags);
chaz_CFlags_add_include_dir(test_cflags, autogen_inc_dir);
- chaz_CFlags_add_library(test_cflags, lib);
+ rule = chaz_MakeFile_override_cflags(makefile, test_lucy_obj, test_cflags);
+ chaz_MakeRule_add_prereq(rule, autogen_target);
+ chaz_CFlags_destroy(test_cflags);
+
+ link_flags = chaz_CC_new_cflags();
+ chaz_CFlags_add_library(link_flags, lib);
if (cfish_lib_dir) {
chaz_CFlags_add_library_path(link_flags, cfish_lib_dir);
}
- chaz_CFlags_add_external_library(test_cflags, cfish_lib_name);
- scratch = chaz_Util_join(dir_sep, "t", "test_lucy.c", NULL);
- rule = chaz_MakeFile_add_compiled_exe(makefile, test_lucy_exe, scratch,
- test_cflags);
- free(scratch);
+ chaz_CFlags_add_external_library(link_flags, cfish_lib_name);
+ rule = chaz_MakeFile_add_exe(makefile, test_lucy_exe, test_lucy_obj,
+ link_flags);
chaz_MakeRule_add_prereq(rule, lib_filename);
- chaz_CFlags_destroy(test_cflags);
+ chaz_CFlags_destroy(link_flags);
rule = chaz_MakeFile_add_rule(makefile, "test", test_lucy_exe);
- if (strcmp(chaz_OS_shared_lib_ext(), ".so") == 0) {
- if (cfish_lib_dir) {
- test_command
- = chaz_Util_join("", "LD_LIBRARY_PATH=.:", cfish_lib_dir,
- ":$$LD_LIBRARY_PATH ", test_lucy_exe, NULL);
- }
- else {
- test_command
- = chaz_Util_join(" ", "LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH",
- test_lucy_exe, NULL);
- }
+ if (cfish_lib_dir) {
+ chaz_MakeRule_add_command_with_libpath(rule, test_lucy_exe, ".",
+ cfish_lib_dir, NULL);
}
else {
- test_command = chaz_Util_strdup(test_lucy_exe);
+ chaz_MakeRule_add_command_with_libpath(rule, test_lucy_exe, ".", NULL);
}
- chaz_MakeRule_add_command(rule, test_command);
if (chaz_CLI_defined(cli, "enable-coverage")) {
rule = chaz_MakeFile_add_rule(makefile, "coverage", test_lucy_exe);
@@ -8285,6 +8283,7 @@ S_write_makefile(struct chaz_CLI *cli) {
chaz_MakeRule_add_rm_command(clean_rule, "$(LUCY_OBJS)");
}
+ chaz_MakeRule_add_rm_command(clean_rule, test_lucy_obj);
chaz_MakeRule_add_recursive_rm_command(clean_rule, "autogen");
if (chaz_CLI_defined(cli, "enable-coverage")) {
@@ -8307,6 +8306,7 @@ S_write_makefile(struct chaz_CLI *cli) {
free(utf8proc_dir);
free(json_parser);
free(test_lucy_exe);
+ free(test_lucy_obj);
free(autogen_inc_dir);
free(autogen_target);
free(snowstem_inc_dir);
http://git-wip-us.apache.org/repos/asf/lucy/blob/e43b4831/common/charmonizer.main
----------------------------------------------------------------------
diff --git a/common/charmonizer.main b/common/charmonizer.main
index 66644d9..0ed7bc4 100644
--- a/common/charmonizer.main
+++ b/common/charmonizer.main
@@ -161,6 +161,8 @@ S_write_makefile(struct chaz_CLI *cli) {
"Json", "JsonParser", NULL);
char *test_lucy_exe = chaz_Util_join("", "t", dir_sep, "test_lucy",
exe_ext, NULL);
+ char *test_lucy_obj = chaz_Util_join("", "t", dir_sep, "test_lucy",
+ obj_ext, NULL);
char *autogen_inc_dir
= chaz_Util_join(dir_sep, "autogen", "include", NULL);
@@ -332,35 +334,29 @@ S_write_makefile(struct chaz_CLI *cli) {
test_cflags = chaz_CC_new_cflags();
chaz_CFlags_enable_optimization(test_cflags);
chaz_CFlags_add_include_dir(test_cflags, autogen_inc_dir);
- chaz_CFlags_add_library(test_cflags, lib);
+ rule = chaz_MakeFile_override_cflags(makefile, test_lucy_obj, test_cflags);
+ chaz_MakeRule_add_prereq(rule, autogen_target);
+ chaz_CFlags_destroy(test_cflags);
+
+ link_flags = chaz_CC_new_cflags();
+ chaz_CFlags_add_library(link_flags, lib);
if (cfish_lib_dir) {
chaz_CFlags_add_library_path(link_flags, cfish_lib_dir);
}
- chaz_CFlags_add_external_library(test_cflags, cfish_lib_name);
- scratch = chaz_Util_join(dir_sep, "t", "test_lucy.c", NULL);
- rule = chaz_MakeFile_add_compiled_exe(makefile, test_lucy_exe, scratch,
- test_cflags);
- free(scratch);
+ chaz_CFlags_add_external_library(link_flags, cfish_lib_name);
+ rule = chaz_MakeFile_add_exe(makefile, test_lucy_exe, test_lucy_obj,
+ link_flags);
chaz_MakeRule_add_prereq(rule, lib_filename);
- chaz_CFlags_destroy(test_cflags);
+ chaz_CFlags_destroy(link_flags);
rule = chaz_MakeFile_add_rule(makefile, "test", test_lucy_exe);
- if (strcmp(chaz_OS_shared_lib_ext(), ".so") == 0) {
- if (cfish_lib_dir) {
- test_command
- = chaz_Util_join("", "LD_LIBRARY_PATH=.:", cfish_lib_dir,
- ":$$LD_LIBRARY_PATH ", test_lucy_exe, NULL);
- }
- else {
- test_command
- = chaz_Util_join(" ", "LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH",
- test_lucy_exe, NULL);
- }
+ if (cfish_lib_dir) {
+ chaz_MakeRule_add_command_with_libpath(rule, test_lucy_exe, ".",
+ cfish_lib_dir, NULL);
}
else {
- test_command = chaz_Util_strdup(test_lucy_exe);
+ chaz_MakeRule_add_command_with_libpath(rule, test_lucy_exe, ".", NULL);
}
- chaz_MakeRule_add_command(rule, test_command);
if (chaz_CLI_defined(cli, "enable-coverage")) {
rule = chaz_MakeFile_add_rule(makefile, "coverage", test_lucy_exe);
@@ -400,6 +396,7 @@ S_write_makefile(struct chaz_CLI *cli) {
chaz_MakeRule_add_rm_command(clean_rule, "$(LUCY_OBJS)");
}
+ chaz_MakeRule_add_rm_command(clean_rule, test_lucy_obj);
chaz_MakeRule_add_recursive_rm_command(clean_rule, "autogen");
if (chaz_CLI_defined(cli, "enable-coverage")) {
@@ -422,6 +419,7 @@ S_write_makefile(struct chaz_CLI *cli) {
free(utf8proc_dir);
free(json_parser);
free(test_lucy_exe);
+ free(test_lucy_obj);
free(autogen_inc_dir);
free(autogen_target);
free(snowstem_inc_dir);
[3/4] lucy git commit: Upgrade to latest Charmonizer version
Posted by nw...@apache.org.
Upgrade to latest Charmonizer version
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/8572510d
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/8572510d
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/8572510d
Branch: refs/heads/0.4
Commit: 8572510d5cccd6567588bc2efd5ed287610f81a0
Parents: 0fdd4e3
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 25 15:16:30 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 25 15:16:30 2015 +0200
----------------------------------------------------------------------
common/charmonizer.c | 1260 +++++++++++++++++++++++++++++++++---------
common/charmonizer.main | 66 +--
2 files changed, 1038 insertions(+), 288 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/8572510d/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/common/charmonizer.c b/common/charmonizer.c
index 47e1e1d..516a04f 100644
--- a/common/charmonizer.c
+++ b/common/charmonizer.c
@@ -36,47 +36,58 @@
/***************************************************************************/
-#line 21 "src/Charmonizer/Core/SharedLibrary.h"
-/* Charmonizer/Core/SharedLibrary.h
+#line 21 "src/Charmonizer/Core/Library.h"
+/* Charmonizer/Core/Library.h
*/
-#ifndef H_CHAZ_SHARED_LIB
-#define H_CHAZ_SHARED_LIB
+#ifndef H_CHAZ_LIB
+#define H_CHAZ_LIB
-typedef struct chaz_SharedLib chaz_SharedLib;
+typedef struct chaz_Lib chaz_Lib;
-chaz_SharedLib*
-chaz_SharedLib_new(const char *name, const char *version,
- const char *major_version);
+typedef enum {
+ chaz_Lib_SHARED = 1,
+ chaz_Lib_STATIC = 2
+} chaz_LibType;
+
+chaz_Lib*
+chaz_Lib_new(const char *name, chaz_LibType type, const char *version,
+ const char *major_version);
void
-chaz_SharedLib_destroy(chaz_SharedLib *flags);
+chaz_Lib_destroy(chaz_Lib *flags);
const char*
-chaz_SharedLib_get_name(chaz_SharedLib *lib);
+chaz_Lib_get_name(chaz_Lib *lib);
const char*
-chaz_SharedLib_get_version(chaz_SharedLib *lib);
+chaz_Lib_get_version(chaz_Lib *lib);
const char*
-chaz_SharedLib_get_major_version(chaz_SharedLib *lib);
+chaz_Lib_get_major_version(chaz_Lib *lib);
+
+int
+chaz_Lib_is_shared(chaz_Lib *lib);
+
+int
+chaz_Lib_is_static(chaz_Lib *lib);
char*
-chaz_SharedLib_filename(chaz_SharedLib *lib);
+chaz_Lib_filename(chaz_Lib *lib);
char*
-chaz_SharedLib_major_version_filename(chaz_SharedLib *lib);
+chaz_Lib_major_version_filename(chaz_Lib *lib);
char*
-chaz_SharedLib_no_version_filename(chaz_SharedLib *lib);
+chaz_Lib_no_version_filename(chaz_Lib *lib);
char*
-chaz_SharedLib_implib_filename(chaz_SharedLib *lib);
+chaz_Lib_implib_filename(chaz_Lib *lib);
char*
-chaz_SharedLib_export_filename(chaz_SharedLib *lib);
+chaz_Lib_export_filename(chaz_Lib *lib);
-#endif /* H_CHAZ_SHARED_LIB */
+#endif /* H_CHAZ_LIB */
@@ -89,7 +100,7 @@ chaz_SharedLib_export_filename(chaz_SharedLib *lib);
#ifndef H_CHAZ_CFLAGS
#define H_CHAZ_CFLAGS
-/* #include "Charmonizer/Core/SharedLibrary.h" */
+/* #include "Charmonizer/Core/Library.h" */
#define CHAZ_CFLAGS_STYLE_POSIX 1
#define CHAZ_CFLAGS_STYLE_GNU 2
@@ -145,8 +156,7 @@ void
chaz_CFlags_link_shared_library(chaz_CFlags *flags);
void
-chaz_CFlags_set_shared_library_version(chaz_CFlags *flags,
- chaz_SharedLib *lib);
+chaz_CFlags_set_shared_library_version(chaz_CFlags *flags, chaz_Lib *lib);
void
chaz_CFlags_set_link_output(chaz_CFlags *flags, const char *filename);
@@ -155,7 +165,7 @@ void
chaz_CFlags_add_library_path(chaz_CFlags *flags, const char *directory);
void
-chaz_CFlags_add_library(chaz_CFlags *flags, chaz_SharedLib *lib);
+chaz_CFlags_add_library(chaz_CFlags *flags, chaz_Lib *lib);
void
chaz_CFlags_add_external_library(chaz_CFlags *flags, const char *library);
@@ -169,6 +179,97 @@ chaz_CFlags_enable_code_coverage(chaz_CFlags *flags);
/***************************************************************************/
+#line 21 "src/Charmonizer/Core/CLI.h"
+#ifndef H_CHAZ_CLI
+#define H_CHAZ_CLI 1
+
+#define CHAZ_CLI_NO_ARG 0
+#define CHAZ_CLI_ARG_REQUIRED (1 << 0)
+#define CHAZ_CLI_ARG_OPTIONAL (1 << 1)
+
+/* The CLI module provides argument parsing for a command line interface.
+ */
+
+typedef struct chaz_CLI chaz_CLI;
+
+/* Constructor.
+ *
+ * @param name The name of the application.
+ * @param description A description of the application.
+ */
+chaz_CLI*
+chaz_CLI_new(const char *name, const char *description);
+
+/* Destructor.
+ */
+void
+chaz_CLI_destroy(chaz_CLI *self);
+
+/* Return a string combining usage header with documentation of options.
+ */
+const char*
+chaz_CLI_help(chaz_CLI *self);
+
+/* Override the generated usage header.
+ */
+void
+chaz_CLI_set_usage(chaz_CLI *self, const char *usage);
+
+/* Register an option. Updates the "help" string, invalidating previous
+ * values. Returns true on success, or reports an error and returns false if
+ * the option was already registered.
+ */
+int
+chaz_CLI_register(chaz_CLI *self, const char *name, const char *help,
+ int flags);
+
+/* Set an option. The specified option must have been registered previously.
+ * The supplied `value` is optional and will be copied.
+ *
+ * Returns true on success. Reports an error and returns false on failure.
+ */
+int
+chaz_CLI_set(chaz_CLI *self, const char *name, const char *value);
+
+/* Returns true if the option has been set, false otherwise.
+ */
+int
+chaz_CLI_defined(chaz_CLI *self, const char *name);
+
+/* Return the value of a given option converted to a long int. Defaults to 0.
+ * Reports an error if the named option has not been registered.
+ */
+long
+chaz_CLI_longval(chaz_CLI *self, const char *name);
+
+/* Return the value of an option as a C string. Defaults to NULL. Reports an
+ * error if the named option has not been registered.
+ */
+const char*
+chaz_CLI_strval(chaz_CLI *self, const char *name);
+
+/* Unset an option, making subsequent calls to `get` return false and making
+ * it possible to call `set` again.
+ *
+ * Returns true if the option exists and was able to be unset.
+ */
+int
+chaz_CLI_unset(chaz_CLI *self, const char *name);
+
+/* Parse `argc` and `argv`, setting options as appropriate. Returns true on
+ * success. Reports an error and returns false if either an unexpected option
+ * was encountered or an option which requires an argument was supplied
+ * without one.
+ */
+int
+chaz_CLI_parse(chaz_CLI *self, int argc, const char *argv[]);
+
+#endif /* H_CHAZ_CLI */
+
+
+
+/***************************************************************************/
+
#line 21 "src/Charmonizer/Core/Compiler.h"
/* Charmonizer/Core/Compiler.h
*/
@@ -200,6 +301,12 @@ chaz_CC_compile_obj(const char *source_path, const char *obj_path,
int
chaz_CC_test_compile(const char *source);
+/* Attempt to compile and link the supplied source code and return true if
+ * the effort succeeds.
+ */
+int
+chaz_CC_test_link(const char *source);
+
/* Attempt to compile the supplied source code. If successful, capture the
* output of the program and return a pointer to a newly allocated buffer.
* If the compilation fails, return NULL. The length of the captured
@@ -263,6 +370,21 @@ chaz_CC_sun_c_version_num(void);
const char*
chaz_CC_link_command(void);
+/* Create a command for building a static library.
+ *
+ * @param target The target library filename.
+ * @param objects The list of object files to be archived in the library.
+ */
+char*
+chaz_CC_format_archiver_command(const char *target, const char *objects);
+
+/* Returns a "ranlib" command if valid.
+ *
+ * @param target The library filename.
+ */
+char*
+chaz_CC_format_ranlib_command(const char *target);
+
#endif /* H_CHAZ_COMPILER */
@@ -477,6 +599,10 @@ chaz_HeadCheck_check_header(const char *header_name);
int
chaz_HeadCheck_check_many_headers(const char **header_names);
+/* Return true if the symbol is defined (possibly as a macro). */
+int
+chaz_HeadCheck_defines_symbol(const char *symbol, const char *includes);
+
/* Return true if the member is present in the struct. */
int
chaz_HeadCheck_contains_member(const char *struct_name, const char *member,
@@ -496,7 +622,7 @@ chaz_HeadCheck_contains_member(const char *struct_name, const char *member,
#define H_CHAZ_MAKE
/* #include "Charmonizer/Core/CFlags.h" */
-/* #include "Charmonizer/Core/SharedLibrary.h" */
+/* #include "Charmonizer/Core/Library.h" */
typedef struct chaz_MakeFile chaz_MakeFile;
typedef struct chaz_MakeVar chaz_MakeVar;
@@ -506,9 +632,11 @@ typedef void (*chaz_Make_list_files_callback_t)(const char *dir, char *file,
void *context);
/** Initialize the environment.
+ *
+ * @param make_command Name of the make command. Auto-detect if NULL.
*/
void
-chaz_Make_init(void);
+chaz_Make_init(const char *make_command);
/** Clean up the environment.
*/
@@ -619,9 +747,20 @@ chaz_MakeFile_add_compiled_exe(chaz_MakeFile *makefile, const char *exe,
* @param link_flags Additional link flags.
*/
chaz_MakeRule*
-chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
+chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_Lib *lib,
const char *sources, chaz_CFlags *link_flags);
+/** Add a rule to create a static library. The static library will also be added
+ * to the list of files to clean.
+ *
+ * @param makefile The makefile.
+ * @param lib The static library.
+ * @param objects The list of object files to be archived.
+ */
+chaz_MakeRule*
+chaz_MakeFile_add_static_lib(chaz_MakeFile *makefile, chaz_Lib *lib,
+ const char *objects);
+
/** Add a rule to build the lemon parser generator.
*
* @param makefile The makefile.
@@ -639,6 +778,16 @@ chaz_MakeRule*
chaz_MakeFile_add_lemon_grammar(chaz_MakeFile *makefile,
const char *base_name);
+/** Override compiler flags for a single object file.
+ *
+ * @param makefile The makefile.
+ * @param obj The object file.
+ * @param cflags Compiler flags.
+ */
+void
+chaz_MakeFile_override_cflags(chaz_MakeFile *makefile, const char *obj,
+ chaz_CFlags *cflags);
+
/** Write the makefile to a file named 'Makefile' in the current directory.
*
* @param makefile The makefile.
@@ -679,6 +828,16 @@ chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq);
void
chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command);
+/** Add a command to be executed with a special runtime library path.
+ *
+ * @param rule The rule.
+ * @param command The additional command.
+ * @param ... NULL-terminated list of library directories.
+ */
+void
+chaz_MakeRule_add_command_with_libpath(chaz_MakeRule *rule,
+ const char *command, ...);
+
/** Add a command to remove one or more files.
*
* @param rule The rule.
@@ -783,6 +942,11 @@ chaz_OS_exe_ext(void);
const char*
chaz_OS_shared_lib_ext(void);
+/* Return the extension for a static library on this system.
+ */
+const char*
+chaz_OS_static_lib_ext(void);
+
/* Return the equivalent of /dev/null on this system.
*/
const char*
@@ -843,6 +1007,11 @@ chaz_Util_strdup(const char *string);
char*
chaz_Util_join(const char *sep, ...);
+/* Join a NULL-terminated list of strings using a separator.
+ */
+char*
+chaz_Util_vjoin(const char *sep, va_list args);
+
/* Get the length of a file (may overshoot on text files under DOS).
*/
long
@@ -883,20 +1052,7 @@ chaz_Util_can_open_file(const char *file_path);
#include <stddef.h>
#include <stdio.h>
-#define CHAZ_PROBE_MAX_CC_LEN 100
-#define CHAZ_PROBE_MAX_CFLAGS_LEN 2000
-
-struct chaz_CLIArgs {
- char cc[CHAZ_PROBE_MAX_CC_LEN + 1];
- char cflags[CHAZ_PROBE_MAX_CFLAGS_LEN + 1];
- int charmony_h;
- int charmony_pm;
- int charmony_py;
- int charmony_rb;
- int verbosity;
- int write_makefile;
- int code_coverage;
-};
+struct chaz_CLI;
/* Parse command line arguments, initializing and filling in the supplied
* `args` struct.
@@ -913,7 +1069,7 @@ struct chaz_CLIArgs {
*/
int
chaz_Probe_parse_cli_args(int argc, const char *argv[],
- struct chaz_CLIArgs *args);
+ struct chaz_CLI *cli);
/* Exit after printing usage instructions to stderr.
*/
@@ -930,7 +1086,7 @@ chaz_Probe_die_usage(void);
* 2 - debugging
*/
void
-chaz_Probe_init(struct chaz_CLIArgs *args);
+chaz_Probe_init(struct chaz_CLI *cli);
/* Clean up the Charmonizer environment -- deleting tempfiles, etc. This
* should be called only after everything else finishes.
@@ -1540,38 +1696,53 @@ void chaz_VariadicMacros_run(void);
/***************************************************************************/
-#line 17 "src/Charmonizer/Core/SharedLibrary.c"
+#line 17 "src/Charmonizer/Core/Library.c"
#include <string.h>
#include <stdlib.h>
-/* #include "Charmonizer/Core/SharedLibrary.h" */
+/* #include "Charmonizer/Core/Library.h" */
/* #include "Charmonizer/Core/Compiler.h" */
/* #include "Charmonizer/Core/Util.h" */
/* #include "Charmonizer/Core/OperatingSystem.h" */
-struct chaz_SharedLib {
+struct chaz_Lib {
char *name;
char *version;
char *major_version;
+ int is_static;
+ int is_shared;
+ chaz_LibType lib_type;
};
static char*
-S_build_filename(chaz_SharedLib *lib, const char *version, const char *ext);
+S_build_filename(chaz_Lib *lib, const char *version, const char *ext);
static const char*
S_get_prefix(void);
-chaz_SharedLib*
-chaz_SharedLib_new(const char *name, const char *version,
- const char *major_version) {
- chaz_SharedLib *lib = (chaz_SharedLib*)malloc(sizeof(chaz_SharedLib));
+chaz_Lib*
+chaz_Lib_new(const char *name, chaz_LibType lib_type, const char *version,
+ const char *major_version) {
+ chaz_Lib *lib = (chaz_Lib*)malloc(sizeof(chaz_Lib));
lib->name = chaz_Util_strdup(name);
lib->version = chaz_Util_strdup(version);
lib->major_version = chaz_Util_strdup(major_version);
+ lib->lib_type = lib_type;
+ if (lib_type == chaz_Lib_SHARED) {
+ lib->is_shared = 1;
+ lib->is_static = 0;
+ }
+ else if (lib_type == chaz_Lib_STATIC) {
+ lib->is_shared = 0;
+ lib->is_static = 1;
+ }
+ else {
+ chaz_Util_die("Invalid value for lib_type: %d", lib_type);
+ }
return lib;
}
void
-chaz_SharedLib_destroy(chaz_SharedLib *lib) {
+chaz_Lib_destroy(chaz_Lib *lib) {
free(lib->name);
free(lib->version);
free(lib->major_version);
@@ -1579,62 +1750,78 @@ chaz_SharedLib_destroy(chaz_SharedLib *lib) {
}
const char*
-chaz_SharedLib_get_name(chaz_SharedLib *lib) {
+chaz_Lib_get_name(chaz_Lib *lib) {
return lib->name;
}
const char*
-chaz_SharedLib_get_version(chaz_SharedLib *lib) {
+chaz_Lib_get_version(chaz_Lib *lib) {
return lib->version;
}
const char*
-chaz_SharedLib_get_major_version(chaz_SharedLib *lib) {
+chaz_Lib_get_major_version(chaz_Lib *lib) {
return lib->major_version;
}
+int
+chaz_Lib_is_shared (chaz_Lib *lib) {
+ return lib->is_shared;
+}
+
+int
+chaz_Lib_is_static (chaz_Lib *lib) {
+ return lib->is_static;
+}
+
char*
-chaz_SharedLib_filename(chaz_SharedLib *lib) {
- const char *shlib_ext = chaz_OS_shared_lib_ext();
+chaz_Lib_filename(chaz_Lib *lib) {
+ const char *ext = lib->is_shared
+ ? chaz_OS_shared_lib_ext()
+ : chaz_OS_static_lib_ext();
- if (strcmp(shlib_ext, ".dll") == 0) {
- return S_build_filename(lib, lib->major_version, shlib_ext);
+ if ((strcmp(ext, ".dll") == 0) || strcmp(ext, ".lib") == 0) {
+ return S_build_filename(lib, lib->major_version, ext);
}
else {
- return S_build_filename(lib, lib->version, shlib_ext);
+ return S_build_filename(lib, lib->version, ext);
}
}
char*
-chaz_SharedLib_major_version_filename(chaz_SharedLib *lib) {
- const char *shlib_ext = chaz_OS_shared_lib_ext();
-
- return S_build_filename(lib, lib->major_version, shlib_ext);
+chaz_Lib_major_version_filename(chaz_Lib *lib) {
+ const char *ext = lib->is_shared
+ ? chaz_OS_shared_lib_ext()
+ : chaz_OS_static_lib_ext();
+ return S_build_filename(lib, lib->major_version, ext);
}
char*
-chaz_SharedLib_no_version_filename(chaz_SharedLib *lib) {
- const char *prefix = S_get_prefix();
- const char *shlib_ext = chaz_OS_shared_lib_ext();
-
- return chaz_Util_join("", prefix, lib->name, shlib_ext, NULL);
+chaz_Lib_no_version_filename(chaz_Lib *lib) {
+ const char *prefix = S_get_prefix();
+ const char *ext = lib->is_shared
+ ? chaz_OS_shared_lib_ext()
+ : chaz_OS_static_lib_ext();
+ return chaz_Util_join("", prefix, lib->name, ext, NULL);
}
char*
-chaz_SharedLib_implib_filename(chaz_SharedLib *lib) {
+chaz_Lib_implib_filename(chaz_Lib *lib) {
return S_build_filename(lib, lib->major_version, ".lib");
}
char*
-chaz_SharedLib_export_filename(chaz_SharedLib *lib) {
+chaz_Lib_export_filename(chaz_Lib *lib) {
return S_build_filename(lib, lib->major_version, ".exp");
}
static char*
-S_build_filename(chaz_SharedLib *lib, const char *version, const char *ext) {
+S_build_filename(chaz_Lib *lib, const char *version, const char *ext) {
const char *prefix = S_get_prefix();
const char *shlib_ext = chaz_OS_shared_lib_ext();
+ /* Use `shlib_ext` as a proxy for OS to determine behavior, but append
+ * the supplied `ext`. */
if (strcmp(shlib_ext, ".dll") == 0) {
return chaz_Util_join("", prefix, lib->name, "-", version, ext, NULL);
}
@@ -1670,7 +1857,7 @@ S_get_prefix() {
/* #include "Charmonizer/Core/Compiler.h" */
/* #include "Charmonizer/Core/Util.h" */
/* #include "Charmonizer/Core/OperatingSystem.h" */
-/* #include "Charmonizer/Core/SharedLibrary.h" */
+/* #include "Charmonizer/Core/Library.h" */
struct chaz_CFlags {
int style;
@@ -1922,20 +2109,19 @@ chaz_CFlags_link_shared_library(chaz_CFlags *flags) {
}
void
-chaz_CFlags_set_shared_library_version(chaz_CFlags *flags,
- chaz_SharedLib *lib) {
+chaz_CFlags_set_shared_library_version(chaz_CFlags *flags, chaz_Lib *lib) {
if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
const char *shlib_ext = chaz_OS_shared_lib_ext();
if (strcmp(shlib_ext, ".dylib") == 0) {
- const char *version = chaz_SharedLib_get_version(lib);
+ const char *version = chaz_Lib_get_version(lib);
char *string
= chaz_Util_join(" ", "-current_version", version, NULL);
chaz_CFlags_append(flags, string);
free(string);
}
else if (strcmp(shlib_ext, ".so") == 0) {
- char *soname = chaz_SharedLib_major_version_filename(lib);
+ char *soname = chaz_Lib_major_version_filename(lib);
char *string = chaz_Util_join("", "-Wl,-soname,", soname, NULL);
chaz_CFlags_append(flags, string);
free(string);
@@ -1943,7 +2129,7 @@ chaz_CFlags_set_shared_library_version(chaz_CFlags *flags,
}
}
else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
- char *soname = chaz_SharedLib_major_version_filename(lib);
+ char *soname = chaz_Lib_major_version_filename(lib);
char *string = chaz_Util_join(" ", "-h", soname, NULL);
chaz_CFlags_append(flags, string);
free(string);
@@ -1988,13 +2174,13 @@ chaz_CFlags_add_library_path(chaz_CFlags *flags, const char *directory) {
}
void
-chaz_CFlags_add_library(chaz_CFlags *flags, chaz_SharedLib *lib) {
+chaz_CFlags_add_library(chaz_CFlags *flags, chaz_Lib *lib) {
char *filename;
if (flags->style == CHAZ_CFLAGS_STYLE_MSVC) {
- filename = chaz_SharedLib_implib_filename(lib);
+ filename = chaz_Lib_implib_filename(lib);
}
else {
- filename = chaz_SharedLib_filename(lib);
+ filename = chaz_Lib_filename(lib);
}
chaz_CFlags_append(flags, filename);
free(filename);
@@ -2028,7 +2214,387 @@ chaz_CFlags_enable_code_coverage(chaz_CFlags *flags) {
/***************************************************************************/
+#line 17 "src/Charmonizer/Core/CLI.c"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+/* #include "Charmonizer/Core/CLI.h" */
+/* #include "Charmonizer/Core/Util.h" */
+
+typedef struct chaz_CLIOption {
+ char *name;
+ char *help;
+ char *value;
+ int defined;
+ int flags;
+} chaz_CLIOption;
+
+struct chaz_CLI {
+ char *name;
+ char *desc;
+ char *usage;
+ char *help;
+ chaz_CLIOption *opts;
+ int num_opts;
+};
+
+static void
+S_chaz_CLI_error(chaz_CLI *self, const char *pattern, ...) {
+ va_list ap;
+ if (chaz_Util_verbosity > 0) {
+ va_start(ap, pattern);
+ vfprintf(stderr, pattern, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ }
+}
+
+static void
+S_chaz_CLI_rebuild_help(chaz_CLI *self) {
+ int i;
+ size_t amount = 200; /* Length of section headers. */
+
+ /* Allocate space. */
+ if (self->usage) {
+ amount += strlen(self->usage);
+ }
+ else {
+ amount += strlen(self->name);
+ }
+ if (self->desc) {
+ amount += strlen(self->desc);
+ }
+ for (i = 0; i < self->num_opts; i++) {
+ chaz_CLIOption *opt = &self->opts[i];
+ amount += 24 + 2 * strlen(opt->name);
+ if (opt->flags) {
+ amount += strlen(opt->name);
+ }
+ if (opt->help) {
+ amount += strlen(opt->help);
+ }
+ }
+ free(self->help);
+ self->help = (char*)malloc(amount);
+ self->help[0] = '\0';
+
+ /* Accumulate "help" string. */
+ if (self->usage) {
+ strcat(self->help, self->usage);
+ }
+ else {
+ strcat(self->help, "Usage: ");
+ strcat(self->help, self->name);
+ if (self->num_opts) {
+ strcat(self->help, " [OPTIONS]");
+ }
+ }
+ if (self->desc) {
+ strcat(self->help, "\n\n");
+ strcat(self->help, self->desc);
+ }
+ strcat(self->help, "\n");
+ if (self->num_opts) {
+ strcat(self->help, "\nArguments:\n");
+ for (i = 0; i < self->num_opts; i++) {
+ chaz_CLIOption *opt = &self->opts[i];
+ size_t line_start = strlen(self->help);
+ size_t current_len;
+
+ strcat(self->help, " --");
+ strcat(self->help, opt->name);
+ current_len = strlen(self->help);
+ if (opt->flags) {
+ int j;
+ if (opt->flags & CHAZ_CLI_ARG_OPTIONAL) {
+ self->help[current_len++] = '[';
+ }
+ self->help[current_len++] = '=';
+ for (j = 0; opt->name[j]; j++) {
+ self->help[current_len++] = toupper(opt->name[j]);
+ }
+ if (opt->flags & CHAZ_CLI_ARG_OPTIONAL) {
+ self->help[current_len++] = ']';
+ }
+ self->help[current_len] = '\0';
+ }
+ if (opt->help) {
+ self->help[current_len++] = ' ';
+ while (current_len - line_start < 25) {
+ self->help[current_len++] = ' ';
+ }
+ self->help[current_len] = '\0';
+ strcpy(self->help + current_len, opt->help);
+ }
+ strcat(self->help, "\n");
+ }
+ }
+ strcat(self->help, "\n");
+}
+
+static chaz_CLIOption*
+S_find_opt(chaz_CLI *self, const char *name) {
+ int i;
+ for (i = 0; i < self->num_opts; i++) {
+ chaz_CLIOption *opt = &self->opts[i];
+ if (strcmp(opt->name, name) == 0) {
+ return opt;
+ }
+ }
+ return NULL;
+}
+
+chaz_CLI*
+chaz_CLI_new(const char *name, const char *description) {
+ chaz_CLI *self = calloc(1, sizeof(chaz_CLI));
+ self->name = chaz_Util_strdup(name ? name : "PROGRAM");
+ self->desc = description ? chaz_Util_strdup(description) : NULL;
+ self->help = NULL;
+ self->opts = NULL;
+ self->num_opts = 0;
+ S_chaz_CLI_rebuild_help(self);
+ return self;
+}
+
+void
+chaz_CLI_destroy(chaz_CLI *self) {
+ int i;
+ for (i = 0; i < self->num_opts; i++) {
+ chaz_CLIOption *opt = &self->opts[i];
+ free(opt->name);
+ free(opt->help);
+ free(opt->value);
+ }
+ free(self->name);
+ free(self->desc);
+ free(self->opts);
+ free(self->usage);
+ free(self->help);
+ free(self);
+}
+
+void
+chaz_CLI_set_usage(chaz_CLI *self, const char *usage) {
+ free(self->usage);
+ self->usage = chaz_Util_strdup(usage);
+}
+
+const char*
+chaz_CLI_help(chaz_CLI *self) {
+ return self->help;
+}
+
+int
+chaz_CLI_register(chaz_CLI *self, const char *name, const char *help,
+ int flags) {
+ int rank;
+ int i;
+ int arg_required = !!(flags & CHAZ_CLI_ARG_REQUIRED);
+ int arg_optional = !!(flags & CHAZ_CLI_ARG_OPTIONAL);
+
+ /* Validate flags */
+ if (arg_required && arg_optional) {
+ S_chaz_CLI_error(self, "Conflicting flags: value both optional "
+ "and required");
+ return 0;
+ }
+
+ /* Insert new option. Keep options sorted by name. */
+ for (rank = self->num_opts; rank > 0; rank--) {
+ int comparison = strcmp(name, self->opts[rank - 1].name);
+ if (comparison == 0) {
+ S_chaz_CLI_error(self, "Option '%s' already registered", name);
+ return 0;
+ }
+ else if (comparison > 0) {
+ break;
+ }
+ }
+ self->num_opts += 1;
+ self->opts = realloc(self->opts, self->num_opts * sizeof(chaz_CLIOption));
+ for (i = self->num_opts - 1; i > rank; i--) {
+ self->opts[i] = self->opts[i - 1];
+ }
+ self->opts[rank].name = chaz_Util_strdup(name);
+ self->opts[rank].help = help ? chaz_Util_strdup(help) : NULL;
+ self->opts[rank].flags = flags;
+ self->opts[rank].defined = 0;
+ self->opts[rank].value = NULL;
+
+ /* Update `help` with new option. */
+ S_chaz_CLI_rebuild_help(self);
+
+ return 1;
+}
+
+int
+chaz_CLI_set(chaz_CLI *self, const char *name, const char *value) {
+ chaz_CLIOption *opt = S_find_opt(self, name);
+ if (opt == NULL) {
+ S_chaz_CLI_error(self, "Attempt to set unknown option: '%s'", name);
+ return 0;
+ }
+ if (opt->defined) {
+ S_chaz_CLI_error(self, "'%s' specified multiple times", name);
+ return 0;
+ }
+ opt->defined = 1;
+ if (opt->flags == CHAZ_CLI_NO_ARG) {
+ if (value != NULL) {
+ S_chaz_CLI_error(self, "'%s' expects no value", name);
+ return 0;
+ }
+ }
+ else {
+ if (value == NULL) {
+ S_chaz_CLI_error(self, "'%s' expects a value", name);
+ return 0;
+ }
+ opt->value = chaz_Util_strdup(value);
+ }
+ return 1;
+}
+
+int
+chaz_CLI_unset(chaz_CLI *self, const char *name) {
+ chaz_CLIOption *opt = S_find_opt(self, name);
+ if (opt == NULL) {
+ S_chaz_CLI_error(self, "Attempt to unset unknown option: '%s'", name);
+ return 0;
+ }
+ free(opt->value);
+ opt->value = NULL;
+ opt->defined = 0;
+ return 1;
+}
+
+int
+chaz_CLI_defined(chaz_CLI *self, const char *name) {
+ chaz_CLIOption *opt = S_find_opt(self, name);
+ if (opt == NULL) {
+ S_chaz_CLI_error(self, "Inquiry for unknown option: '%s'", name);
+ return 0;
+ }
+ return opt->defined;
+}
+
+long
+chaz_CLI_longval(chaz_CLI *self, const char *name) {
+ chaz_CLIOption *opt = S_find_opt(self, name);
+ if (opt == NULL) {
+ S_chaz_CLI_error(self, "Longval request for unknown option: '%s'",
+ name);
+ return 0;
+ }
+ if (!opt->defined || !opt->value) {
+ return 0;
+ }
+ return strtol(opt->value, NULL, 10);
+}
+
+const char*
+chaz_CLI_strval(chaz_CLI *self, const char *name) {
+ chaz_CLIOption *opt = S_find_opt(self, name);
+ if (opt == NULL) {
+ S_chaz_CLI_error(self, "Strval request for unknown option: '%s'",
+ name);
+ return 0;
+ }
+ return opt->value;
+}
+
+int
+chaz_CLI_parse(chaz_CLI *self, int argc, const char *argv[]) {
+ int i;
+ char *name = NULL;
+ size_t name_cap = 0;
+
+ /* Parse most args. */
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ size_t name_len = 0;
+ const char *value = NULL;
+
+ /* Stop processing if we see `-` or `--`. */
+ if (strcmp(arg, "--") == 0 || strcmp(arg, "-") == 0) {
+ break;
+ }
+
+ if (strncmp(arg, "--", 2) != 0) {
+ S_chaz_CLI_error(self, "Unexpected argument: '%s'", arg);
+ free(name);
+ return 0;
+ }
+
+ /* Extract the name of the argument, look for a potential value. */
+ while (1) {
+ char c = arg[name_len + 2];
+ if (isalnum(c) || c == '-' || c == '_') {
+ name_len++;
+ }
+ else if (c == '\0') {
+ break;
+ }
+ else if (c == '=') {
+ /* The rest of the arg is the value. */
+ value = arg + 2 + name_len + 1;
+ break;
+ }
+ else {
+ free(name);
+ S_chaz_CLI_error(self, "Malformed argument: '%s'", arg);
+ return 0;
+ }
+ }
+ if (name_len + 1 > name_cap) {
+ name_cap = name_len + 1;
+ name = (char*)realloc(name, name_cap);
+ }
+ memcpy(name, arg + 2, name_len);
+ name[name_len] = '\0';
+
+ if (value == NULL && i + 1 < argc) {
+ /* Support both '--opt=val' and '--opt val' styles. */
+ chaz_CLIOption *opt = S_find_opt(self, name);
+ if (opt == NULL) {
+ S_chaz_CLI_error(self, "Attempt to set unknown option: '%s'",
+ name);
+ free(name);
+ return 0;
+ }
+ if (opt->flags != CHAZ_CLI_NO_ARG) {
+ i++;
+ value = argv[i];
+ }
+ }
+
+ /* Attempt to set the option. */
+ if (!chaz_CLI_set(self, name, value)) {
+ free(name);
+ return 0;
+ }
+ }
+
+ free(name);
+
+ for (i = 0; i < self->num_opts; i++) {
+ chaz_CLIOption *opt = &self->opts[i];
+ if (!opt->defined && (opt->flags & CHAZ_CLI_ARG_REQUIRED)) {
+ S_chaz_CLI_error(self, "Option '%s' is required", opt->name);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+
+/***************************************************************************/
+
#line 17 "src/Charmonizer/Core/Compiler.c"
+#include <errno.h>
#include <string.h>
#include <stdlib.h>
/* #include "Charmonizer/Core/Util.h" */
@@ -2073,6 +2639,7 @@ void
chaz_CC_init(const char *compiler_command, const char *compiler_flags) {
const char *code = "int main() { return 0; }\n";
int compile_succeeded = 0;
+ int retval = -1;
if (chaz_Util_verbosity) { printf("Creating compiler object...\n"); }
@@ -2086,23 +2653,37 @@ chaz_CC_init(const char *compiler_command, const char *compiler_flags) {
chaz_CC.try_exe_name
= chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_exe_ext(), NULL);
- /* If we can't compile anything, game over. */
+ /* If we can't compile or execute anything, game over. */
if (chaz_Util_verbosity) {
- printf("Trying to compile a small test file...\n");
+ printf("Trying to compile and execute a small test file...\n");
+ }
+ if (!chaz_Util_remove_and_verify(chaz_CC.try_exe_name)) {
+ chaz_Util_die("Failed to delete file '%s'", chaz_CC.try_exe_name);
}
/* Try MSVC argument style. */
strcpy(chaz_CC.obj_ext, ".obj");
chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_MSVC;
- compile_succeeded = chaz_CC_test_compile(code);
+ compile_succeeded = chaz_CC_compile_exe(CHAZ_CC_TRY_SOURCE_PATH,
+ CHAZ_CC_TRY_BASENAME, code);
if (!compile_succeeded) {
/* Try POSIX argument style. */
strcpy(chaz_CC.obj_ext, ".o");
chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_POSIX;
- compile_succeeded = chaz_CC_test_compile(code);
+ compile_succeeded = chaz_CC_compile_exe(CHAZ_CC_TRY_SOURCE_PATH,
+ CHAZ_CC_TRY_BASENAME, code);
}
if (!compile_succeeded) {
chaz_Util_die("Failed to compile a small test file");
}
+ retval = chaz_OS_run_local_redirected(chaz_CC.try_exe_name,
+ chaz_OS_dev_null());
+ chaz_Util_remove_and_verify(chaz_CC.try_exe_name);
+ if (retval < 0) {
+ chaz_Util_die("Failed to execute test file: %s", strerror(errno));
+ }
+ if (retval > 0) {
+ chaz_Util_die("Unexpected exit code %d from test file", retval);
+ }
chaz_CC_detect_known_compilers();
@@ -2295,6 +2876,18 @@ chaz_CC_test_compile(const char *source) {
return compile_succeeded;
}
+int
+chaz_CC_test_link(const char *source) {
+ int link_succeeded;
+ if (!chaz_Util_remove_and_verify(chaz_CC.try_exe_name)) {
+ chaz_Util_die("Failed to delete file '%s'", chaz_CC.try_exe_name);
+ }
+ link_succeeded = chaz_CC_compile_exe(CHAZ_CC_TRY_SOURCE_PATH,
+ CHAZ_CC_TRY_BASENAME, source);
+ chaz_Util_remove_and_verify(chaz_CC.try_exe_name);
+ return link_succeeded;
+}
+
char*
chaz_CC_capture_output(const char *source, size_t *output_len) {
char *captured_output = NULL;
@@ -2391,6 +2984,28 @@ chaz_CC_link_command() {
}
}
+char*
+chaz_CC_format_archiver_command(const char *target, const char *objects) {
+ if (chaz_CC.intval__MSC_VER) {
+ /* TODO: Write `objects` to a temporary file in order to avoid
+ * exceeding line length limits. */
+ char *out = chaz_Util_join("", "/OUT:", target, NULL);
+ char *command = chaz_Util_join(" ", "lib", "/NOLOGO", out, NULL);
+ free(out);
+ return command;
+ }
+ else {
+ return chaz_Util_join(" ", "ar", "rcs", target, objects, NULL);
+ }
+}
+
+char*
+chaz_CC_format_ranlib_command(const char *target) {
+ if (chaz_CC.intval__MSC_VER) {
+ return NULL;
+ }
+ return chaz_Util_join(" ", "ranlib", target, NULL);
+}
/***************************************************************************/
@@ -3658,6 +4273,34 @@ chaz_HeadCheck_check_many_headers(const char **header_names) {
}
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( #endif )
+ CHAZ_QUOTE( } );
+ long needed = sizeof(defines_code)
+ + 2 * strlen(symbol)
+ + strlen(includes)
+ + 10;
+ char *buf = (char*)malloc(needed);
+ int retval;
+ sprintf(buf, defines_code, includes, symbol, symbol);
+ retval = chaz_CC_test_compile(buf);
+ free(buf);
+ return retval;
+}
+
+int
chaz_HeadCheck_contains_member(const char *struct_name, const char *member,
const char *includes) {
static const char contains_code[] =
@@ -3814,15 +4457,17 @@ static void
S_write_rule(chaz_MakeRule *rule, FILE *out);
void
-chaz_Make_init(void) {
- const char *make;
-
- chaz_Make_detect("make", "gmake", "nmake", "dmake", "mingw32-make",
- "mingw64-make", NULL);
- make = chaz_Make.make_command;
+chaz_Make_init(const char *make_command) {
+ if (make_command) {
+ chaz_Make.make_command = chaz_Util_strdup(make_command);
+ }
+ else {
+ chaz_Make_detect("make", "gmake", "nmake", "dmake", "mingw32-make",
+ "mingw64-make", NULL);
+ }
- if (make) {
- if (strcmp(make, "nmake") == 0) {
+ if (chaz_Make.make_command) {
+ if (strcmp(chaz_Make.make_command, "nmake") == 0) {
chaz_Make.shell_type = CHAZ_OS_CMD_EXE;
}
else {
@@ -4056,7 +4701,7 @@ chaz_MakeFile_add_compiled_exe(chaz_MakeFile *makefile, const char *exe,
}
chaz_MakeRule*
-chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
+chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_Lib *lib,
const char *sources, chaz_CFlags *link_flags) {
chaz_CFlags *local_flags = chaz_CC_new_cflags();
const char *link = chaz_CC_link_command();
@@ -4067,7 +4712,7 @@ chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
char *filename;
char *command;
- filename = chaz_SharedLib_filename(lib);
+ filename = chaz_Lib_filename(lib);
rule = chaz_MakeFile_add_rule(makefile, filename, sources);
if (link_flags) {
@@ -4081,7 +4726,7 @@ chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
if (strcmp(shlib_ext, ".dylib") == 0) {
/* Set temporary install name with full path on Darwin. */
const char *dir_sep = chaz_OS_dir_sep();
- char *major_v_name = chaz_SharedLib_major_version_filename(lib);
+ char *major_v_name = chaz_Lib_major_version_filename(lib);
char *install_name = chaz_Util_join("", "-install_name $(CURDIR)",
dir_sep, major_v_name, NULL);
chaz_CFlags_append(local_flags, install_name);
@@ -4101,8 +4746,8 @@ chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
/* Add symlinks. */
if (strcmp(shlib_ext, ".dll") != 0) {
- char *major_v_name = chaz_SharedLib_major_version_filename(lib);
- char *no_v_name = chaz_SharedLib_no_version_filename(lib);
+ char *major_v_name = chaz_Lib_major_version_filename(lib);
+ char *no_v_name = chaz_Lib_no_version_filename(lib);
command = chaz_Util_join(" ", "ln -sf", filename, major_v_name, NULL);
chaz_MakeRule_add_command(rule, command);
@@ -4128,8 +4773,8 @@ chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
if (chaz_CC_msvc_version_num()) {
/* Remove import library and export file under MSVC. */
- char *lib_filename = chaz_SharedLib_implib_filename(lib);
- char *exp_filename = chaz_SharedLib_export_filename(lib);
+ char *lib_filename = chaz_Lib_implib_filename(lib);
+ char *exp_filename = chaz_Lib_export_filename(lib);
chaz_MakeRule_add_rm_command(makefile->clean, lib_filename);
chaz_MakeRule_add_rm_command(makefile->clean, exp_filename);
free(lib_filename);
@@ -4142,6 +4787,57 @@ chaz_MakeFile_add_shared_lib(chaz_MakeFile *makefile, chaz_SharedLib *lib,
}
chaz_MakeRule*
+chaz_MakeFile_add_static_lib(chaz_MakeFile *makefile, chaz_Lib *lib,
+ const char *objects) {
+ const char *shlib_ext = chaz_OS_shared_lib_ext();
+ chaz_MakeRule *rule;
+ char *filename;
+ char *command;
+
+ filename = chaz_Lib_filename(lib);
+ rule = chaz_MakeFile_add_rule(makefile, filename, objects);
+ command = chaz_CC_format_archiver_command(filename, objects);
+ chaz_MakeRule_add_command(rule, command);
+ free(command);
+ command = chaz_CC_format_ranlib_command(filename);
+ if (command) {
+ chaz_MakeRule_add_command(rule, command);
+ free(command);
+ }
+ chaz_MakeRule_add_rm_command(makefile->clean, filename);
+
+ /* Add symlinks. */
+ if (strcmp(shlib_ext, ".dll") != 0) {
+ char *major_v_name = chaz_Lib_major_version_filename(lib);
+ char *no_v_name = chaz_Lib_no_version_filename(lib);
+
+ command = chaz_Util_join(" ", "ln -sf", filename, major_v_name, NULL);
+ chaz_MakeRule_add_command(rule, command);
+ free(command);
+
+ if (strcmp(shlib_ext, ".dylib") == 0) {
+ command = chaz_Util_join(" ", "ln -sf", filename, no_v_name,
+ NULL);
+ }
+ else {
+ command = chaz_Util_join(" ", "ln -sf", major_v_name, no_v_name,
+ NULL);
+ }
+ chaz_MakeRule_add_command(rule, command);
+ free(command);
+
+ chaz_MakeRule_add_rm_command(makefile->clean, major_v_name);
+ chaz_MakeRule_add_rm_command(makefile->clean, no_v_name);
+
+ free(major_v_name);
+ free(no_v_name);
+ }
+
+ free(filename);
+ return rule;
+}
+
+chaz_MakeRule*
chaz_MakeFile_add_lemon_exe(chaz_MakeFile *makefile, const char *dir) {
chaz_CFlags *cflags = chaz_CC_new_cflags();
chaz_MakeRule *rule;
@@ -4186,6 +4882,47 @@ chaz_MakeFile_add_lemon_grammar(chaz_MakeFile *makefile,
}
void
+chaz_MakeFile_override_cflags(chaz_MakeFile *makefile, const char *obj,
+ chaz_CFlags *cflags) {
+ const char *obj_ext = chaz_CC_obj_ext();
+ const char *cflags_string = chaz_CFlags_get_string(cflags);
+ size_t obj_ext_len = strlen(obj_ext);
+ size_t obj_len = strlen(obj);
+ size_t base_len;
+ char *src;
+ char *command;
+ chaz_MakeRule *rule;
+
+ if (obj_len <= obj_ext_len) {
+ chaz_Util_die("Invalid object file: %s", obj);
+ }
+
+ base_len = obj_len - obj_ext_len;
+
+ if (strcmp(obj + base_len, obj_ext) != 0) {
+ chaz_Util_die("Invalid object file: %s", obj);
+ }
+
+ src = malloc(base_len + sizeof(".c"));
+ memcpy(src, obj, base_len);
+ memcpy(src + base_len, ".c", sizeof(".c"));
+
+ rule = chaz_MakeFile_add_rule(makefile, obj, src);
+ if (chaz_CC_msvc_version_num()) {
+ command = chaz_Util_join(" ", "$(CC) /nologo", cflags_string, "/c",
+ src, "/Fo$@", NULL);
+ }
+ else {
+ command = chaz_Util_join(" ", "$(CC)", cflags_string, "-c", src,
+ "-o $@", NULL);
+ }
+ chaz_MakeRule_add_command(rule, command);
+
+ free(command);
+ free(src);
+}
+
+void
chaz_MakeFile_write(chaz_MakeFile *makefile) {
FILE *out;
size_t i;
@@ -4329,6 +5066,45 @@ chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command) {
}
void
+chaz_MakeRule_add_command_with_libpath(chaz_MakeRule *rule,
+ const char *command, ...) {
+ va_list args;
+ char *path = NULL;
+ char *lib_command = NULL;
+
+ if (strcmp(chaz_OS_shared_lib_ext(), ".so") == 0) {
+ va_start(args, command);
+ path = chaz_Util_vjoin(":", args);
+ va_end(args);
+
+ lib_command = chaz_Util_join("", "LD_LIBRARY_PATH=", path,
+ ":$$LD_LIBRARY_PATH ", command, NULL);
+
+ free(path);
+ }
+ else if (strcmp(chaz_OS_shared_lib_ext(), ".dll") == 0) {
+ va_start(args, command);
+ path = chaz_Util_vjoin(";", args);
+ va_end(args);
+
+ /* It's important to not add a space before `&&`. Otherwise, the
+ * space is added to the search path.
+ */
+ lib_command = chaz_Util_join("", "path ", path, ";%path%&& ", command,
+ NULL);
+ }
+ else {
+ /* Assume that library paths are compiled into the executable on
+ * Darwin.
+ */
+ lib_command = chaz_Util_strdup(command);
+ }
+
+ chaz_MakeRule_add_command(rule, lib_command);
+ free(lib_command);
+}
+
+void
chaz_MakeRule_add_rm_command(chaz_MakeRule *rule, const char *files) {
char *command;
@@ -4511,10 +5287,11 @@ static struct {
char dev_null[20];
char dir_sep[2];
char exe_ext[5];
+ char static_lib_ext[5];
char shared_lib_ext[7];
char local_command_start[3];
int shell_type;
-} chaz_OS = { "", "", "", "", "", "", 0 };
+} chaz_OS = { "", "", "", "", "", "", "", 0 };
void
chaz_OS_init(void) {
@@ -4548,6 +5325,7 @@ chaz_OS_init(void) {
strcpy(chaz_OS.dev_null, "/dev/null");
strcpy(chaz_OS.dir_sep, "/");
strcpy(chaz_OS.exe_ext, "");
+ strcpy(chaz_OS.static_lib_ext, ".a");
if (memcmp(chaz_OS.name, "darwin", 6) == 0) {
strcpy(chaz_OS.shared_lib_ext, ".dylib");
}
@@ -4565,6 +5343,7 @@ chaz_OS_init(void) {
strcpy(chaz_OS.dir_sep, "\\");
strcpy(chaz_OS.exe_ext, ".exe");
strcpy(chaz_OS.shared_lib_ext, ".dll");
+ strcpy(chaz_OS.static_lib_ext, ".lib");
strcpy(chaz_OS.local_command_start, ".\\");
chaz_OS.shell_type = CHAZ_OS_CMD_EXE;
}
@@ -4600,6 +5379,11 @@ chaz_OS_shared_lib_ext(void) {
}
const char*
+chaz_OS_static_lib_ext(void) {
+ return chaz_OS.static_lib_ext;
+}
+
+const char*
chaz_OS_dev_null(void) {
return chaz_OS.dev_null;
}
@@ -4751,6 +5535,13 @@ chaz_OS_rmdir(const char *filepath) {
/* #include "Charmonizer/Core/Util.h" */
/* #include "Charmonizer/Core/OperatingSystem.h" */
+/* va_copy is not part of C89. Assume that simple assignment works if it
+ * isn't defined.
+ */
+#ifndef va_copy
+ #define va_copy(dst, src) ((dst) = (src))
+#endif
+
/* Global verbosity setting. */
int chaz_Util_verbosity = 1;
@@ -4850,6 +5641,18 @@ chaz_Util_strdup(const char *string) {
char*
chaz_Util_join(const char *sep, ...) {
va_list args;
+ char *result;
+
+ va_start(args, sep);
+ result = chaz_Util_vjoin(sep, args);
+ va_end(args);
+
+ return result;
+}
+
+char*
+chaz_Util_vjoin(const char *sep, va_list orig_args) {
+ va_list args;
const char *string;
char *result, *p;
size_t sep_len = strlen(sep);
@@ -4857,7 +5660,7 @@ chaz_Util_join(const char *sep, ...) {
int i;
/* Determine result size. */
- va_start(args, sep);
+ va_copy(args, orig_args);
size = 1;
string = va_arg(args, const char*);
for (i = 0; string; ++i) {
@@ -4870,7 +5673,7 @@ chaz_Util_join(const char *sep, ...) {
result = (char*)malloc(size);
/* Create result string. */
- va_start(args, sep);
+ va_copy(args, orig_args);
p = result;
string = va_arg(args, const char*);
for (i = 0; string; ++i) {
@@ -4958,99 +5761,82 @@ chaz_Util_can_open_file(const char *file_path) {
/* #include "Charmonizer/Core/ConfWriterPython.h" */
/* #include "Charmonizer/Core/ConfWriterRuby.h" */
/* #include "Charmonizer/Core/Util.h" */
+/* #include "Charmonizer/Core/CLI.h" */
/* #include "Charmonizer/Core/Compiler.h" */
/* #include "Charmonizer/Core/Make.h" */
/* #include "Charmonizer/Core/OperatingSystem.h" */
int
-chaz_Probe_parse_cli_args(int argc, const char *argv[],
- struct chaz_CLIArgs *args) {
+chaz_Probe_parse_cli_args(int argc, const char *argv[], chaz_CLI *cli) {
int i;
- int output_enabled = 0;
- /* Zero out args struct. */
- memset(args, 0, sizeof(struct chaz_CLIArgs));
+ /* Register Charmonizer-specific options. */
+ chaz_CLI_register(cli, "enable-c", "generate charmony.h", CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "enable-perl", "generate Charmony.pm", CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "enable-python", "generate charmony.py", CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "enable-ruby", "generate charmony.rb", CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "enable-makefile", NULL, CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "enable-coverage", NULL, CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "cc", "compiler command", CHAZ_CLI_ARG_REQUIRED);
+ chaz_CLI_register(cli, "cflags", NULL, CHAZ_CLI_ARG_OPTIONAL);
+ chaz_CLI_register(cli, "make", "make command", 0);
+
+ /* Parse options, exiting on failure. */
+ if (!chaz_CLI_parse(cli, argc, argv)) {
+ fprintf(stderr, "%s", chaz_CLI_help(cli));
+ exit(1);
+ }
- /* Parse most args. */
- for (i = 1; i < argc; i++) {
- const char *arg = argv[i];
- if (strcmp(arg, "--") == 0) {
- /* From here on out, everything will be a compiler flag. */
- i++;
- break;
- }
- if (strcmp(arg, "--enable-c") == 0) {
- args->charmony_h = 1;
- output_enabled = 1;
- }
- else if (strcmp(arg, "--enable-perl") == 0) {
- args->charmony_pm = 1;
- output_enabled = 1;
- }
- else if (strcmp(arg, "--enable-python") == 0) {
- args->charmony_py = 1;
- output_enabled = 1;
- }
- else if (strcmp(arg, "--enable-ruby") == 0) {
- args->charmony_rb = 1;
- output_enabled = 1;
- }
- else if (strcmp(arg, "--enable-makefile") == 0) {
- args->write_makefile = 1;
+ /* Accumulate compiler flags. */
+ {
+ char *cflags = chaz_Util_strdup("");
+ size_t cflags_len = 0;
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "--") == 0) {
+ i++;
+ break;
+ }
}
- else if (strcmp(arg, "--enable-coverage") == 0) {
- args->code_coverage = 1;
+ for (; i < argc; i++) {
+ const char *arg = argv[i];
+ cflags_len += strlen(arg) + 2;
+ cflags = (char*)realloc(cflags, cflags_len);
+ strcat(cflags, " ");
+ strcat(cflags, arg);
}
- else if (memcmp(arg, "--cc=", 5) == 0) {
- size_t len = strlen(arg);
- size_t l = 5;
- size_t r = len;
- size_t trimmed_len;
-
- if (len > CHAZ_PROBE_MAX_CC_LEN - 5) {
- fprintf(stderr, "Exceeded max length for compiler command");
- exit(1);
- }
+ chaz_CLI_set(cli, "cflags", cflags);
+ free(cflags);
+ }
- /*
- * Some Perl setups have a 'cc' config value with leading
- * whitespace.
- */
- while (isspace(arg[l])) {
- ++l;
- }
- while (r > l && isspace(arg[r-1])) {
- --r;
- }
+ /* Some Perl setups have a 'cc' config value with leading whitespace. */
+ if (chaz_CLI_defined(cli, "cc")) {
+ const char *arg = chaz_CLI_strval(cli, "cc");
+ char *cc;
+ size_t len = strlen(arg);
+ size_t l = 0;
+ size_t r = len;
+ size_t trimmed_len;
- trimmed_len = r - l;
- memcpy(args->cc, arg + l, trimmed_len);
- args->cc[trimmed_len] = '\0';
+ while (isspace(arg[l])) {
+ ++l;
}
- } /* preserve value of i */
-
- /* Accumulate compiler flags. */
- for (; i < argc; i++) {
- const char *arg = argv[i];
- size_t new_len = strlen(arg) + strlen(args->cflags) + 2;
- if (new_len >= CHAZ_PROBE_MAX_CFLAGS_LEN) {
- fprintf(stderr, "Exceeded max length for compiler flags");
- exit(1);
+ while (r > l && isspace(arg[r-1])) {
+ --r;
}
- strcat(args->cflags, " ");
- strcat(args->cflags, arg);
- }
- /* Process CHARM_VERBOSITY environment variable. */
- {
- const char *verbosity_env = getenv("CHARM_VERBOSITY");
- if (verbosity_env && strlen(verbosity_env)) {
- args->verbosity = strtol(verbosity_env, NULL, 10);
- }
+ trimmed_len = r - l;
+ cc = (char*)malloc(trimmed_len + 1);
+ memcpy(cc, arg + l, trimmed_len);
+ cc[trimmed_len] = '\0';
+ chaz_CLI_unset(cli, "cc");
+ chaz_CLI_set(cli, "cc", cc);
+ free(cc);
}
/* Validate. */
- if (!strlen(args->cc) || !output_enabled) {
+ if (!chaz_CLI_defined(cli, "cc")
+ || !strlen(chaz_CLI_strval(cli, "cc"))
+ ) {
return false;
}
@@ -5066,7 +5852,7 @@ chaz_Probe_die_usage(void) {
}
void
-chaz_Probe_init(struct chaz_CLIArgs *args) {
+chaz_Probe_init(struct chaz_CLI *cli) {
int output_enabled = 0;
{
@@ -5079,25 +5865,25 @@ chaz_Probe_init(struct chaz_CLIArgs *args) {
/* Dispatch other initializers. */
chaz_OS_init();
- chaz_CC_init(args->cc, args->cflags);
+ chaz_CC_init(chaz_CLI_strval(cli, "cc"), chaz_CLI_strval(cli, "cflags"));
chaz_ConfWriter_init();
chaz_HeadCheck_init();
- chaz_Make_init();
+ chaz_Make_init(chaz_CLI_strval(cli, "make"));
/* Enable output. */
- if (args->charmony_h) {
+ if (chaz_CLI_defined(cli, "enable-c")) {
chaz_ConfWriterC_enable();
output_enabled = true;
}
- if (args->charmony_pm) {
+ if (chaz_CLI_defined(cli, "enable-perl")) {
chaz_ConfWriterPerl_enable();
output_enabled = true;
}
- if (args->charmony_py) {
+ if (chaz_CLI_defined(cli, "enable-python")) {
chaz_ConfWriterPython_enable();
output_enabled = true;
}
- if (args->charmony_rb) {
+ if (chaz_CLI_defined(cli, "enable-ruby")) {
chaz_ConfWriterRuby_enable();
output_enabled = true;
}
@@ -5361,7 +6147,6 @@ chaz_DirManip_try_rmdir(void) {
void
chaz_DirManip_run(void) {
const char *dir_sep = chaz_OS_dir_sep();
- int remove_zaps_dirs = false;
int has_dirent_h = chaz_HeadCheck_check_header("dirent.h");
int has_direct_h = chaz_HeadCheck_check_header("direct.h");
int has_dirent_d_namlen = false;
@@ -5433,7 +6218,6 @@ chaz_DirManip_run(void) {
/* See whether remove works on directories. */
chaz_OS_mkdir("_charm_test_remove_me");
if (0 == remove("_charm_test_remove_me")) {
- remove_zaps_dirs = true;
chaz_ConfWriter_add_def("REMOVE_ZAPS_DIRS", NULL);
}
chaz_OS_rmdir("_charm_test_remove_me");
@@ -5839,7 +6623,9 @@ chaz_Headers_probe_posix(void) {
"grp.h",
"pwd.h",
"regex.h",
+ "sched.h",
"sys/stat.h",
+ "sys/time.h",
"sys/times.h",
"sys/types.h",
"sys/utsname.h",
@@ -5975,7 +6761,6 @@ chaz_Integers_run(void) {
int has___int64 = false;
int has_inttypes = chaz_HeadCheck_check_header("inttypes.h");
int has_stdint = chaz_HeadCheck_check_header("stdint.h");
- int can_convert_u64_to_double = true;
char i32_t_type[10];
char i32_t_postfix[10];
char u32_t_postfix[10];
@@ -6723,13 +7508,8 @@ chaz_Memory_probe_alloca(void) {
CHAZ_QUOTE( void *foo = %s(1); )
CHAZ_QUOTE( return 0; )
CHAZ_QUOTE( } );
- int has_sys_mman_h = false;
- int has_alloca_h = false;
- int has_malloc_h = false;
- int need_stdlib_h = false;
int has_alloca = false;
int has_builtin_alloca = false;
- int has_underscore_alloca = false;
char code_buf[sizeof(alloca_code) + 100];
{
@@ -6742,16 +7522,14 @@ chaz_Memory_probe_alloca(void) {
NULL
};
if (chaz_HeadCheck_check_many_headers((const char**)mman_headers)) {
- has_sys_mman_h = true;
chaz_ConfWriter_add_def("HAS_SYS_MMAN_H", NULL);
}
}
/* Unixen. */
sprintf(code_buf, alloca_code, "alloca.h", "alloca");
- if (chaz_CC_test_compile(code_buf)) {
- has_alloca_h = true;
- has_alloca = true;
+ if (chaz_CC_test_link(code_buf)) {
+ has_alloca = true;
chaz_ConfWriter_add_def("HAS_ALLOCA_H", NULL);
chaz_ConfWriter_add_def("alloca", "alloca");
}
@@ -6762,9 +7540,8 @@ chaz_Memory_probe_alloca(void) {
* are subsequently repeated during the build.
*/
sprintf(code_buf, alloca_code, "stdlib.h", "alloca");
- if (chaz_CC_test_compile(code_buf)) {
- has_alloca = true;
- need_stdlib_h = true;
+ if (chaz_CC_test_link(code_buf)) {
+ has_alloca = true;
chaz_ConfWriter_add_def("ALLOCA_IN_STDLIB_H", NULL);
chaz_ConfWriter_add_def("alloca", "alloca");
}
@@ -6772,7 +7549,7 @@ chaz_Memory_probe_alloca(void) {
if (!has_alloca) {
sprintf(code_buf, alloca_code, "stdio.h", /* stdio.h is filler */
"__builtin_alloca");
- if (chaz_CC_test_compile(code_buf)) {
+ if (chaz_CC_test_link(code_buf)) {
has_builtin_alloca = true;
chaz_ConfWriter_add_def("alloca", "__builtin_alloca");
}
@@ -6781,20 +7558,17 @@ chaz_Memory_probe_alloca(void) {
/* Windows. */
if (!(has_alloca || has_builtin_alloca)) {
sprintf(code_buf, alloca_code, "malloc.h", "alloca");
- if (chaz_CC_test_compile(code_buf)) {
- has_malloc_h = true;
- has_alloca = true;
+ if (chaz_CC_test_link(code_buf)) {
+ has_alloca = true;
chaz_ConfWriter_add_def("HAS_MALLOC_H", NULL);
chaz_ConfWriter_add_def("alloca", "alloca");
}
}
if (!(has_alloca || has_builtin_alloca)) {
sprintf(code_buf, alloca_code, "malloc.h", "_alloca");
- if (chaz_CC_test_compile(code_buf)) {
- has_malloc_h = true;
- has_underscore_alloca = true;
+ if (chaz_CC_test_link(code_buf)) {
chaz_ConfWriter_add_def("HAS_MALLOC_H", NULL);
- chaz_ConfWriter_add_def("chy_alloca", "_alloca");
+ chaz_ConfWriter_add_def("alloca", "_alloca");
}
}
}
@@ -7078,9 +7852,7 @@ void
chaz_VariadicMacros_run(void) {
char *output;
size_t output_len;
- int has_varmacros = false;
- int has_iso_varmacros = false;
- int has_gnuc_varmacros = false;
+ int has_varmacros = false;
chaz_ConfWriter_start_module("VariadicMacros");
@@ -7088,7 +7860,6 @@ chaz_VariadicMacros_run(void) {
output = chaz_CC_capture_output(chaz_VariadicMacros_iso_code, &output_len);
if (output != NULL) {
has_varmacros = true;
- has_iso_varmacros = true;
chaz_ConfWriter_add_def("HAS_VARIADIC_MACROS", NULL);
chaz_ConfWriter_add_def("HAS_ISO_VARIADIC_MACROS", NULL);
free(output);
@@ -7097,7 +7868,6 @@ chaz_VariadicMacros_run(void) {
/* Test for GNU-style variadic macros. */
output = chaz_CC_capture_output(chaz_VariadicMacros_gnuc_code, &output_len);
if (output != NULL) {
- has_gnuc_varmacros = true;
if (has_varmacros == false) {
has_varmacros = true;
chaz_ConfWriter_add_def("HAS_VARIADIC_MACROS", NULL);
@@ -7164,7 +7934,7 @@ static const char lucy_version[] = "0.4.2";
static const char lucy_major_version[] = "0.4";
static void
-S_add_compiler_flags(struct chaz_CLIArgs *args) {
+S_add_compiler_flags(struct chaz_CLI *cli) {
chaz_CFlags *extra_cflags = chaz_CC_get_extra_cflags();
if (chaz_Probe_gcc_version_num()) {
@@ -7175,7 +7945,7 @@ S_add_compiler_flags(struct chaz_CLIArgs *args) {
else if (getenv("LUCY_DEBUG")) {
chaz_CFlags_append(extra_cflags,
"-DLUCY_DEBUG -pedantic -Wall -Wextra -Wno-variadic-macros");
- if (args->charmony_pm) {
+ if (chaz_CLI_defined(cli, "enable-perl")) {
chaz_CFlags_append(extra_cflags, "-DPERL_GCC_PEDANTIC");
}
}
@@ -7251,8 +8021,7 @@ S_cfh_file_callback(const char *dir, char *file, void *context) {
}
static void
-S_write_makefile(struct chaz_CLIArgs *chaz_args,
- struct lucy_CLIArgs *lucy_args) {
+S_write_makefile(struct chaz_CLI *cli) {
SourceFileContext sfc;
const char *base_dir = "..";
@@ -7260,7 +8029,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
const char *exe_ext = chaz_OS_exe_ext();
const char *obj_ext = chaz_CC_obj_ext();
const char *math_lib = chaz_Floats_math_library();
- const char *cfish_prefix = lucy_args->clownfish_prefix;
+ const char *cfish_prefix = chaz_CLI_strval(cli, "clownfish-prefix");
char *core_dir = chaz_Util_join(dir_sep, base_dir, "core", NULL);
char *lemon_dir = chaz_Util_join(dir_sep, base_dir, "lemon", NULL);
@@ -7295,7 +8064,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_CFlags *link_flags;
chaz_CFlags *test_cflags;
- chaz_SharedLib *lib;
+ chaz_Lib *lib;
const char *cfish_lib_name = NULL;
char *cfish_lib_dir = NULL;
@@ -7321,7 +8090,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_CFlags_enable_debugging(makefile_cflags);
chaz_CFlags_disable_strict_aliasing(makefile_cflags);
chaz_CFlags_compile_shared_library(makefile_cflags);
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
chaz_CFlags_enable_code_coverage(makefile_cflags);
}
@@ -7372,8 +8141,9 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
/* Rules */
- lib = chaz_SharedLib_new("lucy", lucy_version, lucy_major_version);
- lib_filename = chaz_SharedLib_filename(lib);
+ lib = chaz_Lib_new("lucy", chaz_Lib_SHARED, lucy_version,
+ lucy_major_version);
+ lib_filename = chaz_Lib_filename(lib);
chaz_MakeFile_add_rule(makefile, "all", lib_filename);
chaz_MakeFile_add_lemon_exe(makefile, lemon_dir);
@@ -7437,7 +8207,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
if (chaz_HeadCheck_check_header("pcre.h")) {
chaz_CFlags_add_external_library(link_flags, "pcre");
}
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
chaz_CFlags_enable_code_coverage(link_flags);
}
rule = chaz_MakeFile_add_shared_lib(makefile, lib, "$(LUCY_OBJS)",
@@ -7477,7 +8247,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
}
chaz_MakeRule_add_command(rule, test_command);
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
rule = chaz_MakeFile_add_rule(makefile, "coverage", test_lucy_exe);
chaz_MakeRule_add_command(rule,
"lcov"
@@ -7517,7 +8287,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_MakeRule_add_recursive_rm_command(clean_rule, "autogen");
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
chaz_MakeRule_add_rm_command(clean_rule, "lucy.info");
chaz_MakeRule_add_recursive_rm_command(clean_rule, "coverage");
}
@@ -7527,7 +8297,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_MakeFile_write(makefile);
chaz_MakeFile_destroy(makefile);
- chaz_SharedLib_destroy(lib);
+ chaz_Lib_destroy(lib);
free(core_dir);
free(lemon_dir);
free(modules_dir);
@@ -7547,30 +8317,19 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
int main(int argc, const char **argv) {
/* Initialize. */
- struct chaz_CLIArgs chaz_args;
- struct lucy_CLIArgs lucy_args = { NULL };
- {
- int result = chaz_Probe_parse_cli_args(argc, argv, &chaz_args);
- if (!result) {
- chaz_Probe_die_usage();
- }
- chaz_Probe_init(&chaz_args);
- S_add_compiler_flags(&chaz_args);
- }
- {
- int i;
- for (i = 0; i < argc; i++) {
- const char *arg = argv[i];
- if (strncmp(arg, "--disable-threads", 17) == 0) {
- chaz_CFlags *extra_cflags = chaz_CC_get_extra_cflags();
- chaz_CFlags_append(extra_cflags, "-DCFISH_NOTHREADS");
- break;
- }
- else if (memcmp(arg, "--clownfish-prefix=", 19) == 0) {
- lucy_args.clownfish_prefix = arg + 19;
- }
- }
- }
+ chaz_CLI *cli
+ = chaz_CLI_new(argv[0], "charmonizer: Probe C build environment");
+ chaz_CLI_register(cli, "disable-threads", "whether to disable threads",
+ CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "clownfish-prefix",
+ "prefix of Clownfish installation",
+ CHAZ_CLI_ARG_OPTIONAL);
+ chaz_CLI_set_usage(cli, "Usage: charmonizer [OPTIONS] [-- [CFLAGS]]");
+ if (!chaz_Probe_parse_cli_args(argc, argv, cli)) {
+ chaz_Probe_die_usage();
+ }
+ chaz_Probe_init(cli);
+ S_add_compiler_flags(cli);
/* Employ integer features but don't define stdint types in charmony.h. */
chaz_ConfWriter_append_conf(
@@ -7618,11 +8377,12 @@ int main(int argc, const char **argv) {
"#endif\n\n"
);
- if (chaz_args.write_makefile) {
- S_write_makefile(&chaz_args, &lucy_args);
+ if (chaz_CLI_defined(cli, "enable-makefile")) {
+ S_write_makefile(cli);
}
/* Clean up. */
+ chaz_CLI_destroy(cli);
chaz_Probe_clean_up();
return 0;
http://git-wip-us.apache.org/repos/asf/lucy/blob/8572510d/common/charmonizer.main
----------------------------------------------------------------------
diff --git a/common/charmonizer.main b/common/charmonizer.main
index 118713f..66644d9 100644
--- a/common/charmonizer.main
+++ b/common/charmonizer.main
@@ -49,7 +49,7 @@ static const char lucy_version[] = "0.4.2";
static const char lucy_major_version[] = "0.4";
static void
-S_add_compiler_flags(struct chaz_CLIArgs *args) {
+S_add_compiler_flags(struct chaz_CLI *cli) {
chaz_CFlags *extra_cflags = chaz_CC_get_extra_cflags();
if (chaz_Probe_gcc_version_num()) {
@@ -60,7 +60,7 @@ S_add_compiler_flags(struct chaz_CLIArgs *args) {
else if (getenv("LUCY_DEBUG")) {
chaz_CFlags_append(extra_cflags,
"-DLUCY_DEBUG -pedantic -Wall -Wextra -Wno-variadic-macros");
- if (args->charmony_pm) {
+ if (chaz_CLI_defined(cli, "enable-perl")) {
chaz_CFlags_append(extra_cflags, "-DPERL_GCC_PEDANTIC");
}
}
@@ -136,8 +136,7 @@ S_cfh_file_callback(const char *dir, char *file, void *context) {
}
static void
-S_write_makefile(struct chaz_CLIArgs *chaz_args,
- struct lucy_CLIArgs *lucy_args) {
+S_write_makefile(struct chaz_CLI *cli) {
SourceFileContext sfc;
const char *base_dir = "..";
@@ -145,7 +144,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
const char *exe_ext = chaz_OS_exe_ext();
const char *obj_ext = chaz_CC_obj_ext();
const char *math_lib = chaz_Floats_math_library();
- const char *cfish_prefix = lucy_args->clownfish_prefix;
+ const char *cfish_prefix = chaz_CLI_strval(cli, "clownfish-prefix");
char *core_dir = chaz_Util_join(dir_sep, base_dir, "core", NULL);
char *lemon_dir = chaz_Util_join(dir_sep, base_dir, "lemon", NULL);
@@ -180,7 +179,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_CFlags *link_flags;
chaz_CFlags *test_cflags;
- chaz_SharedLib *lib;
+ chaz_Lib *lib;
const char *cfish_lib_name = NULL;
char *cfish_lib_dir = NULL;
@@ -206,7 +205,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_CFlags_enable_debugging(makefile_cflags);
chaz_CFlags_disable_strict_aliasing(makefile_cflags);
chaz_CFlags_compile_shared_library(makefile_cflags);
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
chaz_CFlags_enable_code_coverage(makefile_cflags);
}
@@ -257,8 +256,9 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
/* Rules */
- lib = chaz_SharedLib_new("lucy", lucy_version, lucy_major_version);
- lib_filename = chaz_SharedLib_filename(lib);
+ lib = chaz_Lib_new("lucy", chaz_Lib_SHARED, lucy_version,
+ lucy_major_version);
+ lib_filename = chaz_Lib_filename(lib);
chaz_MakeFile_add_rule(makefile, "all", lib_filename);
chaz_MakeFile_add_lemon_exe(makefile, lemon_dir);
@@ -322,7 +322,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
if (chaz_HeadCheck_check_header("pcre.h")) {
chaz_CFlags_add_external_library(link_flags, "pcre");
}
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
chaz_CFlags_enable_code_coverage(link_flags);
}
rule = chaz_MakeFile_add_shared_lib(makefile, lib, "$(LUCY_OBJS)",
@@ -362,7 +362,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
}
chaz_MakeRule_add_command(rule, test_command);
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
rule = chaz_MakeFile_add_rule(makefile, "coverage", test_lucy_exe);
chaz_MakeRule_add_command(rule,
"lcov"
@@ -402,7 +402,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_MakeRule_add_recursive_rm_command(clean_rule, "autogen");
- if (chaz_args->code_coverage) {
+ if (chaz_CLI_defined(cli, "enable-coverage")) {
chaz_MakeRule_add_rm_command(clean_rule, "lucy.info");
chaz_MakeRule_add_recursive_rm_command(clean_rule, "coverage");
}
@@ -412,7 +412,7 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
chaz_MakeFile_write(makefile);
chaz_MakeFile_destroy(makefile);
- chaz_SharedLib_destroy(lib);
+ chaz_Lib_destroy(lib);
free(core_dir);
free(lemon_dir);
free(modules_dir);
@@ -432,30 +432,19 @@ S_write_makefile(struct chaz_CLIArgs *chaz_args,
int main(int argc, const char **argv) {
/* Initialize. */
- struct chaz_CLIArgs chaz_args;
- struct lucy_CLIArgs lucy_args = { NULL };
- {
- int result = chaz_Probe_parse_cli_args(argc, argv, &chaz_args);
- if (!result) {
- chaz_Probe_die_usage();
- }
- chaz_Probe_init(&chaz_args);
- S_add_compiler_flags(&chaz_args);
- }
- {
- int i;
- for (i = 0; i < argc; i++) {
- const char *arg = argv[i];
- if (strncmp(arg, "--disable-threads", 17) == 0) {
- chaz_CFlags *extra_cflags = chaz_CC_get_extra_cflags();
- chaz_CFlags_append(extra_cflags, "-DCFISH_NOTHREADS");
- break;
- }
- else if (memcmp(arg, "--clownfish-prefix=", 19) == 0) {
- lucy_args.clownfish_prefix = arg + 19;
- }
- }
+ chaz_CLI *cli
+ = chaz_CLI_new(argv[0], "charmonizer: Probe C build environment");
+ chaz_CLI_register(cli, "disable-threads", "whether to disable threads",
+ CHAZ_CLI_NO_ARG);
+ chaz_CLI_register(cli, "clownfish-prefix",
+ "prefix of Clownfish installation",
+ CHAZ_CLI_ARG_OPTIONAL);
+ chaz_CLI_set_usage(cli, "Usage: charmonizer [OPTIONS] [-- [CFLAGS]]");
+ if (!chaz_Probe_parse_cli_args(argc, argv, cli)) {
+ chaz_Probe_die_usage();
}
+ chaz_Probe_init(cli);
+ S_add_compiler_flags(cli);
/* Employ integer features but don't define stdint types in charmony.h. */
chaz_ConfWriter_append_conf(
@@ -503,11 +492,12 @@ int main(int argc, const char **argv) {
"#endif\n\n"
);
- if (chaz_args.write_makefile) {
- S_write_makefile(&chaz_args, &lucy_args);
+ if (chaz_CLI_defined(cli, "enable-makefile")) {
+ S_write_makefile(cli);
}
/* Clean up. */
+ chaz_CLI_destroy(cli);
chaz_Probe_clean_up();
return 0;
[2/4] lucy git commit: Backport CI setup to 0.4 branch
Posted by nw...@apache.org.
Backport CI setup to 0.4 branch
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/0fdd4e39
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/0fdd4e39
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/0fdd4e39
Branch: refs/heads/0.4
Commit: 0fdd4e39d57c1bc7a2005be8f345a67958f75d07
Parents: 1aecf7a
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Jul 24 21:00:13 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Jul 24 21:52:11 2015 +0200
----------------------------------------------------------------------
.travis.yml | 25 +++++++++------
appveyor.yml | 17 ++++++++++
devel/bin/appveyor-build.bat | 41 ++++++++++++++++++++++++
devel/bin/travis-test.sh | 66 +++++++++++++++++++++++++++++++++++++++
4 files changed, 139 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/0fdd4e39/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index e746958..4e6c245 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,14 +14,19 @@
# limitations under the License.
language: perl
-perl:
- - "5.19"
- - "5.18"
- - "5.16"
- - "5.14"
- - "5.12"
- - "5.10"
- - "5.8"
-before_install:
- - cd perl
+sudo: required
+# Override Travis' default Perl installation script.
+install: 'true'
+script: devel/bin/travis-test.sh
+env:
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=c
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.20
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.18
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.16
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.14
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.12
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.10
+ - LUCY_DEBUG=1 CLOWNFISH_HOST=perl PERL_VERSION=5.8
+git:
+ depth: 10
http://git-wip-us.apache.org/repos/asf/lucy/blob/0fdd4e39/appveyor.yml
----------------------------------------------------------------------
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..c153317
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,17 @@
+environment:
+ global:
+ LUCY_DEBUG: 1
+ matrix:
+ - CLOWNFISH_HOST: c
+ MSVC_VERSION: 10
+ - CLOWNFISH_HOST: c
+ MSVC_VERSION: 12
+# - CLOWNFISH_HOST: perl
+
+build: off
+
+test_script:
+ - 'devel\bin\appveyor-build.bat'
+
+clone_depth: 10
+
http://git-wip-us.apache.org/repos/asf/lucy/blob/0fdd4e39/devel/bin/appveyor-build.bat
----------------------------------------------------------------------
diff --git a/devel/bin/appveyor-build.bat b/devel/bin/appveyor-build.bat
new file mode 100644
index 0000000..c0d7f5f
--- /dev/null
+++ b/devel/bin/appveyor-build.bat
@@ -0,0 +1,41 @@
+@echo off
+
+if "%CLOWNFISH_HOST%" == "c" goto test_c
+if "%CLOWNFISH_HOST%" == "perl" goto test_perl
+
+echo unknown CLOWNFISH_HOST: %CLOWNFISH_HOST%
+exit /b 1
+
+:test_c
+
+if "%MSVC_VERSION%" == "10" goto msvc_10
+
+call "C:\Program Files (x86)\Microsoft Visual Studio %MSVC_VERSION%.0\VC\vcvarsall.bat" amd64
+goto msvc_build
+
+:msvc_10
+call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64
+
+:msvc_build
+
+rem Install Clownfish.
+cd \projects
+git clone -q -b 0.4 --depth 1 https://git-wip-us.apache.org/repos/asf/lucy-clownfish.git
+cd lucy-clownfish\runtime\c
+call configure && nmake || exit /b
+call install --prefix C:\install
+
+cd \projects\lucy\c
+call configure --clownfish-prefix=C:\install && nmake && nmake test
+
+exit /b
+
+:test_perl
+
+perl -V
+
+cd perl
+perl Build.PL && call Build && call Build test
+
+exit /b
+
http://git-wip-us.apache.org/repos/asf/lucy/blob/0fdd4e39/devel/bin/travis-test.sh
----------------------------------------------------------------------
diff --git a/devel/bin/travis-test.sh b/devel/bin/travis-test.sh
new file mode 100755
index 0000000..65d0b2d
--- /dev/null
+++ b/devel/bin/travis-test.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Exit if any command returns non-zero.
+set -e
+
+# Print all commands before executing.
+set -x
+
+test_c() {
+ # Install Clownfish.
+ git clone -q -b 0.4 --depth 1 https://git-wip-us.apache.org/repos/asf/lucy-clownfish.git
+ cd lucy-clownfish/runtime/c
+ ./configure
+ make -j
+ sudo ./install.sh --prefix /usr/local
+ sudo ldconfig
+
+ cd ../../../c
+ ./configure
+ make -j test
+}
+
+test_perl() {
+ perlbrew switch $PERL_VERSION
+
+ # Install Clownfish.
+ git clone -q -b 0.4 --depth 1 https://git-wip-us.apache.org/repos/asf/lucy-clownfish.git
+ cd lucy-clownfish/runtime/perl
+ perl Build.PL
+ ./Build
+ sudo ./Build install
+ cd ../../compiler/perl
+ sudo ./Build install
+
+ cd ../../../perl
+ perl Build.PL
+ ./Build test
+}
+
+case $CLOWNFISH_HOST in
+ perl)
+ test_perl
+ ;;
+ c)
+ test_c
+ ;;
+ *)
+ echo "unknown CLOWNFISH_HOST: $CLOWNFISH_HOST"
+ exit 1
+esac
+