Checkin tiny_libmaker (ar replacement) by Timovj Lahde

This commit is contained in:
grischka 2008-03-08 19:55:47 +00:00
parent 265dddbecf
commit 2eaa1104f7
7 changed files with 393 additions and 72 deletions

View file

@ -19,8 +19,10 @@ ifeq ($(GCC_MAJOR),2)
CFLAGS+=-m386 -malign-functions=0 CFLAGS+=-m386 -malign-functions=0
else else
CFLAGS+=-march=i386 -falign-functions=0 -fno-strict-aliasing CFLAGS+=-march=i386 -falign-functions=0 -fno-strict-aliasing
ifneq ($(GCC_MAJOR),3)
CFLAGS+=-Wno-pointer-sign -Wno-sign-compare CFLAGS+=-Wno-pointer-sign -Wno-sign-compare
endif endif
endif
DISAS=objdump -d DISAS=objdump -d
INSTALL=install INSTALL=install
@ -30,7 +32,7 @@ PROGS=tcc$(EXESUF)
ifdef CONFIG_CROSS ifdef CONFIG_CROSS
PROGS+=c67-tcc$(EXESUF) arm-tcc$(EXESUF) PROGS+=c67-tcc$(EXESUF) arm-tcc$(EXESUF)
endif endif
PROGS+=tiny_impdef$(EXESUF) PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
else else
ifeq ($(ARCH),i386) ifeq ($(ARCH),i386)
PROGS=tcc$(EXESUF) PROGS=tcc$(EXESUF)
@ -168,7 +170,9 @@ i386-win32-tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h
$(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS) $(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS)
# windows utilities # windows utilities
tiny_impdef$(EXESUF): tiny_impdef.c tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
$(CC) $(CFLAGS) -o $@ $< -lkernel32
tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
$(CC) $(CFLAGS) -o $@ $< -lkernel32 $(CC) $(CFLAGS) -o $@ $< -lkernel32
# TinyCC runtime libraries # TinyCC runtime libraries

13
configure vendored
View file

@ -183,6 +183,19 @@ gcc_major="2"
if $cc -o $TMPO $TMPC 2> /dev/null ; then if $cc -o $TMPO $TMPC 2> /dev/null ; then
gcc_major="3" gcc_major="3"
fi fi
cat > $TMPC <<EOF
int main(void) {
#if __GNUC__ >= 4
return 0;
#else
#error gcc < 4
#endif
}
EOF
if $cc -o $TMPO $TMPC 2> /dev/null ; then
gcc_major="4"
fi
if test x"$1" = x"-h" -o x"$1" = x"--help" ; then if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
cat << EOF cat << EOF

View file

@ -2,17 +2,14 @@
@rem batch file to build tcc using gcc and ar from mingw @rem batch file to build tcc using gcc and ar from mingw
@rem ---------------------------------------------------- @rem ----------------------------------------------------
: :
@if exist ..\config.h goto configready @echo>..\config.h #define TCC_VERSION "0.9.24"
:
@echo>..\config.h #define TCC_VERSION "0.9.24pre"
@echo>>..\config.h #define TCC_TARGET_PE 1 @echo>>..\config.h #define TCC_TARGET_PE 1
@echo>>..\config.h #define CONFIG_TCCDIR NULL @echo>>..\config.h #define CONFIG_TCCDIR NULL
: :
:configready
:
gcc -Os -fno-strict-aliasing ../tcc.c -o tcc.exe -s gcc -Os -fno-strict-aliasing ../tcc.c -o tcc.exe -s
gcc -Os -fno-strict-aliasing ../tcc.c -D LIBTCC -c -o libtcc.o gcc -Os -fno-strict-aliasing ../tcc.c -D LIBTCC -c -o libtcc.o
gcc -Os -fno-strict-aliasing ../tiny_impdef.c -o tiny_impdef.exe -s gcc -Os tools/tiny_impdef.c -o tiny_impdef.exe -s
gcc -Os tools/tiny_libmaker.c -o tiny_libmaker.exe -s
mkdir libtcc mkdir libtcc
ar rcs libtcc/libtcc.a libtcc.o ar rcs libtcc/libtcc.a libtcc.o
del libtcc.o del libtcc.o

