Add macos clang/ld compiler options

With these option I can now built several packages without problem.
There are a lot of options we can add so I tried to implement the
minumum.

Add the following options:
dynamiclib		same as -shared
flat_namespace		default/ignored
two_levelnamespace	ignored
undefined		default/ignored
install_name		name of dynmic lib
compatibility_version	version dynamic lib
current_version	version version dynamic lib

-Wl options:
all_load		same as whole-archive
force_load		same as whole-archive with lib
single_module		ignored
This commit is contained in:
herman ten brugge 2022-12-20 07:24:48 +01:00
parent f6f3d646fb
commit d5f25d19b3
3 changed files with 97 additions and 13 deletions

View File

@ -846,6 +846,9 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
tcc_free(s1->mapfile);
tcc_free(s1->outfile);
tcc_free(s1->deps_outfile);
#if defined TCC_TARGET_MACHO
tcc_free(s1->install_name);
#endif
dynarray_reset(&s1->files, &s1->nb_files);
dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
@ -1374,6 +1377,14 @@ static void copy_linker_arg(char **pp, const char *s, int sep)
pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
}
static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
{
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
f->type = filetype;
strcpy(f->name, filename);
dynarray_add(&s->files, &s->nb_files, f);
}
/* set linker options */
static int tcc_set_linker(TCCState *s, const char *option)
{
@ -1470,6 +1481,16 @@ static int tcc_set_linker(TCCState *s, const char *option)
#endif
} else
goto err;
#endif
#ifdef TCC_TARGET_MACHO
} else if (link_option(option, "all_load", &p)) {
s->filetype |= AFF_WHOLE_ARCHIVE;
} else if (link_option(option, "force_load", &p)) {
s->filetype |= AFF_WHOLE_ARCHIVE;
args_parser_add_file(s, p, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));
s->nb_libraries++;
} else if (link_option(option, "single_module", &p)) {
ignoring = 1;
#endif
} else if (ret = link_option(option, "?whole-archive", &p), ret) {
if (ret > 0)
@ -1549,6 +1570,13 @@ enum {
TCC_OPTION_x,
TCC_OPTION_ar,
TCC_OPTION_impdef,
TCC_OPTION_dynamiclib,
TCC_OPTION_flat_namespace,
TCC_OPTION_two_levelnamespace,
TCC_OPTION_undefined,
TCC_OPTION_install_name,
TCC_OPTION_compatibility_version ,
TCC_OPTION_current_version,
};
#define TCC_OPTION_HAS_ARG 0x0001
@ -1576,7 +1604,14 @@ static const TCCOption tcc_options[] = {
{ "b", TCC_OPTION_b, 0 },
#endif
{ "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
#ifdef TCC_TARGET_MACHO
{ "compatibility_version", TCC_OPTION_compatibility_version, TCC_OPTION_HAS_ARG },
{ "current_version", TCC_OPTION_current_version, TCC_OPTION_HAS_ARG },
#endif
{ "c", TCC_OPTION_c, 0 },
#ifdef TCC_TARGET_MACHO
{ "dynamiclib", TCC_OPTION_dynamiclib, 0 },
#endif
{ "dumpversion", TCC_OPTION_dumpversion, 0},
{ "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "static", TCC_OPTION_static, 0 },
@ -1596,6 +1631,9 @@ static const TCCOption tcc_options[] = {
{ "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
#endif
{ "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
#ifdef TCC_TARGET_MACHO
{ "flat_namespace", TCC_OPTION_flat_namespace, 0 },
#endif
{ "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
{ "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
@ -1613,6 +1651,11 @@ static const TCCOption tcc_options[] = {
{ "ar", TCC_OPTION_ar, 0},
#ifdef TCC_TARGET_PE
{ "impdef", TCC_OPTION_impdef, 0},
#endif
#ifdef TCC_TARGET_MACHO
{ "install_name", TCC_OPTION_install_name, TCC_OPTION_HAS_ARG },
{ "two_levelnamespace", TCC_OPTION_two_levelnamespace, 0 },
{ "undefined", TCC_OPTION_undefined, TCC_OPTION_HAS_ARG },
#endif
/* ignored (silently, except after -Wunsupported) */
{ "arch", 0, TCC_OPTION_HAS_ARG},
@ -1697,14 +1740,6 @@ static int set_flag(TCCState *s, const FlagDef *flags, const char *name)
return ret;
}
static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
{
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
f->type = filetype;
strcpy(f->name, filename);
dynarray_add(&s->files, &s->nb_files, f);
}
static int args_parser_make_argv(const char *r, int *argc, char ***argv)
{
int ret = 0, q, c;
@ -1763,6 +1798,26 @@ static void args_parser_listfile(TCCState *s,
*pargc = s->argc = argc, *pargv = s->argv = argv;
}
#if defined TCC_TARGET_MACHO
static uint32_t parse_version(TCCState *s1, const char *version)
{
uint32_t a = 0;
uint32_t b = 0;
uint32_t c = 0;
char* last;
a = strtoul(version, &last, 10);
if (*last == '.') {
b = strtoul(&last[1], &last, 10);
if (*last == '.')
c = strtoul(&last[1], &last, 10);
}
if (*last || a > 0xffff || b > 0xff || c > 0xff)
tcc_error("version a.b.c not correct: %s", version);
return (a << 16) | (b << 8) | c;
}
#endif
PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
{
TCCState *s1 = s;
@ -2042,6 +2097,26 @@ reparse:
case TCC_OPTION_impdef:
x = OPT_IMPDEF;
goto extra_action;
#if defined TCC_TARGET_MACHO
case TCC_OPTION_dynamiclib:
x = TCC_OUTPUT_DLL;
goto set_output_type;
case TCC_OPTION_flat_namespace:
break;
case TCC_OPTION_two_levelnamespace:
break;
case TCC_OPTION_undefined:
break;
case TCC_OPTION_install_name:
s->install_name = tcc_strdup(optarg);
break;
case TCC_OPTION_compatibility_version:
s->compatibility_version = parse_version(s, optarg);
break;
case TCC_OPTION_current_version:
s->current_version = parse_version(s, optarg);;
break;
#endif
case TCC_OPTION_ar:
x = OPT_AR;
extra_action:

6
tcc.h
View File

@ -975,6 +975,12 @@ struct TCCState {
# endif
#endif
#if defined TCC_TARGET_MACHO
char *install_name;
uint32_t compatibility_version;
uint32_t current_version;
#endif
#ifndef ELF_OBJ_ONLY
int nb_sym_versions;
struct sym_version *sym_versions;

View File

@ -429,7 +429,7 @@ struct macho {
} sk_to_sect[sk_last];
int *elfsectomacho;
int *e2msym;
Section *symtab, *strtab, *wdata, *indirsyms, *stubs, *exports;
Section *symtab, *strtab, *indirsyms, *stubs, *exports;
uint32_t ilocal, iextdef, iundef;
int stubsym, n_got, nr_plt;
int segment[sk_last];
@ -1705,14 +1705,17 @@ static void collect_sections(TCCState *s1, struct macho *mo, const char *filenam
}
if (s1->output_type != TCC_OUTPUT_EXE) {
i = (sizeof(*dylib) + strlen(filename) + 1 + 7) &-8;
const char *name = s1->install_name ? s1->install_name : filename;
i = (sizeof(*dylib) + strlen(name) + 1 + 7) &-8;
dylib = add_lc(mo, LC_ID_DYLIB, i);
dylib->name = sizeof(*dylib);
dylib->timestamp = 1;
dylib->current_version = 1 << 16;
dylib->compatibility_version = 1 << 16;
dylib->current_version =
s1->current_version ? s1->current_version : 1 << 16;
dylib->compatibility_version =
s1->compatibility_version ? s1->compatibility_version : 1 << 16;
str = (char*)dylib + dylib->name;
strcpy(str, filename);
strcpy(str, name);
}
#ifdef CONFIG_NEW_MACHO