2 Star 4 Fork 1

阙博凯/The Chinese Compiler 中文编译器

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
tcc.c 16.31 KB
一键复制 编辑 原始数据 按行查看 历史
阙博凯 提交于 2023-07-30 15:21 . The Chinese Compiler cn.0.1
/*
* TCC - Tiny C Compiler
*
* Copyright (c) 2001-2004 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/****************************************************************************************************
* 名称:中文编译器
* 描述:中文版C语言编译器。
* Tiny C Compiler 0.9.27 - Copyright (C) 2001-2006 Fabrice Bellard
* The Chinese Compiler cn.0.1 版权(C) 2023 阙博凯
****************************************************************************************************/
#include "tcc.h"
#if ONE_SOURCE
# include "libtcc.c"
#endif
#include "tcctools.c"
static const char help[] =
"————————————————————————————————————————————————\n"
"The Chinese Compiler "TCC_VERSION" - 版权(C) 2023 阙博凯\n"
"————————————————————————————————————————————————\n"
"用法: tcc [选项...] [-o 输出文件] [-c] 输入文件(s)...\n"
" tcc [选项...] -run 输入文件 [参数...]\n"
"————————————————————————————————————————————————\n"
"常用选项:\n"
" -c 仅编译 - 生成一个TARGET文件\n"
" -o 输出文件名 设置输出文件名\n"
" -run 运行编译源码\n"
" -fflag 设置或重置(带有 'no-' 前缀)'flag'(见 tcc -hh)\n"
" -std=c99 Conform to the ISO 1999 C standard (default).\n"
" -std=c11 Conform to the ISO 2011 C standard.\n"
" -Wwarning 设置或重置(带有 'no-' 前缀)'警告'(见 tcc -hh)\n"
" -w 禁用所有警告\n"
" --version -v show 显示版本\n"
" -vv 显示搜索路径或加载的文件\n"
" -h -hh show this, show more help\n"
" -bench 显示编译统计信息\n"
" - 使用标准输入管道作为 infile\n"
" @listfile 从列表文件中读取参数\n"
"————————————————————————————————————————————————\n"
"预处理器选项:\n"
" -Idir 添加包含路径 'dir'\n"
" -Dsym[=val] 用值 'val'定义'sym'\n"
" -Usym 未定义的'符号'\n"
" -E 仅预处理\n"
" -C keep comments (not yet implemented)\n"
"————————————————————————————————————————————————\n"
"链接器选项:\n"
" -Ldir 添加库路径 'dir'\n"
" -llib 链接动态或静态库 'lib'\n"
" -r 生成(可重定位)TARGET文件\n"
" -shared 生成共享库/dll\n"
" -rdynamic 将所有全局符号导出到动态链接器\n"
" -soname 为运行时使用的共享库设置名称\n"
" -Wl,-opt[=val] 设置链接器选项(参见 tcc -hh)\n"
"————————————————————————————————————————————————\n"
"调试器选项:\n"
" -g 生成运行时调试信息\n"
#ifdef CONFIG_TCC_BCHECK
" -b 使用内置内存和边界检查器进行编译 (暗示 -g)\n"
#endif
#ifdef CONFIG_TCC_BACKTRACE
" -bt N 链接与回溯(堆栈转储)支持 [显示最多 N 个调用者]\n"
#endif
"————————————————————————————————————————————————\n"
"杂项:\n"
" -x[c|a|b|n] 指定下一个 infile 的类型 (C,ASM,BIN,NONE)\n"
" -nostdinc 不使用标准系统包含路径\n"
" -nostdlib 不要与标准 crt 和库链接\n"
" -Bdir 设置 tcc 的私有 include/library 目录\n"
" -MD 生成make依赖文件【忽略系统文件】\n"
" -MF file 指定依赖项文件名\n"
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
" -m32/64 遵循 i386/x86_64 交叉编译器\n"
#endif
"工具:\n"
" create library : tcc -ar [rcsv] lib.a files\n"
#ifdef TCC_TARGET_PE
" create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
#endif
;
static const char help2[] =
"————————————————————————————————————————————————\n"
"The Chinese Compiler "TCC_VERSION" - 版权(C) 2023 阙博凯\n"
"————————————————————————————————————————————————\n"
"特殊选项:\n"
" -P -P1 带 -E:无/替代 #line 输出\n"
" -dD -dM 带 -E: 输出 #define 指令\n"
" -pthread 与 -D_REENTRANT 和 -lpthread 相同\n"
" -On 与 n 的 -D__OPTIMIZE__ 相同 > 0\n"
" -Wp,-opt 与 -opt 相同\n"
" -include file 在每个输入文件上方包含“文件”\n"
" -isystem dir 将 'dir' 添加到系统包含路径\n"
" -static 链接到静态库(不推荐)\n"
" -dumpversion 打印版本\n"
" -print-search-dirs 打印搜索路径\n"
" -dt 使用 -run/-E: 自动定义 'test_...' 宏\n"
"————————————————————————————————————————————————\n"
"忽略的选项:\n"
" --param -pedantic -pipe -s -std -traditional\n"
"————————————————————————————————————————————————\n"
"-W... 警告:\n"
" all 打开一些 (*) 警告\n"
" error 警告后停止(任何或指定)\n"
" unsupported 警告忽略的选项、编译指示等\n"
" write-strings 字符串是常量\n"
" implicit-function-declaration 警告丢失原型 (*)\n"
"————————————————————————————————————————————————\n"
"-f[no-]... 标志:\n"
" unsigned-char 默认字符是无符号的\n"
" signed-char 默认字符有符号的\n"
" common 修饰外部符号 bss\n"
" leading-underscore 修饰外部符号\n"
" ms-extensions 允许在结构体中使用匿名结构体\n"
" dollars-in-identifiers 允许在 C 符号中使用'$'\n"
"————————————————————————————————————————————————\n"
"-m... 特定选项:\n"
" ms-bitfields 使用 MSVC 位域布局\n"
#ifdef TCC_TARGET_ARM
" float-abi hard/softfp on arm\n"
#endif
#ifdef TCC_TARGET_X86_64
" no-sse 在 x86_64 上禁用浮动\n"
#endif
"————————————————————————————————————————————————\n"
"-Wl,... 链接器选项:\n"
" -nostdlib do 不与标准 crt/libs 链接\n"
" -[no-]whole-archive 完全/仅根据需要加载库\n"
" -export-all-symbols 与 -rdynamic 一样\n"
" -export-dynamic same as -rdynamic\n"
" -image-base= -Ttext= 设置可执行文件的基地址\n"
" -section-alignment= 在可执行文件中设置节对齐\n"
#ifdef TCC_TARGET_PE
" -file-alignment= 设置PE文件对齐\n"
" -stack= 设置 PE 堆栈保留\n"
" -large-address-aware 设置相关PE选项\n"
" -subsystem=[console/windows] 设置 PE 子系统\n"
" -oformat=[pe-* binary] 设置可执行输出格式\n"
"————————————————————————————————————————————————\n"
"预定义宏:\n"
" tcc -E -dM - < nul\n"
#else
" -rpath= 设置动态库搜索路径\n"
" -enable-new-dtags 设置 DT_RUNPATH 而不是 DT_RPATH\n"
" -soname= 设置 DT_SONAME 精灵标签\n"
" -Bsymbolic 设置 DT_SYMBOLIC elf精灵标签\n"
" -oformat=[elf32/64-* binary] 设置可执行输出格式\n"
" -init= -fini= -as-needed -O (忽略)\n"
"————————————————————————————————————————————————\n"
"预定义宏:\n"
" tcc -E -dM - < /dev/null\n"
#endif
"————————————————————————————————————————————————\n"
"另请参见手册以获取更多详细信息\n"
;
static const char version[] =
"tcc version "TCC_VERSION" ("
#ifdef TCC_TARGET_I386
"i386"
#elif defined TCC_TARGET_X86_64
"x86_64"
#elif defined TCC_TARGET_C67
"C67"
#elif defined TCC_TARGET_ARM
"ARM"
#elif defined TCC_TARGET_ARM64
"AArch64"
#elif defined TCC_TARGET_RISCV64
"riscv64"
#endif
#ifdef TCC_ARM_HARDFLOAT
" Hard Float"
#endif
#ifdef TCC_TARGET_PE
" Windows"
#elif defined(TCC_TARGET_MACHO)
" Darwin"
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
" FreeBSD"
#else
" Linux"
#endif
")\n"
;
static void print_dirs(const char *msg, char **paths, int nb_paths)
{
int i;
printf("%s:\n%s", msg, nb_paths ? "" : " -\n");
for(i = 0; i < nb_paths; i++)
printf(" %s\n", paths[i]);
}
static void print_search_dirs(TCCState *s)
{
printf("install: %s\n", s->tcc_lib_path);
/* print_dirs("programs", NULL, 0); */
print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
print_dirs("libraries", s->library_paths, s->nb_library_paths);
#ifdef TCC_TARGET_PE
printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", s->tcc_lib_path);
#else
printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
print_dirs("crt", s->crt_paths, s->nb_crt_paths);
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
#endif
}
static void set_environment(TCCState *s)
{
char * path;
path = getenv("C_INCLUDE_PATH");
if(path != NULL) {
tcc_add_sysinclude_path(s, path);
}
path = getenv("CPATH");
if(path != NULL) {
tcc_add_include_path(s, path);
}
path = getenv("LIBRARY_PATH");
if(path != NULL) {
tcc_add_library_path(s, path);
}
}
static char *default_outputfile(TCCState *s, const char *first_file)
{
char buf[1024];
char *ext;
const char *name = "a";
if (first_file && strcmp(first_file, "-"))
name = tcc_basename(first_file);
snprintf(buf, sizeof(buf), "%s", name);
ext = tcc_fileextension(buf);
#ifdef TCC_TARGET_PE
if (s->output_type == TCC_OUTPUT_DLL)
strcpy(ext, ".dll");
else
if (s->output_type == TCC_OUTPUT_EXE)
strcpy(ext, ".exe");
else
#endif
if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
strcpy(ext, ".o");
else
strcpy(buf, "a.out");
return tcc_strdup(buf);
}
static unsigned getclock_ms(void)
{
#ifdef _WIN32
return GetTickCount();
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
#endif
}
int main(int argc0, char **argv0)
{
TCCState *s, *s1;
int ret, opt, n = 0, t = 0, done;
unsigned start_time = 0;
const char *first_file;
int argc; char **argv;
FILE *ppfp = stdout;
redo:
argc = argc0, argv = argv0;
s = s1 = tcc_new();
opt = tcc_parse_args(s, &argc, &argv, 1);
if (n == 0) {
if (opt == OPT_HELP) {
fputs(help, stdout);
if (!s->verbose)
return 0;
++opt;
}
if (opt == OPT_HELP2) {
fputs(help2, stdout);
return 0;
}
if (opt == OPT_M32 || opt == OPT_M64)
tcc_tool_cross(s, argv, opt); /* never returns */
if (s->verbose)
printf(version);
if (opt == OPT_AR)
return tcc_tool_ar(s, argc, argv);
#ifdef TCC_TARGET_PE
if (opt == OPT_IMPDEF)
return tcc_tool_impdef(s, argc, argv);
#endif
if (opt == OPT_V)
return 0;
if (opt == OPT_PRINT_DIRS) {
/* initialize search dirs */
set_environment(s);
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
print_search_dirs(s);
return 0;
}
if (s->nb_files == 0)
tcc_error("no input files\n");
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
if (s->outfile && 0!=strcmp("-",s->outfile)) {
ppfp = fopen(s->outfile, "w");
if (!ppfp)
tcc_error("could not write '%s'", s->outfile);
}
} else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
if (s->nb_libraries)
tcc_error("cannot specify libraries with -c");
if (s->nb_files > 1 && s->outfile)
tcc_error("cannot specify output file with -c many files");
}
if (s->do_bench)
start_time = getclock_ms();
}
set_environment(s);
if (s->output_type == 0)
s->output_type = TCC_OUTPUT_EXE;
tcc_set_output_type(s, s->output_type);
s->ppfp = ppfp;
if ((s->output_type == TCC_OUTPUT_MEMORY
|| s->output_type == TCC_OUTPUT_PREPROCESS)
&& (s->dflag & 16)) { /* -dt option */
if (t)
s->dflag |= 32;
s->run_test = ++t;
if (n)
--n;
}
/* compile or add each files or library */
first_file = NULL, ret = 0;
do {
struct filespec *f = s->files[n];
s->filetype = f->type;
if (f->type & AFF_TYPE_LIB) {
if (tcc_add_library_err(s, f->name) < 0)
ret = 1;
} else {
if (1 == s->verbose)
printf("-> %s\n", f->name);
if (!first_file)
first_file = f->name;
if (tcc_add_file(s, f->name) < 0)
ret = 1;
}
done = ret || ++n >= s->nb_files;
} while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
if (s->run_test) {
t = 0;
} else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
;
} else if (0 == ret) {
if (s->output_type == TCC_OUTPUT_MEMORY) {
#ifdef TCC_IS_NATIVE
ret = tcc_run(s, argc, argv);
#endif
} else {
if (!s->outfile)
s->outfile = default_outputfile(s, first_file);
if (tcc_output_file(s, s->outfile))
ret = 1;
else if (s->gen_deps)
gen_makedeps(s, s->outfile, s->deps_outfile);
}
}
if (s->do_bench && done && !(t | ret))
tcc_print_stats(s, getclock_ms() - start_time);
tcc_delete(s);
if (!done)
goto redo; /* compile more files with -c */
if (t)
goto redo; /* run more tests with -dt -run */
if (ppfp && ppfp != stdout)
fclose(ppfp);
return ret;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/bokai-que/TCC.git
git@gitee.com:bokai-que/TCC.git
bokai-que
TCC
The Chinese Compiler 中文编译器
中文版

搜索帮助