View file

@ -32,13 +32,12 @@
#define __MINGW32_MAJOR_VERSION 2 #define __MINGW32_MAJOR_VERSION 2
#define __MINGW32_MINOR_VERSION 0 #define __MINGW32_MINOR_VERSION 0
#define __MSVCRT__ #define __MSVCRT__ 1
#define __MINGW_IMPORT extern #define __MINGW_IMPORT extern
#define _CRTIMP #define _CRTIMP
#define __CRT_INLINE extern __inline__ #define __CRT_INLINE extern __inline__
#define _WIN32 #define WIN32 1
#define WIN32
#ifndef _WINT_T #ifndef _WINT_T
#define _WINT_T #define _WINT_T
@ -46,7 +45,8 @@ typedef unsigned int wint_t;
#endif #endif
/* for winapi */ /* for winapi */
#define NONAMELESSUNION #define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#define DECLSPEC_NORETURN #define DECLSPEC_NORETURN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define DECLARE_STDCALL_P(type) __stdcall type #define DECLARE_STDCALL_P(type) __stdcall type

View file

@ -1,37 +1,34 @@
TinyCC-PE TinyCC
======
This file contains some additional information for usage of TinyCC
under MS-Windows:
Overview:
--------- ---------
TinyCC (aka TCC) is a small but hyperfast C compiler, written by
Fabrice Bellard.
TinyCC (aka TCC) is a small but hyperfast C compiler, TinyCC for MS-Windows can produce console applications, native
written by Fabrice Bellard, windows GUI programs and DLL's.
The package with under 300kb includes a complete C-compiler with
header files and basic system library support.
TinyCC-PE is the TinyCC compiler with an extension to With the -run switch you can run C-sources without any linking
write PE executables for MS-Windows. directly from the command line.
TinyCC can be used as dynamic code generator library in your own
program.
Features: TinyCC can of course compile itself.
---------
TinyCC-PE can produce console applications, native windows
GUI programs and DLL's.
Most of the features pointed out by Fabrice Bellard for the
original version are still valid, i.e:
- SMALL! The package with ~400kb includes a complete C-compiler
with header files for console and GUI applications.
- With the -run switch you can run C-sources without any
linking directly from the command line.
- TCC can of course compile itself.
Compilation: (omit that if you use the binary ZIP package) Compilation: (omit that if you use the binary ZIP package)
------------ ------------
You can use the MinGW and MSYS tools available at
You must use the MinGW and MSYS tools available at
http://www.mingw.org to compile TCC for Windows. Untar the TCC http://www.mingw.org to compile TCC for Windows. Untar the TCC
archive and type in the MSYS shell: archive and type in the MSYS shell:
@ -48,13 +45,14 @@
Installation: (from the binary ZIP package) Installation: (from the binary ZIP package)
------------- -------------
Just unzip the package to a directory anywhere on your computer. Just unzip the package to a directory anywhere on your computer.
The binary package does not include libtcc. If you want tcc as
dynamic code generator, please use the source code distribution.
Examples: Examples:
--------- ---------
For the 'Fibonacci' console example type from the command line: For the 'Fibonacci' console example type from the command line:
tcc examples\fib.c tcc examples\fib.c
@ -69,25 +67,22 @@
tcc examples\hello_dll.c examples\dll.def tcc examples\hello_dll.c examples\dll.def
Import Definitions: Import Definition Files:
------------------- ------------------------
To link with Windows system DLLs, TinyCC uses import definition
files (.def) instead of libraries.
TinyCC-PE searches and reads import definition files similar The included 'tiny_impdef' program may be used to make additional
to libraries. .def files for any DLL. For example:
The included 'tiny_impdef' program may be used to make .def files
for any DLL, e.g for an 'opengl32.def':
tiny_impdef.exe opengl32.dll tiny_impdef.exe opengl32.dll
or to the same effect: To use it, put the opengl32.def file into the tcc/lib directory,
and specify -lopengl32 at the tcc commandline.
tcc -run tiny_impdef.c opengl32.dll
Resource Files: Resource Files:
--------------- ---------------
TinyCC-PE can now link windows resources in coff format as generated TinyCC-PE can now link windows resources in coff format as generated
by MINGW's windres.exe. For example: by MINGW's windres.exe. For example:
@ -95,32 +90,25 @@
tcc app.c appres.o -o app.exe tcc app.c appres.o -o app.exe
Tiny Libmaker:
--------------
The included tiny_libmaker tool by Timovj Lahde can be used as
'ar' replacement to make a library from several object files.
Header Files: Header Files:
------------- -------------
The system header files (except _mingw.h) are from the mingw
The system header files, except '_mingw.h', are from the distribution (http://www.mingw.org/).
3.7 mingw distribution. See also: http://www.mingw.org/
Compile TCC:
------------
With TCC itself just say:
tcc src\tcc.c -o tcc.new.exe
Other compilers like mingw-gcc or msvc work as well.
To make libtcc1.a, you need 'ar' from the mingw binutils.
Documentation and License: Documentation and License:
-------------------------- --------------------------
TCC is distributed under the GNU Lesser General Public License TCC is distributed under the GNU Lesser General Public License
(see COPYING file). (see COPYING file).
Please read the original tcc-doc.html to have all the features Please read tcc-doc.html to have all the features of TCC. Also
of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/ visit: http://fabrice.bellard.free.fr/tcc/
--
grischka@users.sourceforge.net -- grischka@users.sourceforge.net

319
win32/tools/tiny_libmaker.c Normal file
View file

@ -0,0 +1,319 @@
/*
* This program is for making libtcc1.a without ar
* tiny_libmaker - tiny elf lib maker
* usage: tiny_libmaker [lib] files...
* Copyright (c) 2007 Timppa
*
* This program is free software but WITHOUT ANY WARRANTY
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* #include "ar-elf.h" */
/* "ar-elf.h" */
/* ELF_v1.2.pdf */
typedef unsigned short int Elf32_Half;
typedef int Elf32_Sword;
typedef unsigned int Elf32_Word;
typedef unsigned int Elf32_Addr;
typedef unsigned int Elf32_Off;
typedef unsigned short int Elf32_Section;
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
} Elf32_Sym;
#define ELF32_ST_BIND(i) ((i)>>4)
#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_LOPROC 13
#define STT_HIPROC 15
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOPROC 13
#define STB_HIPROC 15
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
/* "ar-elf.h" ends */
#define ARMAG "!<arch>\n"
#define ARFMAG "`\n"
typedef struct ArHdr {
char ar_name[16];
char ar_date[12];
char ar_uid[6];
char ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];
} ArHdr;
unsigned long le2belong(unsigned long ul) {
return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
}
ArHdr arhdr = {
"/ ",
" ",
"0 ",
"0 ",
"0 ",
" ",
ARFMAG
};
ArHdr arhdro = {
" ",
" ",
"0 ",
"0 ",
"0 ",
" ",
ARFMAG
};
int main(int argc, char **argv)
{
FILE *fi, *fh, *fo;
Elf32_Ehdr *ehdr;
Elf32_Shdr *shdr;
Elf32_Sym *sym;
int i, fsize, iarg;
char *buf, *shstr, *symtab = NULL, *strtab = NULL;
int symtabsize = 0, strtabsize = 0;
char *anames = NULL;
int *afpos = NULL;
int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
char afile[260], tfile[260], stmp[20];
strcpy(afile, "ar_test.a");
iarg = 1;
if (argc < 2)
{
printf("usage: tiny_libmaker [lib] file...\n");
return 1;
}
for (i=1; i<argc; i++) {
istrlen = strlen(argv[i]);
if (argv[i][istrlen-2] == '.') {
if(argv[i][istrlen-1] == 'a')
strcpy(afile, argv[i]);
else if(argv[i][istrlen-1] == 'o') {
iarg = i;
break;
}
}
}
//tfile[0] = '.'; tfile[1] = '/';
//if (tmpnam(&tfile[2])) {
strcpy(tfile, "./XXXXXX");
if (mktemp(tfile))
{
if ((fo = fopen(tfile, "wb+")) == NULL)
{
fprintf(stderr, "Can't open file %s \n", tfile);
return 2;
}
}
/*
if ((fo = tmpfile()) == NULL)
{
fprintf(stderr, "Can't open temporary file \n");
return 2;
}
*/
if ((fh = fopen(afile, "wb")) == NULL)
{
fprintf(stderr, "Can't open file %s \n", afile);
remove(tfile);
return 2;
}
funcmax = 1000;
afpos = realloc(NULL, funcmax); // 250 func
memcpy(&arhdro.ar_mode, "100666", 6);
//iarg = 1;
while (iarg < argc)
{
if (!strcmp(argv[iarg], "rcs")) {
iarg++;
continue;
}
if ((fi = fopen(argv[iarg], "rb")) == NULL)
{
fprintf(stderr, "Can't open file %s \n", argv[iarg]);
remove(tfile);
return 2;
}
fseek(fi, 0, SEEK_END);
fsize = ftell(fi);
fseek(fi, 0, SEEK_SET);
buf = malloc(fsize + 1);
fread(buf, fsize, 1, fi);
fclose(fi);
printf("%s:\n", argv[iarg]);
// elf header
ehdr = (Elf32_Ehdr *)buf;
shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
shstr = (char *)(buf + shdr->sh_offset);
for (i = 0; i < ehdr->e_shnum; i++)
{
shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
if (!shdr->sh_offset) continue;
if (shdr->sh_type == SHT_SYMTAB)
{
symtab = (char *)(buf + shdr->sh_offset);
symtabsize = shdr->sh_size;
}
if (shdr->sh_type == SHT_STRTAB)
{
if (!strcmp(shstr + shdr->sh_name, ".strtab"))
{
strtab = (char *)(buf + shdr->sh_offset);
strtabsize = shdr->sh_size;
}
}
}
if (symtab && symtabsize)
{
int nsym = symtabsize / sizeof(Elf32_Sym);
//printf("symtab: info size shndx name\n");
for (i = 1; i < nsym; i++)
{
sym = (Elf32_Sym *) (symtab + i * sizeof(Elf32_Sym));
if (sym->st_shndx && (sym->st_info == 0x11 || sym->st_info == 0x12)) {
//printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
istrlen = strlen(strtab + sym->st_name)+1;
anames = realloc(anames, strpos+istrlen);
strcpy(anames + strpos, strtab + sym->st_name);
strpos += istrlen;
if (funccnt >= funcmax) {
afpos = realloc(NULL, funcmax+1000); // 250 func more
funcmax += 1000;
}
afpos[++funccnt] = fpos;
}
}
}
memset(&arhdro.ar_name, ' ', sizeof(arhdr.ar_name));
strcpy(arhdro.ar_name, argv[iarg]);
arhdro.ar_name[strlen(argv[iarg])] = '/';
sprintf(stmp, "%-10d", fsize);
memcpy(&arhdro.ar_size, stmp, 10);
fwrite(&arhdro, sizeof(arhdro), 1, fo);
fwrite(buf, fsize, 1, fo);
free(buf);
iarg++;
fpos += (fsize + sizeof(arhdro));
}
hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
if ((hofs & 1)) { // align
hofs++;
fpos = 1;
} else fpos = 0;
// write header
fwrite("!<arch>\n", 8, 1, fh);
sprintf(stmp, "%-10d", strpos + (funccnt+1) * sizeof(int));
memcpy(&arhdr.ar_size, stmp, 10);
fwrite(&arhdr, sizeof(arhdr), 1, fh);
afpos[0] = le2belong(funccnt);
for (i=1; i<=funccnt; i++) {
afpos[i] = le2belong(afpos[i] + hofs);
}
fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
fwrite(anames, strpos, 1, fh);
if (fpos) fwrite("", 1, 1, fh);
// write objects
fseek(fo, 0, SEEK_END);
fsize = ftell(fo);
fseek(fo, 0, SEEK_SET);
buf = malloc(fsize + 1);
fread(buf, fsize, 1, fo);
fclose(fo);
fwrite(buf, fsize, 1, fh);
fclose(fh);
free(buf);
if (anames)
free(anames);
if (afpos)
free(afpos);
remove(tfile);
return 0;
}