![Roman Zippel](/assets/img/avatar_default.png)
This fixes one of the worst kbuild warts left - the broken dependencies used to check and regenerate the .config file. This was done via an indirect dependency and the .config itself had an empty command, which can cause make not to reread the changed .config file. Instead of this we generate now a new file include/config/auto.conf from .config, which is used for kbuild and has the proper dependencies. It's also the main make target now for all files generated during this step (and thus replaces include/linux/autoconf.h). This also means we can now relax the syntax requirements for the .config file and we don't have to rewrite it all the time, i.e. silentoldconfig only writes .config now when it's necessary to keep it in sync with the Kconfig files and even this can be suppressed by setting the environment variable KCONFIG_NOSILENTUPDATE, so the update can (and must) be done manually. Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
112 lines
2.2 KiB
C
112 lines
2.2 KiB
C
/*
|
|
* Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
|
|
* Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
|
|
*
|
|
* Released under the terms of the GNU GPL v2.0.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "lkc.h"
|
|
|
|
/* file already present in list? If not add it */
|
|
struct file *file_lookup(const char *name)
|
|
{
|
|
struct file *file;
|
|
|
|
for (file = file_list; file; file = file->next) {
|
|
if (!strcmp(name, file->name))
|
|
return file;
|
|
}
|
|
|
|
file = malloc(sizeof(*file));
|
|
memset(file, 0, sizeof(*file));
|
|
file->name = strdup(name);
|
|
file->next = file_list;
|
|
file_list = file;
|
|
return file;
|
|
}
|
|
|
|
/* write a dependency file as used by kbuild to track dependencies */
|
|
int file_write_dep(const char *name)
|
|
{
|
|
struct file *file;
|
|
FILE *out;
|
|
|
|
if (!name)
|
|
name = ".kconfig.d";
|
|
out = fopen("..config.tmp", "w");
|
|
if (!out)
|
|
return 1;
|
|
fprintf(out, "deps_config := \\\n");
|
|
for (file = file_list; file; file = file->next) {
|
|
if (file->next)
|
|
fprintf(out, "\t%s \\\n", file->name);
|
|
else
|
|
fprintf(out, "\t%s\n", file->name);
|
|
}
|
|
fprintf(out, "\ninclude/config/auto.conf: \\\n"
|
|
"\t$(deps_config)\n\n"
|
|
"$(deps_config): ;\n");
|
|
fclose(out);
|
|
rename("..config.tmp", name);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* Allocate initial growable sting */
|
|
struct gstr str_new(void)
|
|
{
|
|
struct gstr gs;
|
|
gs.s = malloc(sizeof(char) * 64);
|
|
gs.len = 16;
|
|
strcpy(gs.s, "\0");
|
|
return gs;
|
|
}
|
|
|
|
/* Allocate and assign growable string */
|
|
struct gstr str_assign(const char *s)
|
|
{
|
|
struct gstr gs;
|
|
gs.s = strdup(s);
|
|
gs.len = strlen(s) + 1;
|
|
return gs;
|
|
}
|
|
|
|
/* Free storage for growable string */
|
|
void str_free(struct gstr *gs)
|
|
{
|
|
if (gs->s)
|
|
free(gs->s);
|
|
gs->s = NULL;
|
|
gs->len = 0;
|
|
}
|
|
|
|
/* Append to growable string */
|
|
void str_append(struct gstr *gs, const char *s)
|
|
{
|
|
size_t l = strlen(gs->s) + strlen(s) + 1;
|
|
if (l > gs->len) {
|
|
gs->s = realloc(gs->s, l);
|
|
gs->len = l;
|
|
}
|
|
strcat(gs->s, s);
|
|
}
|
|
|
|
/* Append printf formatted string to growable string */
|
|
void str_printf(struct gstr *gs, const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
char s[10000]; /* big enough... */
|
|
va_start(ap, fmt);
|
|
vsnprintf(s, sizeof(s), fmt, ap);
|
|
str_append(gs, s);
|
|
va_end(ap);
|
|
}
|
|
|
|
/* Retrieve value of growable string */
|
|
const char *str_get(struct gstr *gs)
|
|
{
|
|
return gs->s;
|
|
}
|
|
|