Commit b613ee7a authored by Dimitrie O. Paun's avatar Dimitrie O. Paun Committed by Alexandre Julliard

First cut at -shared support.

parent d81e8db3
...@@ -221,7 +221,8 @@ file_type get_file_type(const char* filename) ...@@ -221,7 +221,8 @@ file_type get_file_type(const char* filename)
if (strendswith(filename, ".res")) return file_res; if (strendswith(filename, ".res")) return file_res;
if (strendswith(filename, ".so")) return file_so; if (strendswith(filename, ".so")) return file_so;
if (strendswith(filename, ".dylib")) return file_so; if (strendswith(filename, ".dylib")) return file_so;
if (strendswith(filename, ".def")) return file_dll; if (strendswith(filename, ".def")) return file_def;
if (strendswith(filename, ".spec")) return file_spec;
if (strendswith(filename, ".rc")) return file_rc; if (strendswith(filename, ".rc")) return file_rc;
return file_other; return file_other;
...@@ -254,9 +255,9 @@ static file_type guess_lib_type(const char* dir, const char* library, char** fil ...@@ -254,9 +255,9 @@ static file_type guess_lib_type(const char* dir, const char* library, char** fil
return file_so; return file_so;
/* Windows DLL */ /* Windows DLL */
if ((*file = try_lib_path(dir, "lib", library, ".def", file_dll))) if ((*file = try_lib_path(dir, "lib", library, ".def", file_def)))
return file_dll; return file_dll;
if ((*file = try_lib_path(dir, "", library, ".def", file_dll))) if ((*file = try_lib_path(dir, "", library, ".def", file_def)))
return file_dll; return file_dll;
/* Unix static archives */ /* Unix static archives */
......
...@@ -54,8 +54,8 @@ strarray* strarray_fromstring(const char* str, const char* delim); ...@@ -54,8 +54,8 @@ strarray* strarray_fromstring(const char* str, const char* delim);
char* strarray_tostring(const strarray* arr, const char* sep); char* strarray_tostring(const strarray* arr, const char* sep);
typedef enum { typedef enum {
file_na, file_other, file_obj, file_res, file_na, file_other, file_obj, file_res, file_rc,
file_rc, file_arh, file_dll, file_so file_arh, file_dll, file_so, file_def, file_spec
} file_type; } file_type;
char* get_basename(const char* file); char* get_basename(const char* file);
......
...@@ -153,6 +153,7 @@ static strarray* tmp_files; ...@@ -153,6 +153,7 @@ static strarray* tmp_files;
struct options struct options
{ {
enum { proc_cc = 0, proc_cxx = 1, proc_cpp = 2} processor; enum { proc_cc = 0, proc_cxx = 1, proc_cpp = 2} processor;
int shared;
int use_msvcrt; int use_msvcrt;
int nostdinc; int nostdinc;
int nostdlib; int nostdlib;
...@@ -345,9 +346,9 @@ static void build(struct options* opts) ...@@ -345,9 +346,9 @@ static void build(struct options* opts)
static const char *stdlibpath[] = { DLLDIR, LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" }; static const char *stdlibpath[] = { DLLDIR, LIBDIR, "/usr/lib", "/usr/local/lib", "/lib" };
strarray *lib_dirs, *files; strarray *lib_dirs, *files;
strarray *spec_args, *comp_args, *link_args; strarray *spec_args, *comp_args, *link_args;
char *base_file, *base_name; char *output_file;
const char *spec_c_name, *spec_o_name; const char *spec_c_name, *spec_o_name;
const char* output_name; const char *output_name, *spec_file, *def_ext;
const char* winebuild = getenv("WINEBUILD"); const char* winebuild = getenv("WINEBUILD");
int generate_app_loader = 1; int generate_app_loader = 1;
int j; int j;
...@@ -363,35 +364,40 @@ static void build(struct options* opts) ...@@ -363,35 +364,40 @@ static void build(struct options* opts)
if (!winebuild) winebuild = "winebuild"; if (!winebuild) winebuild = "winebuild";
output_name = opts->output_name ? opts->output_name : "a.out"; output_file = strdup( opts->output_name ? opts->output_name : "a.out" );
/* get base filename by removing the .exe extension, if present */
base_file = strdup(output_name);
if (strendswith(base_file, ".exe.so"))
{
base_file[strlen(base_file) - 7] = 0;
generate_app_loader = 0;
}
else if (strendswith(base_file, ".exe")) base_file[strlen(base_file) - 4] = 0;
if ((base_name = strrchr(base_file, '/'))) base_name++;
else base_name = base_file;
/* 'winegcc -o app xxx.exe.so' only creates the load script */ /* 'winegcc -o app xxx.exe.so' only creates the load script */
if (opts->files->size == 1 && strendswith(opts->files->base[0], ".exe.so")) if (opts->files->size == 1 && strendswith(opts->files->base[0], ".exe.so"))
{ {
create_file(base_file, 0755, app_loader_template, opts->files->base[0]); create_file(output_file, 0755, app_loader_template, opts->files->base[0]);
return; return;
} }
/* generate app loader only for .exe */
if (opts->shared || strendswith(output_file, ".exe.so"))
generate_app_loader = 0;
/* normalize the filename a bit: strip .so, ensure it has proper ext */
def_ext = opts->shared ? ".dll" : ".exe";
if (strendswith(output_file, ".so"))
output_file[strlen(output_file) - 3] = 0;
if(!strendswith(output_file, def_ext))
output_file = strmake("%s%s", output_file, def_ext);
/* get the filename by the path, if present */
if ((output_name = strrchr(output_file, '/'))) output_name++;
else output_name = output_file;
/* prepare the linking path */ /* prepare the linking path */
lib_dirs = strarray_dup(opts->lib_dirs); lib_dirs = strarray_dup(opts->lib_dirs);
if (!opts->wine_mode) if (!opts->wine_mode)
{ {
for ( j = 0; j < sizeof(stdlibpath)/sizeof(stdlibpath[0]);j++ ) for ( j = 0; j < sizeof(stdlibpath)/sizeof(stdlibpath[0]); j++ )
strarray_add(lib_dirs, stdlibpath[j]); strarray_add(lib_dirs, stdlibpath[j]);
} }
/* mark the files with their appropriate type */ /* mark the files with their appropriate type */
spec_file = 0;
files = strarray_alloc(); files = strarray_alloc();
for ( j = 0; j < opts->files->size; j++ ) for ( j = 0; j < opts->files->size; j++ )
{ {
...@@ -400,6 +406,14 @@ static void build(struct options* opts) ...@@ -400,6 +406,14 @@ static void build(struct options* opts)
{ {
switch(get_file_type(file)) switch(get_file_type(file))
{ {
case file_def:
case file_spec:
if (!opts->shared)
error("Spec file %s not supported in non-shared mode", file);
if (spec_file)
error("Only one spec file can be specified in shared mode");
spec_file = file;
break;
case file_rc: case file_rc:
/* FIXME: invoke wrc to build it */ /* FIXME: invoke wrc to build it */
error("Can't compile .rc file at the moment: %s", file); error("Can't compile .rc file at the moment: %s", file);
...@@ -441,6 +455,8 @@ static void build(struct options* opts) ...@@ -441,6 +455,8 @@ static void build(struct options* opts)
free(fullname); free(fullname);
} }
} }
if (opts->shared && !spec_file)
error("A spec file is currently needed in shared mode");
/* add the default libraries, if needed */ /* add the default libraries, if needed */
if (!opts->nostdlib) if (!opts->nostdlib)
...@@ -463,13 +479,21 @@ static void build(struct options* opts) ...@@ -463,13 +479,21 @@ static void build(struct options* opts)
/* run winebuild to generate the .spec.c file */ /* run winebuild to generate the .spec.c file */
spec_args = strarray_alloc(); spec_args = strarray_alloc();
spec_c_name = get_temp_file(base_name, ".spec.c"); spec_c_name = get_temp_file(output_name, ".spec.c");
strarray_add(spec_args, winebuild); strarray_add(spec_args, winebuild);
strarray_add(spec_args, "-o"); strarray_add(spec_args, "-o");
strarray_add(spec_args, spec_c_name); strarray_add(spec_args, spec_c_name);
strarray_add(spec_args, "--exe"); if (opts->shared)
strarray_add(spec_args, strmake("%s.exe", base_name)); {
strarray_add(spec_args, opts->gui_app ? "-mgui" : "-mcui"); strarray_add(spec_args, "--dll");
strarray_add(spec_args, spec_file);
}
else
{
strarray_add(spec_args, "--exe");
strarray_add(spec_args, output_name);
strarray_add(spec_args, opts->gui_app ? "-mgui" : "-mcui");
}
for ( j = 0; j < lib_dirs->size; j++ ) for ( j = 0; j < lib_dirs->size; j++ )
strarray_add(spec_args, strmake("-L%s", lib_dirs->base[j])); strarray_add(spec_args, strmake("-L%s", lib_dirs->base[j]));
...@@ -507,7 +531,7 @@ static void build(struct options* opts) ...@@ -507,7 +531,7 @@ static void build(struct options* opts)
strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " ")); strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " "));
strarray_add(link_args, "-o"); strarray_add(link_args, "-o");
strarray_add(link_args, strmake("%s.exe.so", base_file)); strarray_add(link_args, strmake("%s.so", output_file));
for ( j = 0 ; j < opts->linker_args->size ; j++ ) for ( j = 0 ; j < opts->linker_args->size ; j++ )
strarray_add(link_args, opts->linker_args->base[j]); strarray_add(link_args, opts->linker_args->base[j]);
...@@ -544,7 +568,10 @@ static void build(struct options* opts) ...@@ -544,7 +568,10 @@ static void build(struct options* opts)
/* create the loader script */ /* create the loader script */
if (generate_app_loader) if (generate_app_loader)
create_file(base_file, 0755, app_loader_template, strmake("%s.exe.so", base_name)); {
if (strendswith(output_file, ".exe")) output_file[strlen(output_file) - 4] = 0;
create_file(output_file, 0755, app_loader_template, strmake("%s.so", output_name));
}
} }
...@@ -775,6 +802,11 @@ int main(int argc, char **argv) ...@@ -775,6 +802,11 @@ int main(int argc, char **argv)
linking = -1; linking = -1;
else if(strcmp("-save-temps", argv[i]) == 0) else if(strcmp("-save-temps", argv[i]) == 0)
keep_generated = 1; keep_generated = 1;
else if(strcmp("-shared", argv[i]) == 0)
{
opts.shared = 1;
raw_compiler_arg = raw_linker_arg = 0;
}
break; break;
case 'v': case 'v':
if (argv[i][2] == 0) verbose++; if (argv[i][2] == 0) verbose++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment