Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a328834f
Commit
a328834f
authored
May 30, 2009
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebuild: Add a --resources mode that compiles multiple resource files into a single object.
parent
a37b8f79
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
175 additions
and
6 deletions
+175
-6
build.h
tools/winebuild/build.h
+2
-0
main.c
tools/winebuild/main.c
+12
-1
res32.c
tools/winebuild/res32.c
+133
-5
utils.c
tools/winebuild/utils.c
+21
-0
winebuild.man.in
tools/winebuild/winebuild.man.in
+7
-0
No files found.
tools/winebuild/build.h
View file @
a328834f
...
...
@@ -205,6 +205,7 @@ extern int output( const char *format, ... )
extern
const
char
*
get_as_command
(
void
);
extern
const
char
*
get_ld_command
(
void
);
extern
const
char
*
get_nm_command
(
void
);
extern
const
char
*
get_windres_command
(
void
);
extern
char
*
get_temp_file_name
(
const
char
*
prefix
,
const
char
*
suffix
);
extern
void
output_standard_file_header
(
void
);
extern
FILE
*
open_input_file
(
const
char
*
srcdir
,
const
char
*
name
);
...
...
@@ -250,6 +251,7 @@ extern void load_res16_file( const char *name, DLLSPEC *spec );
extern
void
output_res16_data
(
DLLSPEC
*
spec
);
extern
void
output_res16_directory
(
DLLSPEC
*
spec
);
extern
void
output_spec16_file
(
DLLSPEC
*
spec
);
extern
void
output_res_o_file
(
DLLSPEC
*
spec
);
extern
void
BuildRelays16
(
void
);
extern
void
BuildRelays32
(
void
);
...
...
tools/winebuild/main.c
View file @
a328834f
...
...
@@ -96,7 +96,8 @@ enum exec_mode_values
MODE_EXE
,
MODE_DEF
,
MODE_RELAY16
,
MODE_RELAY32
MODE_RELAY32
,
MODE_RESOURCES
};
static
enum
exec_mode_values
exec_mode
=
MODE_NONE
;
...
...
@@ -243,6 +244,7 @@ static const char usage_str[] =
" --exe Build a .c file for an executable
\n
"
" --relay16 Build the 16-bit relay assembly routines
\n
"
" --relay32 Build the 32-bit relay assembly routines
\n\n
"
" --resources Build a .o file for the resource files
\n\n
"
"The mode options are mutually exclusive; you must specify one and only one.
\n\n
"
;
enum
long_options_values
...
...
@@ -257,6 +259,7 @@ enum long_options_values
LONG_OPT_NXCOMPAT
,
LONG_OPT_RELAY16
,
LONG_OPT_RELAY32
,
LONG_OPT_RESOURCES
,
LONG_OPT_SAVE_TEMPS
,
LONG_OPT_SUBSYSTEM
,
LONG_OPT_VERSION
...
...
@@ -276,6 +279,7 @@ static const struct option long_options[] =
{
"nxcompat"
,
1
,
0
,
LONG_OPT_NXCOMPAT
},
{
"relay16"
,
0
,
0
,
LONG_OPT_RELAY16
},
{
"relay32"
,
0
,
0
,
LONG_OPT_RELAY32
},
{
"resources"
,
0
,
0
,
LONG_OPT_RESOURCES
},
{
"save-temps"
,
0
,
0
,
LONG_OPT_SAVE_TEMPS
},
{
"subsystem"
,
1
,
0
,
LONG_OPT_SUBSYSTEM
},
{
"version"
,
0
,
0
,
LONG_OPT_VERSION
},
...
...
@@ -463,6 +467,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case
LONG_OPT_RELAY32
:
set_exec_mode
(
MODE_RELAY32
);
break
;
case
LONG_OPT_RESOURCES
:
set_exec_mode
(
MODE_RESOURCES
);
break
;
case
LONG_OPT_SAVE_TEMPS
:
save_temps
=
1
;
break
;
...
...
@@ -621,6 +628,10 @@ int main(int argc, char **argv)
if
(
argv
[
0
])
fatal_error
(
"file argument '%s' not allowed in this mode
\n
"
,
argv
[
0
]
);
BuildRelays32
();
break
;
case
MODE_RESOURCES
:
load_resources
(
argv
,
spec
);
output_res_o_file
(
spec
);
break
;
default:
usage
(
1
);
break
;
...
...
tools/winebuild/res32.c
View file @
a328834f
...
...
@@ -21,6 +21,7 @@
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -55,6 +56,7 @@ struct resource
struct
string_id
name
;
const
void
*
data
;
unsigned
int
data_size
;
unsigned
short
mem_options
;
unsigned
short
lang
;
};
...
...
@@ -89,6 +91,9 @@ static const unsigned char *file_pos; /* current position in resource file */
static
const
unsigned
char
*
file_end
;
/* end of resource file */
static
const
char
*
file_name
;
/* current resource file name */
static
unsigned
char
*
file_out_pos
;
/* current position in output resource file */
static
unsigned
char
*
file_out_end
;
/* end of output buffer */
/* size of a resource directory with n entries */
#define RESOURCE_DIR_SIZE (4 * sizeof(unsigned int))
#define RESOURCE_DIR_ENTRY_SIZE (2 * sizeof(unsigned int))
...
...
@@ -178,6 +183,41 @@ static void get_string( struct string_id *str )
}
}
/* put a word into the resource file */
static
void
put_word
(
unsigned
short
val
)
{
if
(
byte_swapped
)
val
=
(
val
<<
8
)
|
(
val
>>
8
);
*
(
unsigned
short
*
)
file_out_pos
=
val
;
file_out_pos
+=
sizeof
(
unsigned
short
);
assert
(
file_out_pos
<=
file_out_end
);
}
/* put a dword into the resource file */
static
void
put_dword
(
unsigned
int
val
)
{
if
(
byte_swapped
)
val
=
((
val
<<
24
)
|
((
val
<<
8
)
&
0x00ff0000
)
|
((
val
>>
8
)
&
0x0000ff00
)
|
(
val
>>
24
));
*
(
unsigned
int
*
)
file_out_pos
=
val
;
file_out_pos
+=
sizeof
(
unsigned
int
);
assert
(
file_out_pos
<=
file_out_end
);
}
/* put a string into the resource file */
static
void
put_string
(
const
struct
string_id
*
str
)
{
if
(
str
->
str
)
{
const
WCHAR
*
p
=
str
->
str
;
while
(
*
p
)
put_word
(
*
p
++
);
put_word
(
0
);
}
else
{
put_word
(
0xffff
);
put_word
(
str
->
id
);
}
}
/* check the file header */
/* all values must be zero except header size */
static
int
check_header
(
void
)
...
...
@@ -204,7 +244,7 @@ static void load_next_resource( DLLSPEC *spec )
unsigned
int
hdr_size
;
struct
resource
*
res
=
add_resource
(
spec
);
res
->
data_size
=
(
get_dword
()
+
3
)
&
~
3
;
res
->
data_size
=
get_dword
()
;
hdr_size
=
get_dword
();
if
(
hdr_size
&
3
)
fatal_error
(
"%s header size not aligned
\n
"
,
file_name
);
...
...
@@ -213,12 +253,12 @@ static void load_next_resource( DLLSPEC *spec )
get_string
(
&
res
->
name
);
if
((
unsigned
long
)
file_pos
&
2
)
get_word
();
/* align to dword boundary */
get_dword
();
/* skip data version */
get_word
();
/* skip mem options */
res
->
mem_options
=
get_word
();
res
->
lang
=
get_word
();
get_dword
();
/* skip version */
get_dword
();
/* skip characteristics */
file_pos
=
(
const
unsigned
char
*
)
res
->
data
+
res
->
data_size
;
file_pos
=
(
const
unsigned
char
*
)
res
->
data
+
((
res
->
data_size
+
3
)
&
~
3
)
;
if
(
file_pos
>
file_end
)
fatal_error
(
"%s is a truncated file
\n
"
,
file_name
);
}
...
...
@@ -441,7 +481,7 @@ void output_resources( DLLSPEC *spec )
for
(
i
=
0
,
res
=
spec
->
resources
;
i
<
spec
->
nb_resources
;
i
++
,
res
++
)
output
(
"
\t
.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0
\n
"
,
i
,
res
->
data_size
);
i
,
(
res
->
data_size
+
3
)
&
~
3
);
/* dump the name strings */
...
...
@@ -458,10 +498,98 @@ void output_resources( DLLSPEC *spec )
{
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
".L__wine_spec_res_%d:
\n
"
,
i
);
dump_bytes
(
res
->
data
,
res
->
data_size
);
dump_bytes
(
res
->
data
,
(
res
->
data_size
+
3
)
&
~
3
);
}
output
(
".L__wine_spec_resources_end:
\n
"
);
output
(
"
\t
.byte 0
\n
"
);
free_resource_tree
(
tree
);
}
static
unsigned
int
get_resource_header_size
(
const
struct
resource
*
res
)
{
unsigned
int
size
=
5
*
sizeof
(
unsigned
int
)
+
2
*
sizeof
(
unsigned
short
);
if
(
!
res
->
type
.
str
)
size
+=
2
*
sizeof
(
unsigned
short
);
else
size
+=
(
strlenW
(
res
->
type
.
str
)
+
1
)
*
sizeof
(
WCHAR
);
if
(
!
res
->
name
.
str
)
size
+=
2
*
sizeof
(
unsigned
short
);
else
size
+=
(
strlenW
(
res
->
name
.
str
)
+
1
)
*
sizeof
(
WCHAR
);
return
size
;
}
/* output the resources into a .o file */
void
output_res_o_file
(
DLLSPEC
*
spec
)
{
unsigned
int
i
,
total_size
;
unsigned
char
*
data
;
char
*
res_file
,
*
cmd
;
const
char
*
prog
;
int
fd
,
err
;
if
(
!
spec
->
nb_resources
)
fatal_error
(
"--resources mode needs at least one resource file as input
\n
"
);
if
(
!
output_file_name
)
fatal_error
(
"No output file name specified
\n
"
);
total_size
=
32
;
/* header */
for
(
i
=
0
;
i
<
spec
->
nb_resources
;
i
++
)
{
total_size
+=
(
get_resource_header_size
(
&
spec
->
resources
[
i
]
)
+
3
)
&
~
3
;
total_size
+=
(
spec
->
resources
[
i
].
data_size
+
3
)
&
~
3
;
}
data
=
xmalloc
(
total_size
);
byte_swapped
=
0
;
file_out_pos
=
data
;
file_out_end
=
data
+
total_size
;
put_dword
(
0
);
/* ResSize */
put_dword
(
32
);
/* HeaderSize */
put_word
(
0xffff
);
/* ResType */
put_word
(
0x0000
);
put_word
(
0xffff
);
/* ResName */
put_word
(
0x0000
);
put_dword
(
0
);
/* DataVersion */
put_word
(
0
);
/* Memory options */
put_word
(
0
);
/* Language */
put_dword
(
0
);
/* Version */
put_dword
(
0
);
/* Characteristics */
for
(
i
=
0
;
i
<
spec
->
nb_resources
;
i
++
)
{
unsigned
int
header_size
=
get_resource_header_size
(
&
spec
->
resources
[
i
]
);
put_dword
(
spec
->
resources
[
i
].
data_size
);
put_dword
(
header_size
);
put_string
(
&
spec
->
resources
[
i
].
type
);
put_string
(
&
spec
->
resources
[
i
].
name
);
if
((
unsigned
long
)
file_out_pos
&
2
)
put_word
(
0
);
put_dword
(
0
);
put_word
(
spec
->
resources
[
i
].
mem_options
);
put_word
(
spec
->
resources
[
i
].
lang
);
put_dword
(
0
);
put_dword
(
0
);
memcpy
(
file_out_pos
,
spec
->
resources
[
i
].
data
,
spec
->
resources
[
i
].
data_size
);
file_out_pos
+=
spec
->
resources
[
i
].
data_size
;
while
((
unsigned
long
)
file_out_pos
&
3
)
*
file_out_pos
++
=
0
;
}
assert
(
file_out_pos
==
file_out_end
);
res_file
=
get_temp_file_name
(
output_file_name
,
".res"
);
if
((
fd
=
open
(
res_file
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0600
))
==
-
1
)
fatal_error
(
"Cannot create %s
\n
"
,
res_file
);
if
(
write
(
fd
,
data
,
total_size
)
!=
total_size
)
fatal_error
(
"Error writing to %s
\n
"
,
res_file
);
close
(
fd
);
free
(
data
);
prog
=
get_windres_command
();
cmd
=
xmalloc
(
strlen
(
prog
)
+
strlen
(
res_file
)
+
strlen
(
output_file_name
)
+
9
);
sprintf
(
cmd
,
"%s -i %s -o %s"
,
prog
,
res_file
,
output_file_name
);
if
(
verbose
)
fprintf
(
stderr
,
"%s
\n
"
,
cmd
);
err
=
system
(
cmd
);
if
(
err
)
fatal_error
(
"%s failed with status %d
\n
"
,
prog
,
err
);
free
(
cmd
);
output_file_name
=
NULL
;
/* so we don't try to assemble it */
}
tools/winebuild/utils.c
View file @
a328834f
...
...
@@ -319,6 +319,27 @@ const char *get_nm_command(void)
return
nm_command
;
}
const
char
*
get_windres_command
(
void
)
{
static
char
*
windres_command
;
if
(
!
windres_command
)
{
if
(
target_alias
)
{
windres_command
=
xmalloc
(
strlen
(
target_alias
)
+
sizeof
(
"-windres"
)
);
strcpy
(
windres_command
,
target_alias
);
strcat
(
windres_command
,
"-windres"
);
}
else
{
static
const
char
*
const
commands
[]
=
{
"windres"
,
NULL
};
if
(
!
(
windres_command
=
find_tool
(
commands
)))
windres_command
=
xstrdup
(
"windres"
);
}
}
return
windres_command
;
}
/* get a name for a temp file, automatically cleaned up on exit */
char
*
get_temp_file_name
(
const
char
*
prefix
,
const
char
*
suffix
)
{
...
...
tools/winebuild/winebuild.man.in
View file @
a328834f
...
...
@@ -53,6 +53,13 @@ Wine internal usage only, you should never need to use this option.
.B \--relay32
Generate the assembly code for the 32-bit relay routines. This is for
Wine internal usage only, you should never need to use this option.
.TP
.B \--resources
Generate a .o file containing all the input resources. This is useful
when building with a PE compiler, since the PE binutils cannot handle
multiple resource files as input. For a standard Unix build, the
resource files are automatically included when building the spec file,
so there's no need for an intermediate .o file.
.SH OPTIONS
.TP
.BI \--as-cmd= as-command
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment