utils.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Useful functions for winegcc
  3. *
  4. * Copyright 2000 Francois Gouget
  5. * Copyright 2002 Dimitrie O. Paun
  6. * Copyright 2003 Richard Cohen
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  21. */
  22. #include "config.h"
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdarg.h>
  26. #include <stdlib.h>
  27. #include <errno.h>
  28. #include "utils.h"
  29. int verbose = 0;
  30. void error(const char* s, ...)
  31. {
  32. va_list ap;
  33. va_start(ap, s);
  34. fprintf(stderr, "winegcc: ");
  35. vfprintf(stderr, s, ap);
  36. va_end(ap);
  37. exit(2);
  38. }
  39. void create_file(const char* name, int mode, const char* fmt, ...)
  40. {
  41. va_list ap;
  42. FILE *file;
  43. if (verbose) printf("Creating file %s\n", name);
  44. va_start(ap, fmt);
  45. if ( !(file = fopen(name, "w")) )
  46. error("Unable to open %s for writing\n", name);
  47. vfprintf(file, fmt, ap);
  48. va_end(ap);
  49. fclose(file);
  50. chmod(name, mode);
  51. }
  52. file_type get_file_type(const char* filename)
  53. {
  54. /* see tools/winebuild/res32.c: check_header for details */
  55. static const char res_sig[] = { 0,0,0,0, 32,0,0,0, 0xff,0xff, 0,0, 0xff,0xff, 0,0, 0,0,0,0, 0,0, 0,0, 0,0,0,0, 0,0,0,0 };
  56. static const char elf_sig[4] = "\177ELF";
  57. char buf[sizeof(res_sig)];
  58. int fd, cnt;
  59. fd = open( filename, O_RDONLY );
  60. if (fd == -1) return file_na;
  61. cnt = read(fd, buf, sizeof(buf));
  62. close( fd );
  63. if (cnt == -1) return file_na;
  64. if (cnt == sizeof(res_sig) && !memcmp(buf, res_sig, sizeof(res_sig))) return file_res;
  65. if (strendswith(filename, ".o")) return file_obj;
  66. if (strendswith(filename, ".obj")) return file_obj;
  67. if (strendswith(filename, ".a")) return file_arh;
  68. if (strendswith(filename, ".res")) return file_res;
  69. if (strendswith(filename, ".so")) return file_so;
  70. if (strendswith(filename, ".dylib")) return file_so;
  71. if (strendswith(filename, ".def")) return file_def;
  72. if (strendswith(filename, ".spec")) return file_spec;
  73. if (strendswith(filename, ".rc")) return file_rc;
  74. if (cnt >= sizeof(elf_sig) && !memcmp(buf, elf_sig, sizeof(elf_sig))) return file_so; /* ELF lib */
  75. if (cnt >= sizeof(unsigned int) &&
  76. (*(unsigned int *)buf == 0xfeedface || *(unsigned int *)buf == 0xcefaedfe ||
  77. *(unsigned int *)buf == 0xfeedfacf || *(unsigned int *)buf == 0xcffaedfe))
  78. return file_so; /* Mach-O lib */
  79. return file_other;
  80. }
  81. static char* try_lib_path(const char* dir, const char* pre,
  82. const char* library, const char* ext,
  83. file_type expected_type)
  84. {
  85. char *fullname;
  86. file_type type;
  87. /* first try a subdir named from the library we are looking for */
  88. fullname = strmake("%s/%s/%s%s%s", dir, library, pre, library, ext);
  89. if (verbose > 1) fprintf(stderr, "Try %s...", fullname);
  90. type = get_file_type(fullname);
  91. if (verbose > 1) fprintf(stderr, type == expected_type ? "FOUND!\n" : "no\n");
  92. if (type == expected_type) return fullname;
  93. free( fullname );
  94. fullname = strmake("%s/%s%s%s", dir, pre, library, ext);
  95. if (verbose > 1) fprintf(stderr, "Try %s...", fullname);
  96. type = get_file_type(fullname);
  97. if (verbose > 1) fprintf(stderr, type == expected_type ? "FOUND!\n" : "no\n");
  98. if (type == expected_type) return fullname;
  99. free( fullname );
  100. return 0;
  101. }
  102. static file_type guess_lib_type(struct target target, const char* dir,
  103. const char* library, const char *prefix, const char *suffix, char** file)
  104. {
  105. if (target.platform != PLATFORM_WINDOWS &&
  106. target.platform != PLATFORM_MINGW &&
  107. target.platform != PLATFORM_CYGWIN)
  108. {
  109. /* Unix shared object */
  110. if ((*file = try_lib_path(dir, prefix, library, ".so", file_so)))
  111. return file_so;
  112. /* Mach-O (Darwin/Mac OS X) Dynamic Library behaves mostly like .so */
  113. if ((*file = try_lib_path(dir, prefix, library, ".dylib", file_so)))
  114. return file_so;
  115. /* Windows DLL */
  116. if ((*file = try_lib_path(dir, prefix, library, ".def", file_def)))
  117. return file_dll;
  118. }
  119. /* static archives */
  120. if ((*file = try_lib_path(dir, prefix, library, suffix, file_arh)))
  121. return file_arh;
  122. return file_na;
  123. }
  124. file_type get_lib_type(struct target target, struct strarray path, const char *library,
  125. const char *prefix, const char *suffix, char** file)
  126. {
  127. unsigned int i;
  128. if (!suffix) suffix = ".a";
  129. for (i = 0; i < path.count; i++)
  130. {
  131. file_type type = guess_lib_type(target, path.str[i], library, prefix, suffix, file);
  132. if (type != file_na) return type;
  133. }
  134. return file_na;
  135. }
  136. const char *find_binary( struct strarray prefix, const char *name )
  137. {
  138. char *file_name, *args;
  139. struct strarray dirs = empty_strarray;
  140. static struct strarray path;
  141. unsigned int i;
  142. if (strchr( name, '/' )) return name;
  143. file_name = xstrdup( name );
  144. if ((args = strchr( file_name, ' ' ))) *args++ = 0;
  145. if (!path.count) strarray_addall( &path, strarray_frompath( getenv( "PATH" )));
  146. strarray_addall( &dirs, prefix );
  147. strarray_addall( &dirs, path );
  148. for (i = 0; i < dirs.count; i++)
  149. {
  150. struct stat st;
  151. char *prog = strmake( "%s/%s%s", dirs.str[i], file_name, EXEEXT );
  152. if (stat( prog, &st ) == 0 && S_ISREG( st.st_mode ) && (st.st_mode & 0111))
  153. return args ? strmake( "%s %s", prog, args ) : prog;
  154. free( prog );
  155. }
  156. return NULL;
  157. }
  158. int spawn(struct strarray prefix, struct strarray args, int ignore_errors)
  159. {
  160. int status;
  161. args.str[0] = find_binary( prefix, args.str[0] );
  162. if (verbose) strarray_trace( args );
  163. if ((status = strarray_spawn( args )) && !ignore_errors)
  164. {
  165. if (status > 0) error("%s failed\n", args.str[0]);
  166. else perror("winegcc");
  167. exit(3);
  168. }
  169. return status;
  170. }