📄 nutcomponent.c
字号:
else { fprintf(fp, "=%s\n", opts->nco_value); } } } opts = opts->nco_nxt; } /* Recursively process the subcomponents. */ if (compo->nc_child) { WriteMakedefLines(fp, compo->nc_child); } compo = compo->nc_nxt; }}/*! * \brief Add target to the Makefile in the top build directory. * * \param fp Pointer to an opened file. * \param compo Pointer to the first child of the root component. * \param target Makefile target, set to NULL for 'all'. */void WriteMakeRootLines(FILE * fp, NUTCOMPONENT * compo, char *target){ if (target) { fprintf(fp, "%s:\n", target); } else { fprintf(fp, "all:\n"); } while (compo) { if (compo->nc_subdir) { fprintf(fp, "\t$(MAKE) -C %s", compo->nc_subdir); if (target) { fprintf(fp, " %s", target); } fputc('\n', fp); } compo = compo->nc_nxt; } fprintf(fp, "\n");}/*! * \brief Create makefiles from a specified NUTCOMPONENT tree. * * This routine creates all required Makefiles, one in the top build directory * and one in each library's subdirectory. It will also create the NutConf.mk * and UserConf.mk. Except for UserConf.mk, any existing file will be replaced. * * \param root Pointer to the root component. * \param bld_dir Pathname of the top build directory. * \param src_dir Pathname of the top source directory. * \param mak_ext Filename extension of the Makedefs/Makerules to be used, e.g. avr-gcc. * \param ifirst_dir Optional include directory. Header files will be included first * and thus may replace standard Nut/OS headers with the same name. * \param ilast_dir Optional include directory. Header files will be included last. * This parameter is typically used to specify the compilers runtime * library. Header files with the same name as Nut/OS standard headers * are ignored. * \param ins_dir Final target directory of the Nut/OS libraries. Will be used with * 'make install'. * * \return 0 on success, otherwise return -1. * * \todo This function's parameter list is a bit overloaded. Either split the function * or use a parameter structure. */int CreateMakeFiles(NUTCOMPONENT *root, const char *bld_dir, const char *src_dir, const char *mak_ext, const char *ifirst_dir, const char *ilast_dir, const char *ins_dir){ FILE *fp; char path[255]; NUTCOMPONENT *compo; int targets; int i; struct tm *ltime; time_t now; time(&now); ltime = localtime(&now); /* Create the Makedefs file */ sprintf(path, "%s/NutConf.mk", bld_dir); if(CreateDirectoryPath(path) == 0) { fp = fopen(path, "w"); if (fp) { fprintf(fp, "# Automatically generated on %s", asctime(ltime)); fprintf(fp, "#\n# Do not edit, modify UserConf.mk instead!\n#\n\n"); WriteMakedefLines(fp, root->nc_child); fprintf(fp, "\n\ninclude $(top_blddir)/UserConf.mk\n"); fclose(fp); } } /* Create the user's Makedefs file, if it doesn't exist */ sprintf(path, "%s/UserConf.mk", bld_dir); if(access(path, 0)) { fp = fopen(path, "w"); if (fp) { fprintf(fp, "# Automatically created on %s", asctime(ltime)); fprintf(fp, "#\n# You can use this file to modify values in NutConf.mk\n#\n\n"); fclose(fp); } } /* Create the root Makefile */ sprintf(path, "%s/Makefile", bld_dir); if(CreateDirectoryPath(path) == 0) { fp = fopen(path, "w"); if (fp) { fprintf(fp, "# Do not edit! Automatically generated on %s\n", asctime(ltime)); WriteMakeRootLines(fp, root->nc_child, NULL); if(ins_dir && *ins_dir) { WriteMakeRootLines(fp, root->nc_child, "install"); } WriteMakeRootLines(fp, root->nc_child, "clean"); fclose(fp); } } /* Create library Makefiles */ compo = root->nc_child; while (compo) { if (compo->nc_subdir) { sprintf(path, "%s/%s", bld_dir, compo->nc_subdir); strcat(path, "/Makefile"); if(CreateDirectoryPath(path) == 0) { fp = fopen(path, "w"); if (fp) { fprintf(fp, "# Do not edit! Automatically generated on %s\n", asctime(ltime)); fprintf(fp, "PROJ =\tlib%s\n\n", compo->nc_name); if (src_dir[0] == '/' || src_dir[1] == ':') fprintf(fp, "top_srcdir = %s\n", src_dir); else if (strlen(src_dir)) fprintf(fp, "top_srcdir = ../../%s\n", src_dir); else fprintf(fp, "top_srcdir = ../..\n"); if (bld_dir[0] == '/' || bld_dir[1] == ':') fprintf(fp, "top_blddir = %s\n\n", bld_dir); else if (strlen(bld_dir)) fprintf(fp, "top_blddir = ../../%s\n\n", bld_dir); else fprintf(fp, "top_blddir = ../..\n\n"); fprintf(fp, "VPATH = $(top_srcdir)/%s\n\n", compo->nc_subdir); sprintf(path, "%s/%s", bld_dir, compo->nc_subdir); targets = WriteMakeSources(fp, compo->nc_child, path); fprintf(fp, "OBJS = $(SRCS:.c=.o)\n"); //for(i = 0; i < targets; i++) { // fprintf(fp, "OBJ%d = $(SRC%d:.c=.o)\n", i + 1, i + 1); //} fprintf(fp, "include $(top_blddir)/NutConf.mk\n\n", mak_ext); fprintf(fp, "include $(top_srcdir)/Makedefs.%s\n\n", mak_ext); fprintf(fp, "INCFIRST=$(INCPRE)$(top_blddir)/include "); if(ifirst_dir && *ifirst_dir) { fprintf(fp, " $(INCPRE)%s", ifirst_dir); } fputc('\n', fp); if(ilast_dir && *ilast_dir) { fprintf(fp, "INCLAST = $(INCPRE)%s\n", ilast_dir); } fprintf(fp, "\nall: $(PROJ).a $(OBJS)"); for(i = 0; i < targets; i++) { fprintf(fp, " $(OBJ%d)", i + 1); } fprintf(fp, "\n\n"); if(ins_dir && *ins_dir) { /* Sigh! What a crap! But the bloody create requires a file. */ sprintf(path, "%s/read.me", ins_dir); CreateDirectoryPath(path); fprintf(fp, "install: $(PROJ).a"); for(i = 0; i < targets; i++) { fprintf(fp, " $(OBJ%d)", i + 1); } if (ins_dir[0] == '/' || ins_dir[1] == ':') strcpy (path, ins_dir); else sprintf(path, "../../%s", ins_dir); fprintf(fp, "\n\t$(CP) $(PROJ).a %s/$(PROJ).a\n", path); for(i = 0; i < targets; i++) { fprintf(fp, "\t$(CP) $(OBJ%d) %s/$(notdir $(OBJ%d))\n", i + 1, path, i + 1); } } fprintf(fp, "\ninclude $(top_srcdir)/Makerules.%s\n\n", mak_ext); fprintf(fp, ".PHONY: clean\n"); fprintf(fp, "clean: cleancc cleanedit\n"); fprintf(fp, "\t-rm -f $(PROJ).a\n"); for(i = 0; i < targets; i++) { fprintf(fp, "\t-rm -f $(OBJ%d)\n", i + 1); } fclose(fp); } } } compo = compo->nc_nxt; } return 0;}typedef struct _NUTHEADERMACRO NUTHEADERMACRO;/*! * \brief Linked list of header file macros. */struct _NUTHEADERMACRO { NUTHEADERMACRO *nhm_nxt; char *nhm_name; char *nhm_value;};typedef struct _NUTHEADERFILE NUTHEADERFILE;/*! * \brief Linked list of header files. */struct _NUTHEADERFILE { NUTHEADERFILE *nhf_nxt; char *nhf_path; NUTHEADERMACRO *nhf_macros;};/*! * \brief Get entry to the header file list. */NUTHEADERFILE *GetHeaderFileEntry(NUTHEADERFILE **nh_root, char *filename){ NUTHEADERFILE *nhf; /* Add to existing list. */ if (*nh_root) { nhf = *nh_root; while (strcasecmp(nhf->nhf_path, filename)) { if (nhf->nhf_nxt) { nhf = nhf->nhf_nxt; } else { nhf->nhf_nxt = calloc(1, sizeof(NUTHEADERFILE)); nhf = nhf->nhf_nxt; nhf->nhf_path = filename; } } } /* First entry, create list root. */ else { nhf = calloc(1, sizeof(NUTHEADERFILE)); nhf->nhf_path = filename; *nh_root = nhf; } return nhf;}/*! * \brief Add header file and option to the header file list. */NUTHEADERFILE *AddHeaderFileMacro(NUTHEADERFILE *nh_root, NUTCOMPONENTOPTION * opts){ NUTHEADERFILE *nhf; NUTHEADERMACRO *nhm; /* Get the header file entry. */ nhf = GetHeaderFileEntry(&nh_root, opts->nco_file); /* Add macro to existing header file entry. */ if (nhf->nhf_macros) { nhm = nhf->nhf_macros; while (strcasecmp(nhm->nhm_name, opts->nco_name)) { if (nhm->nhm_nxt) { nhm = nhm->nhm_nxt; } else { nhm->nhm_nxt = calloc(1, sizeof(NUTHEADERMACRO)); nhm = nhm->nhm_nxt; nhm->nhm_name = opts->nco_name; nhm->nhm_value = opts->nco_value; } } } /* First entry of this header file. */ else { nhm = calloc(1, sizeof(NUTHEADERMACRO)); nhm->nhm_name = opts->nco_name; nhm->nhm_value = opts->nco_value; nhf->nhf_macros = nhm; } return nh_root;}/*! * \brief Create a linked list of header files and associated macros. */NUTHEADERFILE *CreateHeaderList(NUTCOMPONENT * compo, NUTHEADERFILE *nh_root){ NUTCOMPONENTOPTION *opts; while (compo) { opts = compo->nc_opts; while (opts) { if (opts->nco_file) { if((opts->nco_enabled && opts->nco_active) || opts->nco_default != NULL) { /* Do not save empty values. */ if (opts->nco_value == NULL) { if (opts->nco_flavor && (strcasecmp(opts->nco_flavor, "boolean") == 0 || strcasecmp(opts->nco_flavor, "booldata") == 0)) { nh_root = AddHeaderFileMacro(nh_root, opts); } else { GetHeaderFileEntry(&nh_root, opts->nco_file); } } else { nh_root = AddHeaderFileMacro(nh_root, opts); } } else { GetHeaderFileEntry(&nh_root, opts->nco_file); } } opts = opts->nco_nxt; } if (compo->nc_child) { nh_root = CreateHeaderList(compo->nc_child, nh_root); } compo = compo->nc_nxt; } return nh_root;}/*! * \brief Deletes a linked list of header files and associated macros. */void ReleaseHeaderList(NUTHEADERFILE *nh_root){ NUTHEADERFILE *nhf; NUTHEADERMACRO *nhm, *c; while (nh_root) { nhm = nh_root->nhf_macros; while (nhm) { c = nhm->nhm_nxt; free (nhm); nhm = c; } nhf = nh_root->nhf_nxt; free (nh_root); nh_root = nhf; }}/*! * \brief Create header files from a specified NUTCOMPONENT tree. * * This routine creates all build specific header files in the build * directory. Existing files will be replaced. * * \param root Pointer to the root component. * \param bld_dir Pathname of the top build directory. * * \return 0 on success, otherwise return -1. * * \todo Release allocated heap space. */int CreateHeaderFiles(NUTCOMPONENT * root, const char *bld_dir){ NUTHEADERFILE *nh_root = NULL; NUTHEADERFILE *nhf; NUTHEADERMACRO *nhm; FILE *fp; char path[255]; char exname[255]; char *cp; struct tm *ltime; time_t now; time(&now); ltime = localtime(&now); /* Create a linked list of header files with active component options. */ nh_root = CreateHeaderList(root->nc_child, nh_root); for (nhf = nh_root; nhf; nhf = nhf->nhf_nxt) { strcpy(path, bld_dir); strcat(path, "/"); strcat(path, nhf->nhf_path); strcpy(exname, "_"); strcat(exname, nhf->nhf_path); strcat(exname, "_"); for(cp = exname; *cp; cp++) { if(*cp < '0') { *cp = '_'; } else { *cp = (char)toupper(*cp); } } /* If no macros are specified, then remove the file. */ if(nhf->nhf_macros == NULL) { unlink(path); } else if(CreateDirectoryPath(path) == 0) { if ((fp = fopen(path, "w")) != 0) { fprintf(fp, "#ifndef %s\n", exname); fprintf(fp, "#define %s\n\n", exname); fprintf(fp, "/*\n * Do not edit! Automatically generated on %s */\n\n", asctime(ltime)); for (nhm = nhf->nhf_macros; nhm; nhm = nhm->nhm_nxt) { fprintf(fp, "#ifndef %s\n", nhm->nhm_name); fprintf(fp, "#define %s", nhm->nhm_name); if (nhm->nhm_value) { fprintf(fp, " %s", nhm->nhm_value); } fprintf(fp, "\n#endif\n\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -