From e169fbe3bdb946dcec42d920af916ef49e91068e Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Sat, 4 Jun 2016 20:04:14 +0200 Subject: [PATCH] Perl build with make Let Charmonizer create a Makefile for the Perl bindings that builds the core object files. The list of object files is passed in a Charmonizer variable named `CORE_OBJECTS`. Make options can be passed by running perl Build.PL --charmonizer_params make_options= Module::Build options can also be specified in ~/.modulebuildrc, so an easy way to always launch parallel builds is to add a line like Build_PL --charmonizer_params make_options=-j5 --- compiler/perl/lib/Clownfish/CFC/Perl/Build.pm | 14 ++- .../lib/Clownfish/CFC/Perl/Build/Charmonic.pm | 58 +++++++-- runtime/common/charmonizer.c | 115 ++++++++++-------- runtime/common/charmonizer.main | 115 ++++++++++-------- runtime/perl/.gitignore | 1 + runtime/perl/buildlib/Clownfish/Build.pm | 4 +- 6 files changed, 184 insertions(+), 123 deletions(-) diff --git a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm index 8e7689b9..7c522e7f 100644 --- a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm +++ b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm @@ -368,13 +368,21 @@ sub ACTION_compile_custom_xs { mkpath( $archdir, 0, 0777 ) unless -d $archdir; my @objects; + # Make core objects. + if ($self->can('cf_make_core_objects')) { + my $core_objects = $self->cf_make_core_objects(); + push @objects, @$core_objects; + $self->add_to_cleanup(@$core_objects); + } + # Compile C source files. my $c_files = []; - my $source_dirs = $self->clownfish_params('source'); - my $autogen_src_dir = catdir( $AUTOGEN_DIR, 'source' ); - for my $source_dir ( @$source_dirs, $autogen_src_dir ) { + my $source_dirs = $self->clownfish_params('c_source'); + for my $source_dir (@$source_dirs) { push @$c_files, @{ $self->rscan_dir( $source_dir, qr/\.c$/ ) }; } + my $autogen_src_dir = catdir( $AUTOGEN_DIR, 'source' ); + push @$c_files, @{ $self->rscan_dir( $autogen_src_dir, qr/_perl\.c$/ ) }; my $extra_cflags = $self->clownfish_params('cflags'); for my $c_file (@$c_files) { my $o_file = $c_file; diff --git a/compiler/perl/lib/Clownfish/CFC/Perl/Build/Charmonic.pm b/compiler/perl/lib/Clownfish/CFC/Perl/Build/Charmonic.pm index 045d98a9..03b48f50 100644 --- a/compiler/perl/lib/Clownfish/CFC/Perl/Build/Charmonic.pm +++ b/compiler/perl/lib/Clownfish/CFC/Perl/Build/Charmonic.pm @@ -31,6 +31,8 @@ use File::Spec::Functions qw( catfile curdir ); # Add a custom Module::Build hashref property to pass the following build # parameters. # charmonizer_c: Charmonizer C file, required +# create_makefile: Whether to create a Makefile. +# make_options: Options passed to make. if ( $Module::Build::VERSION <= 0.30 ) { __PACKAGE__->add_property( charmonizer_params => {} ); } @@ -49,19 +51,29 @@ my $CHARMONY_PM_PATH = 'Charmony.pm'; # Charmony.pm files. sub ACTION_charmony { my $self = shift; - my $charmonizer_c = $self->charmonizer_params('charmonizer_c'); + + my ($cc, @cc_args) = $self->split_like_shell($self->config('cc')); + my $is_msvc = lc($cc) =~ /^cl\b/; + my $charmonizer_c = $self->charmonizer_params('charmonizer_c'); + my $create_makefile = $self->charmonizer_params('create_makefile'); + $self->add_to_cleanup($CHARMONIZER_EXE_PATH); if ( !$self->up_to_date( $charmonizer_c, $CHARMONIZER_EXE_PATH ) ) { print "\nCompiling $CHARMONIZER_EXE_PATH...\n\n"; - my $cc = $self->config('cc'); - my $outflag = $cc =~ /cl\b/ ? "/Fe" : "-o "; - system("$cc $charmonizer_c $outflag$CHARMONIZER_EXE_PATH") + my @command = ($cc, @cc_args, $charmonizer_c); + if ($is_msvc) { + push @command, "/Fe$CHARMONIZER_EXE_PATH"; + } + else { + push @command, '-o', $CHARMONIZER_EXE_PATH; + } + system @command and die "Failed to compile $CHARMONIZER_EXE_PATH"; } - return if $self->up_to_date( $CHARMONIZER_EXE_PATH, [ - $CHARMONY_H_PATH, $CHARMONY_PM_PATH, - ] ); + my @derived_files = ( $CHARMONY_H_PATH, $CHARMONY_PM_PATH ); + push @derived_files, 'Makefile' if $create_makefile; + return if $self->up_to_date( $CHARMONIZER_EXE_PATH, \@derived_files ); print "\nRunning $CHARMONIZER_EXE_PATH...\n\n"; $self->add_to_cleanup($CHARMONY_H_PATH); @@ -69,13 +81,11 @@ sub ACTION_charmony { # Clean up after charmonizer if it doesn't succeed on its own. $self->add_to_cleanup("_charm*"); - if ($Config{cc} =~ /^cl\b/) { + if ($is_msvc) { $self->add_to_cleanup('charmonizer.obj'); } # Prepare arguments to charmonizer. - my @cc_args = $self->split_like_shell($self->config('cc')); - my $cc = shift(@cc_args); my @command = ( $CHARMONIZER_EXE_PATH, "--cc=$cc", @@ -83,10 +93,19 @@ sub ACTION_charmony { '--enable-c', '--enable-perl', ); + if ($create_makefile) { + push @command, + '--make=' . $self->config('make'), + '--enable-makefile'; + $self->add_to_cleanup('Makefile'); + } if ( !$self->config('usethreads') ) { push @command, '--disable-threads'; } - push @command, ( '--', @cc_args, $self->config('ccflags') ); + push @command, ( + '--', @cc_args, $self->config('ccflags'), + '-I' . File::Spec->catdir($self->config('archlibexp'), 'CORE'), + ); if ( $ENV{CHARM_VALGRIND} ) { unshift @command, "valgrind", "--leak-check=yes"; } @@ -121,6 +140,23 @@ sub charmony { return; } +sub cf_make_core_objects { + my $self = shift; + + return [] unless $self->charmonizer_params('create_makefile'); + + my $make_options = $self->charmonizer_params('make_options'); + my @command = ( + $self->config('make'), + $self->split_like_shell($make_options), + 'core_objects', + ); + print join(' ', @command), "\n"; + system @command and die($self->config('make') . " failed"); + + return [ split( /\s+/, $self->charmony('CORE_OBJECTS') ) ]; +} + 1; __END__ diff --git a/runtime/common/charmonizer.c b/runtime/common/charmonizer.c index c6e1e1e7..62355e86 100644 --- a/runtime/common/charmonizer.c +++ b/runtime/common/charmonizer.c @@ -8323,6 +8323,8 @@ chaz_VariadicMacros_run(void) { typedef struct cfish_MakeFile { chaz_MakeFile *makefile; + chaz_MakeVar *obj_var; + chaz_MakeVar *cfh_var; chaz_CLI *cli; /* Directories and files. */ @@ -8332,7 +8334,7 @@ typedef struct cfish_MakeFile { char *autogen_src_dir; char *autogen_inc_dir; char *autogen_target; - const char **autogen_src_files; + char *core_objects; /* Libraries. */ chaz_Lib *shared_lib; @@ -8341,10 +8343,6 @@ typedef struct cfish_MakeFile { char *static_lib_filename; } cfish_MakeFile; -typedef struct SourceFileContext { - chaz_MakeVar *var; -} SourceFileContext; - static const char cfish_version[] = "0.5.0"; static const char cfish_major_version[] = "0.5"; @@ -8372,6 +8370,9 @@ cfish_MakeFile_write_c_test_rules(cfish_MakeFile *self); static void S_c_file_callback(const char *dir, char *file, void *context); +static void +S_add_core_object(cfish_MakeFile *self, const char *obj_file); + static void S_cfh_file_callback(const char *dir, char *file, void *context); @@ -8468,6 +8469,7 @@ int main(int argc, const char **argv) { mf->shared_lib_filename); chaz_ConfWriter_add_def("STATIC_LIB_FILENAME", mf->static_lib_filename); + chaz_ConfWriter_add_def("CORE_OBJECTS", mf->core_objects); cfish_MakeFile_destroy(mf); } @@ -8552,6 +8554,9 @@ cfish_MakeFile_new(chaz_CLI *cli) { cfish_MakeFile *self = malloc(sizeof(cfish_MakeFile)); self->makefile = chaz_MakeFile_new(); + self->obj_var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_OBJS", + NULL); + self->cfh_var = NULL; self->cli = cli; self->base_dir = ".."; @@ -8563,42 +8568,18 @@ cfish_MakeFile_new(chaz_CLI *cli) { = chaz_Util_join(dir_sep, "autogen", "hierarchy.json", NULL); if (strcmp(chaz_CLI_strval(cli, "host"), "go") == 0) { - static const char *go_autogen_src_files[] = { - "cfish_parcel", - "testcfish_parcel", - NULL - }; + /* TODO: Let Go bindings build code in "ext". */ self->host_src_dir = "ext"; - self->autogen_src_files = go_autogen_src_files; } else if (chaz_CLI_defined(cli, "enable-python")) { - static const char *python_autogen_src_files[] = { - "cfish_parcel", - "testcfish_parcel", - NULL - }; + /* TODO: Let Python bindings build code in "cfext". */ self->host_src_dir = "cfext"; - self->autogen_src_files = python_autogen_src_files; - } - else if (chaz_CLI_defined(cli, "enable-perl")) { - static const char *perl_autogen_src_files[] = { - "cfish_parcel", - "cfish_perl", - "testcfish_parcel", - "testcfish_perl", - NULL - }; - self->host_src_dir = "xs"; - self->autogen_src_files = perl_autogen_src_files; } - else { - static const char *c_autogen_src_files[] = { - "cfish_parcel", - "testcfish_parcel", - NULL - }; + else if (strcmp(chaz_CLI_strval(cli, "host"), "c") == 0) { self->host_src_dir = "src"; - self->autogen_src_files = c_autogen_src_files; + } + else { + self->host_src_dir = NULL; } self->shared_lib = chaz_Lib_new_shared("cfish", cfish_version, @@ -8606,6 +8587,7 @@ cfish_MakeFile_new(chaz_CLI *cli) { self->static_lib = chaz_Lib_new_static("clownfish"); self->shared_lib_filename = chaz_Lib_filename(self->shared_lib); self->static_lib_filename = chaz_Lib_filename(self->static_lib); + self->core_objects = chaz_Util_strdup(""); return self; } @@ -8623,13 +8605,18 @@ cfish_MakeFile_destroy(cfish_MakeFile *self) { chaz_Lib_destroy(self->static_lib); free(self->shared_lib_filename); free(self->static_lib_filename); + free(self->core_objects); free(self); } static void cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { - SourceFileContext sfc; + static const char *const autogen_src_files[] = { + "cfish_parcel", + "testcfish_parcel", + NULL + }; const char *dir_sep = chaz_OS_dir_sep(); const char *obj_ext = chaz_CC_obj_ext(); @@ -8668,7 +8655,9 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { chaz_CFlags_add_include_dir(makefile_cflags, "."); chaz_CFlags_add_include_dir(makefile_cflags, self->core_dir); - chaz_CFlags_add_include_dir(makefile_cflags, self->host_src_dir); + if (self->host_src_dir) { + chaz_CFlags_add_include_dir(makefile_cflags, self->host_src_dir); + } chaz_CFlags_add_include_dir(makefile_cflags, self->autogen_inc_dir); var = chaz_MakeFile_add_var(self->makefile, "CFLAGS", NULL); @@ -8680,15 +8669,15 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { /* Object files */ - var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_OBJS", NULL); - sfc.var = var; - chaz_Make_list_files(self->host_src_dir, "c", S_c_file_callback, &sfc); - chaz_Make_list_files(self->core_dir, "c", S_c_file_callback, &sfc); + if (self->host_src_dir) { + chaz_Make_list_files(self->host_src_dir, "c", S_c_file_callback, self); + } + chaz_Make_list_files(self->core_dir, "c", S_c_file_callback, self); - for (i = 0; self->autogen_src_files[i] != NULL; ++i) { + for (i = 0; autogen_src_files[i] != NULL; ++i) { char *path = chaz_Util_join("", self->autogen_src_dir, dir_sep, - self->autogen_src_files[i], obj_ext, NULL); - chaz_MakeVar_append(var, path); + autogen_src_files[i], obj_ext, NULL); + S_add_core_object(self, path); free(path); } @@ -8696,15 +8685,17 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { chaz_MakeFile_add_rule(self->makefile, "all", self->shared_lib_filename); chaz_MakeFile_add_rule(self->makefile, "static", self->static_lib_filename); + chaz_MakeFile_add_rule(self->makefile, "core_objects", + "$(CLOWNFISH_OBJS)"); if (strcmp(chaz_CLI_strval(self->cli, "host"), "c") == 0) { cfish_MakeFile_write_c_cfc_rules(self); } /* Needed for parallel builds. */ - for (i = 0; self->autogen_src_files[i] != NULL; ++i) { + for (i = 0; autogen_src_files[i] != NULL; ++i) { char *path = chaz_Util_join("", self->autogen_src_dir, dir_sep, - self->autogen_src_files[i], ".c", NULL); + autogen_src_files[i], ".c", NULL); chaz_MakeFile_add_rule(self->makefile, path, self->autogen_target); free(path); } @@ -8734,7 +8725,6 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { static void cfish_MakeFile_write_c_cfc_rules(cfish_MakeFile *self) { - SourceFileContext sfc; chaz_MakeVar *var; chaz_MakeRule *rule; @@ -8752,9 +8742,9 @@ cfish_MakeFile_write_c_cfc_rules(cfish_MakeFile *self) { rule = chaz_MakeFile_add_rule(self->makefile, cfc_exe, NULL); chaz_MakeRule_add_make_command(rule, cfc_dir, NULL); - var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_HEADERS", NULL); - sfc.var = var; - chaz_Make_list_files(self->core_dir, "cfh", S_cfh_file_callback, &sfc); + self->cfh_var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_HEADERS", + NULL); + chaz_Make_list_files(self->core_dir, "cfh", S_cfh_file_callback, self); rule = chaz_MakeFile_add_rule(self->makefile, self->autogen_target, cfc_exe); chaz_MakeRule_add_prereq(rule, "$(CLOWNFISH_HEADERS)"); @@ -8874,7 +8864,7 @@ cfish_MakeFile_write_c_test_rules(cfish_MakeFile *self) { static void S_c_file_callback(const char *dir, char *file, void *context) { - SourceFileContext *sfc = (SourceFileContext*)context; + cfish_MakeFile *self = (cfish_MakeFile*)context; const char *dir_sep = chaz_OS_dir_sep(); const char *obj_ext = chaz_CC_obj_ext(); size_t file_len = strlen(file); @@ -8888,13 +8878,30 @@ S_c_file_callback(const char *dir, char *file, void *context) { file[file_len-2] = '\0'; obj_file = chaz_Util_join("", dir, dir_sep, file, obj_ext, NULL); - chaz_MakeVar_append(sfc->var, obj_file); + S_add_core_object(self, obj_file); free(obj_file); } +static void +S_add_core_object(cfish_MakeFile *self, const char *obj_file) { + char *new_core_objects; + + chaz_MakeVar_append(self->obj_var, obj_file); + + if (self->core_objects[0] == '\0') { + new_core_objects = chaz_Util_strdup(obj_file); + } + else { + new_core_objects = chaz_Util_join(" ", self->core_objects, obj_file, + NULL); + } + free(self->core_objects); + self->core_objects = new_core_objects; +} + static void S_cfh_file_callback(const char *dir, char *file, void *context) { - SourceFileContext *sfc = (SourceFileContext*)context; + cfish_MakeFile *self = (cfish_MakeFile*)context; const char *dir_sep = chaz_OS_dir_sep(); char *cfh_file; @@ -8904,7 +8911,7 @@ S_cfh_file_callback(const char *dir, char *file, void *context) { } cfh_file = chaz_Util_join(dir_sep, dir, file, NULL); - chaz_MakeVar_append(sfc->var, cfh_file); + chaz_MakeVar_append(self->cfh_var, cfh_file); free(cfh_file); } diff --git a/runtime/common/charmonizer.main b/runtime/common/charmonizer.main index f5e7c927..4a425f3a 100644 --- a/runtime/common/charmonizer.main +++ b/runtime/common/charmonizer.main @@ -41,6 +41,8 @@ typedef struct cfish_MakeFile { chaz_MakeFile *makefile; + chaz_MakeVar *obj_var; + chaz_MakeVar *cfh_var; chaz_CLI *cli; /* Directories and files. */ @@ -50,7 +52,7 @@ typedef struct cfish_MakeFile { char *autogen_src_dir; char *autogen_inc_dir; char *autogen_target; - const char **autogen_src_files; + char *core_objects; /* Libraries. */ chaz_Lib *shared_lib; @@ -59,10 +61,6 @@ typedef struct cfish_MakeFile { char *static_lib_filename; } cfish_MakeFile; -typedef struct SourceFileContext { - chaz_MakeVar *var; -} SourceFileContext; - static const char cfish_version[] = "0.5.0"; static const char cfish_major_version[] = "0.5"; @@ -90,6 +88,9 @@ cfish_MakeFile_write_c_test_rules(cfish_MakeFile *self); static void S_c_file_callback(const char *dir, char *file, void *context); +static void +S_add_core_object(cfish_MakeFile *self, const char *obj_file); + static void S_cfh_file_callback(const char *dir, char *file, void *context); @@ -186,6 +187,7 @@ int main(int argc, const char **argv) { mf->shared_lib_filename); chaz_ConfWriter_add_def("STATIC_LIB_FILENAME", mf->static_lib_filename); + chaz_ConfWriter_add_def("CORE_OBJECTS", mf->core_objects); cfish_MakeFile_destroy(mf); } @@ -270,6 +272,9 @@ cfish_MakeFile_new(chaz_CLI *cli) { cfish_MakeFile *self = malloc(sizeof(cfish_MakeFile)); self->makefile = chaz_MakeFile_new(); + self->obj_var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_OBJS", + NULL); + self->cfh_var = NULL; self->cli = cli; self->base_dir = ".."; @@ -281,42 +286,18 @@ cfish_MakeFile_new(chaz_CLI *cli) { = chaz_Util_join(dir_sep, "autogen", "hierarchy.json", NULL); if (strcmp(chaz_CLI_strval(cli, "host"), "go") == 0) { - static const char *go_autogen_src_files[] = { - "cfish_parcel", - "testcfish_parcel", - NULL - }; + /* TODO: Let Go bindings build code in "ext". */ self->host_src_dir = "ext"; - self->autogen_src_files = go_autogen_src_files; } else if (chaz_CLI_defined(cli, "enable-python")) { - static const char *python_autogen_src_files[] = { - "cfish_parcel", - "testcfish_parcel", - NULL - }; + /* TODO: Let Python bindings build code in "cfext". */ self->host_src_dir = "cfext"; - self->autogen_src_files = python_autogen_src_files; - } - else if (chaz_CLI_defined(cli, "enable-perl")) { - static const char *perl_autogen_src_files[] = { - "cfish_parcel", - "cfish_perl", - "testcfish_parcel", - "testcfish_perl", - NULL - }; - self->host_src_dir = "xs"; - self->autogen_src_files = perl_autogen_src_files; } - else { - static const char *c_autogen_src_files[] = { - "cfish_parcel", - "testcfish_parcel", - NULL - }; + else if (strcmp(chaz_CLI_strval(cli, "host"), "c") == 0) { self->host_src_dir = "src"; - self->autogen_src_files = c_autogen_src_files; + } + else { + self->host_src_dir = NULL; } self->shared_lib = chaz_Lib_new_shared("cfish", cfish_version, @@ -324,6 +305,7 @@ cfish_MakeFile_new(chaz_CLI *cli) { self->static_lib = chaz_Lib_new_static("clownfish"); self->shared_lib_filename = chaz_Lib_filename(self->shared_lib); self->static_lib_filename = chaz_Lib_filename(self->static_lib); + self->core_objects = chaz_Util_strdup(""); return self; } @@ -341,13 +323,18 @@ cfish_MakeFile_destroy(cfish_MakeFile *self) { chaz_Lib_destroy(self->static_lib); free(self->shared_lib_filename); free(self->static_lib_filename); + free(self->core_objects); free(self); } static void cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { - SourceFileContext sfc; + static const char *const autogen_src_files[] = { + "cfish_parcel", + "testcfish_parcel", + NULL + }; const char *dir_sep = chaz_OS_dir_sep(); const char *obj_ext = chaz_CC_obj_ext(); @@ -386,7 +373,9 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { chaz_CFlags_add_include_dir(makefile_cflags, "."); chaz_CFlags_add_include_dir(makefile_cflags, self->core_dir); - chaz_CFlags_add_include_dir(makefile_cflags, self->host_src_dir); + if (self->host_src_dir) { + chaz_CFlags_add_include_dir(makefile_cflags, self->host_src_dir); + } chaz_CFlags_add_include_dir(makefile_cflags, self->autogen_inc_dir); var = chaz_MakeFile_add_var(self->makefile, "CFLAGS", NULL); @@ -398,15 +387,15 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { /* Object files */ - var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_OBJS", NULL); - sfc.var = var; - chaz_Make_list_files(self->host_src_dir, "c", S_c_file_callback, &sfc); - chaz_Make_list_files(self->core_dir, "c", S_c_file_callback, &sfc); + if (self->host_src_dir) { + chaz_Make_list_files(self->host_src_dir, "c", S_c_file_callback, self); + } + chaz_Make_list_files(self->core_dir, "c", S_c_file_callback, self); - for (i = 0; self->autogen_src_files[i] != NULL; ++i) { + for (i = 0; autogen_src_files[i] != NULL; ++i) { char *path = chaz_Util_join("", self->autogen_src_dir, dir_sep, - self->autogen_src_files[i], obj_ext, NULL); - chaz_MakeVar_append(var, path); + autogen_src_files[i], obj_ext, NULL); + S_add_core_object(self, path); free(path); } @@ -414,15 +403,17 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { chaz_MakeFile_add_rule(self->makefile, "all", self->shared_lib_filename); chaz_MakeFile_add_rule(self->makefile, "static", self->static_lib_filename); + chaz_MakeFile_add_rule(self->makefile, "core_objects", + "$(CLOWNFISH_OBJS)"); if (strcmp(chaz_CLI_strval(self->cli, "host"), "c") == 0) { cfish_MakeFile_write_c_cfc_rules(self); } /* Needed for parallel builds. */ - for (i = 0; self->autogen_src_files[i] != NULL; ++i) { + for (i = 0; autogen_src_files[i] != NULL; ++i) { char *path = chaz_Util_join("", self->autogen_src_dir, dir_sep, - self->autogen_src_files[i], ".c", NULL); + autogen_src_files[i], ".c", NULL); chaz_MakeFile_add_rule(self->makefile, path, self->autogen_target); free(path); } @@ -452,7 +443,6 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { static void cfish_MakeFile_write_c_cfc_rules(cfish_MakeFile *self) { - SourceFileContext sfc; chaz_MakeVar *var; chaz_MakeRule *rule; @@ -470,9 +460,9 @@ cfish_MakeFile_write_c_cfc_rules(cfish_MakeFile *self) { rule = chaz_MakeFile_add_rule(self->makefile, cfc_exe, NULL); chaz_MakeRule_add_make_command(rule, cfc_dir, NULL); - var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_HEADERS", NULL); - sfc.var = var; - chaz_Make_list_files(self->core_dir, "cfh", S_cfh_file_callback, &sfc); + self->cfh_var = chaz_MakeFile_add_var(self->makefile, "CLOWNFISH_HEADERS", + NULL); + chaz_Make_list_files(self->core_dir, "cfh", S_cfh_file_callback, self); rule = chaz_MakeFile_add_rule(self->makefile, self->autogen_target, cfc_exe); chaz_MakeRule_add_prereq(rule, "$(CLOWNFISH_HEADERS)"); @@ -592,7 +582,7 @@ cfish_MakeFile_write_c_test_rules(cfish_MakeFile *self) { static void S_c_file_callback(const char *dir, char *file, void *context) { - SourceFileContext *sfc = (SourceFileContext*)context; + cfish_MakeFile *self = (cfish_MakeFile*)context; const char *dir_sep = chaz_OS_dir_sep(); const char *obj_ext = chaz_CC_obj_ext(); size_t file_len = strlen(file); @@ -606,13 +596,30 @@ S_c_file_callback(const char *dir, char *file, void *context) { file[file_len-2] = '\0'; obj_file = chaz_Util_join("", dir, dir_sep, file, obj_ext, NULL); - chaz_MakeVar_append(sfc->var, obj_file); + S_add_core_object(self, obj_file); free(obj_file); } +static void +S_add_core_object(cfish_MakeFile *self, const char *obj_file) { + char *new_core_objects; + + chaz_MakeVar_append(self->obj_var, obj_file); + + if (self->core_objects[0] == '\0') { + new_core_objects = chaz_Util_strdup(obj_file); + } + else { + new_core_objects = chaz_Util_join(" ", self->core_objects, obj_file, + NULL); + } + free(self->core_objects); + self->core_objects = new_core_objects; +} + static void S_cfh_file_callback(const char *dir, char *file, void *context) { - SourceFileContext *sfc = (SourceFileContext*)context; + cfish_MakeFile *self = (cfish_MakeFile*)context; const char *dir_sep = chaz_OS_dir_sep(); char *cfh_file; @@ -622,7 +629,7 @@ S_cfh_file_callback(const char *dir, char *file, void *context) { } cfh_file = chaz_Util_join(dir_sep, dir, file, NULL); - chaz_MakeVar_append(sfc->var, cfh_file); + chaz_MakeVar_append(self->cfh_var, cfh_file); free(cfh_file); } diff --git a/runtime/perl/.gitignore b/runtime/perl/.gitignore index 62216108..4e0ff0f1 100644 --- a/runtime/perl/.gitignore +++ b/runtime/perl/.gitignore @@ -4,6 +4,7 @@ /Charmony.pm /MYMETA.json /MYMETA.yml +/Makefile /_build/ /autogen/ /blib/ diff --git a/runtime/perl/buildlib/Clownfish/Build.pm b/runtime/perl/buildlib/Clownfish/Build.pm index 061759d1..8ae957f5 100644 --- a/runtime/perl/buildlib/Clownfish/Build.pm +++ b/runtime/perl/buildlib/Clownfish/Build.pm @@ -68,7 +68,8 @@ sub new { $args{clownfish_params} = { autogen_header => _autogen_header(), include => [], # Don't use default includes. - source => [ $CORE_SOURCE_DIR, $XS_SOURCE_DIR ], + source => [ $CORE_SOURCE_DIR ], + c_source => [ $XS_SOURCE_DIR ], }; my $self = $class->SUPER::new( recursive_test_files => 1, %args ); @@ -83,6 +84,7 @@ sub new { $self->extra_compiler_flags(@$extra_cflags); } + $self->charmonizer_params( create_makefile => 1 ); $self->charmonizer_params( charmonizer_c => $CHARMONIZER_C ); return $self;