-include makefile.auto
PREAUTO := \
+ $(BIN2RES_TARGET) \
$(BUILDNO_H) \
$(BUGCODES_H) \
$(BUGCODES_RC) \
<define name="DBG" value="1" />\r
<property name="DBG_OR_KDBG" value="true" />\r
</if>\r
+ <if property="DBG" value="0">\r
+ <compilerflag>-O2</compilerflag>\r
+ <compilerflag>-Wno-strict-aliasing</compilerflag>\r
+ <compilerflag>-ftracer</compilerflag>\r
+ <compilerflag>-momit-leaf-frame-pointer</compilerflag>\r
+ <compilerflag>-mpreferred-stack-boundary=2</compilerflag>\r
+ </if>\r
<if property="KDBG" value="1">\r
<define name="KDBG" value="1" />\r
<property name="DBG_OR_KDBG" value="true" />\r
# include <unistd.h>
#endif
+#if defined(WIN32)
+#define DIR_SEPARATOR "\\"
+#else
+#define DIR_SEPARATOR "/"
+#endif
+
extern int mkstemps(char *template, int suffix_len);
+int process_resources(const char* input_file_name, const char* specific_file_name,
+ const char* relative_path,
+ int inserting, int force_processing, int verbose);
+
static const char* help =
"Usage: bin2res [OPTIONS] <rsrc.rc>\n"
" -a archive binaries into the <rsrc.rc> file\n"
" -x extract binaries from the <rsrc.rc> file\n"
" -i <filename> archive the named file into the <rsrc.rc> file\n"
" -o <filename> extract the named file from the <rsrc.rc> file\n"
+ " -b <path> assume resources are relative to this base path\n"
" -f force processing of older resources\n"
" -v causes the command to be verbous during processing\n"
" -h print this help screen and exit\n"
return res_file_name;
}
+const char* parse_include(const char *line)
+{
+ static char include_filename[PATH_MAX], *rpos, *wpos;
+
+ if (!(rpos = strstr(line, "#"))) return 0;
+ for (rpos += 1; *rpos && isspace(*rpos); rpos++) /**/;
+ if (!(rpos = strstr(line, "include"))) return 0;
+ for (rpos += 7; *rpos && isspace(*rpos); rpos++) /**/;
+ for (; *rpos && (*rpos == '"' || *rpos == '<'); rpos++) /**/;
+ for (wpos = include_filename; *rpos && !(*rpos == '"' || *rpos == '<'); ) *wpos++ = *rpos++;
+ if (!(rpos = strstr(include_filename, ".rc"))) return 0;
+ *wpos = 0;
+
+ return include_filename;
+}
+
+char* get_filename_with_full_path(char* output, const char* filename, const char* relative_path)
+{
+ if (relative_path != NULL && relative_path[0] != 0)
+ {
+ strcpy(output, relative_path);
+ strcat(output, DIR_SEPARATOR);
+ strcat(output, filename);
+ }
+ else
+ strcpy(output, filename);
+ return output;
+}
+
+void process_includes(const char* input_file_name, const char* specific_file_name,
+ const char* relative_path,
+ int inserting, int force_processing, int verbose)
+{
+ char filename[PATH_MAX];
+ char buffer[2048];
+ const char *include_file_name;
+ FILE *fin;
+ int c;
+
+ if (!(fin = fopen(input_file_name, "r"))) return;
+ for (c = EOF; fgets(buffer, sizeof(buffer), fin); c = EOF)
+ {
+ if (!(include_file_name = parse_include(buffer))) continue;
+ if ( verbose ) printf ( "Processing included file %s\n", include_file_name);
+ process_resources(get_filename_with_full_path(filename, include_file_name, relative_path),
+ specific_file_name, relative_path,
+ inserting, force_processing, verbose);
+ }
+ fclose(fin);
+}
+
int process_resources(const char* input_file_name, const char* specific_file_name,
+ const char* relative_path,
int inserting, int force_processing, int verbose)
{
+ char filename[PATH_MAX];
char buffer[2048], tmp_file_name[PATH_MAX];
const char *res_file_name;
time_t rc_last_update, res_last_update;
if (inserting) fputc(c, ftmp);
if (c == EOF) break;
- if (!(fres = fopen(res_file_name, inserting ? "rb" : "wb"))) break;
+ if (!(fres = fopen(get_filename_with_full_path(filename, res_file_name, relative_path),
+ inserting ? "rb" : "wb"))) break;
if (inserting)
{
if (!insert_hexdump(ftmp, fres)) break;
}
else unlink(tmp_file_name);
}
+ else
+ {
+ process_includes(input_file_name, specific_file_name, relative_path,
+ inserting, force_processing, verbose);
+ }
return c == EOF;
}
int force_overwrite = 0, verbose = 0;
const char* input_file_name = 0;
const char* specific_file_name = 0;
+ const char* relative_path = 0;
- while((optc = getopt(argc, argv, "axi:o:fhv")) != EOF)
+ while((optc = getopt(argc, argv, "axi:o:b:fhv")) != EOF)
{
switch(optc)
{
if (convert_dir && convert_dir != optc) usage();
convert_dir = optc;
break;
+ case 'b':
+ if (relative_path) usage();
+ relative_path = optarg;
+ break;
case 'f':
force_overwrite = 1;
break;
if (!convert_dir) usage();
- if (!process_resources(input_file_name, specific_file_name,
+ if (!process_resources(input_file_name, specific_file_name, relative_path,
convert_dir == 'a', force_overwrite, verbose))
{
perror("Processing failed");
$(ECHO_CC)
${host_gcc} $(BIN2RES_HOST_CFLAGS) -c $< -o $@
+.PHONY: bin2res
+bin2res: $(BIN2RES_TARGET)
+
.PHONY: bin2res_clean
bin2res_clean: $(BIN2RES_TARGET)
-@$(rm) $(BIN2RES_TARGET) $(BIN2RES_OBJECTS) 2>$(NUL)
string
Directory::ReplaceVariable ( string name,
- string value,
- string path )
+ string value,
+ string path )
{
size_t i = path.find ( name );
if ( i != string::npos )
return path;
}
-string
+/* static */ string
Directory::GetEnvironmentVariablePathOrDefault ( const string& name,
- const string& defaultValue )
+ const string& defaultValue )
{
const string& environmentVariableValue = Environment::GetVariable ( name );
if ( environmentVariableValue.length () > 0 )
return defaultValue;
}
-string
+/* static */ string
Directory::GetIntermediatePath ()
{
return GetEnvironmentVariablePathOrDefault ( "ROS_INTERMEDIATE",
"obj-i386" );
}
-string
+/* static */ string
Directory::GetOutputPath ()
{
return GetEnvironmentVariablePathOrDefault ( "ROS_OUTPUT",
"output-i386" );
}
-string
+/* static */ string
Directory::GetInstallPath ()
{
return GetEnvironmentVariablePathOrDefault ( "ROS_INSTALL",
void
Directory::ResolveVariablesInPath ( char* buf,
- string path )
+ string path )
{
string s = ReplaceVariable ( "$(INTERMEDIATE)", GetIntermediatePath (), path );
s = ReplaceVariable ( "$(OUTPUT)", GetOutputPath (), s );
void
Directory::GenerateTree ( const string& parent,
- bool verbose )
+ bool verbose )
{
string path;
GenerateInstallTarget ();
GenerateDirectoryTargets ();
GenerateDirectories ();
+ UnpackWineResources ();
CheckAutomaticDependencies ();
CloseMakefile ();
}
fprintf ( fMakefile, "\n" );
}
+string
+MingwBackend::GetBin2ResExecutable ()
+{
+ return NormalizeFilename ( Directory::GetOutputPath () + SSEP + "tools/bin2res/bin2res" + EXEPOSTFIX );
+}
+
+void
+MingwBackend::UnpackWineResources ()
+{
+ printf ( "Unpacking WINE resources..." );
+ WineResource wineResource ( ProjectNode,
+ GetBin2ResExecutable () );
+ wineResource.UnpackResources ( verbose );
+ printf ( "done\n" );
+}
+
void
MingwBackend::CheckAutomaticDependencies ()
{
std::string EscapeSpaces ( std::string path );
void CreateRule ( FILE* f,
const std::string& parent );
+ static std::string GetIntermediatePath ();
+ static std::string GetOutputPath ();
+ static std::string GetInstallPath ();
private:
bool mkdir_p ( const char* path );
std::string ReplaceVariable ( std::string name,
std::string value,
std::string path );
std::string GetEnvironmentVariable ( const std::string& name );
- std::string GetEnvironmentVariablePathOrDefault ( const std::string& name,
- const std::string& defaultValue );
- std::string GetIntermediatePath ();
- std::string GetOutputPath ();
- std::string GetInstallPath ();
+ static std::string GetEnvironmentVariablePathOrDefault ( const std::string& name,
+ const std::string& defaultValue );
void ResolveVariablesInPath ( char* buf,
std::string path );
bool CreateDirectory ( std::string path );
std::string GetBuildToolDependencies () const;
void GenerateInitTarget () const;
void GenerateXmlBuildFilesMacro() const;
+ std::string GetBin2ResExecutable ();
+ void UnpackWineResources ();
void CheckAutomaticDependencies ();
bool IncludeDirectoryTarget ( const std::string& directory ) const;
bool TryToDetectThisCompiler ( const std::string& compiler );
deps[i].c_str () );
fprintf ( fMakefile, " | %s\n",
- GetDirectory ( GetTargetFilename ( module, NULL ) ).c_str () );
+ GetDirectory ( GetImportLibraryFilename ( module, NULL ) ).c_str () );
fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
void
MingwWin32DLLModuleHandler::Process ()
{
- GenerateExtractWineDLLResourcesTarget ();
GenerateWin32DLLModuleTarget ();
}
-void
-MingwWin32DLLModuleHandler::GenerateExtractWineDLLResourcesTarget ()
-{
- fprintf ( fMakefile, ".PHONY: %s_extractresources\n\n",
- module.name.c_str () );
- fprintf ( fMakefile, "%s_extractresources: $(BIN2RES_TARGET)\n",
- module.name.c_str () );
- const vector<File*>& files = module.non_if_data.files;
- for ( size_t i = 0; i < files.size (); i++ )
- {
- File& file = *files[i];
- string extension = GetExtension ( file.name );
- if ( extension == ".rc" || extension == ".RC" )
- {
- string resource = NormalizeFilename ( file.name );
- fprintf ( fMakefile, "\t$(ECHO_BIN2RES)\n" );
- fprintf ( fMakefile, "\t@:echo ${bin2res} -f -x %s\n",
- resource.c_str () );
- }
- }
- fprintf ( fMakefile, "\n");
-}
-
void
MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
{
virtual HostType DefaultHost() { return HostFalse; }
virtual void Process ();
private:
- void GenerateExtractWineDLLResourcesTarget ();
void GenerateWin32DLLModuleTarget ();
};
class CompilerFlag;
class LinkerFlag;
class Property;
+class WineResource;
class AutomaticDependency;
class Bootstrap;
class CDFile;
};
+class WineResource
+{
+public:
+ const Project& project;
+ std::string bin2res;
+
+ WineResource ( const Project& project,
+ std::string bin2res );
+ ~WineResource ();
+ void UnpackResources ( bool verbose );
+private:
+ bool IsSpecFile ( const File& file );
+ bool IsWineModule ( const Module& module );
+ bool IsResourceFile ( const File& file );
+ std::string GetResourceFilename ( const Module& module );
+ void UnpackResourcesInModule ( Module& module,
+ bool verbose );
+};
+
+
class SourceFile
{
public:
project.cpp \
ssprintf.cpp \
stubbedcomponent.cpp \
+ wineresource.cpp \
XML.cpp \
)
$(ECHO_CC)
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
+$(RBUILD_INT_)wineresource.o: $(RBUILD_BASE_)wineresource.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
+ $(ECHO_CC)
+ ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
+
$(RBUILD_INT_)XML.o: $(RBUILD_BASE_)XML.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
$(ECHO_CC)
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
.PHONY: rbuild_test
-
rbuild_test: $(RBUILD_TEST_TARGET)
$(ECHO_TEST)
$(Q)$(RBUILD_TEST_TARGET)
--- /dev/null
+#include "pch.h"
+#include <assert.h>
+
+#include "rbuild.h"
+
+using std::string;
+using std::vector;
+
+WineResource::WineResource ( const Project& project,
+ string bin2res )
+ : project ( project ),
+ bin2res ( bin2res )
+{
+}
+
+WineResource::~WineResource ()
+{
+}
+
+bool
+WineResource::IsSpecFile ( const File& file )
+{
+ string extension = GetExtension ( file.name );
+ if ( extension == ".spec" || extension == ".SPEC" )
+ return true;
+ return false;
+}
+
+bool
+WineResource::IsWineModule ( const Module& module )
+{
+ const vector<File*>& files = module.non_if_data.files;
+ for ( size_t i = 0; i < files.size (); i++ )
+ {
+ if ( IsSpecFile ( *files[i] ) )
+ return true;
+ }
+ return false;
+}
+
+bool
+WineResource::IsResourceFile ( const File& file )
+{
+ string extension = GetExtension ( file.name );
+ if ( extension == ".rc" || extension == ".RC" )
+ return true;
+ return false;
+}
+
+string
+WineResource::GetResourceFilename ( const Module& module )
+{
+ const vector<File*>& files = module.non_if_data.files;
+ for ( size_t i = 0; i < files.size (); i++ )
+ {
+ if ( IsResourceFile ( *files[i] ) )
+ return files[i]->name;
+ }
+ return "";
+}
+
+void
+WineResource::UnpackResources ( bool verbose )
+{
+ for ( size_t i = 0; i < project.modules.size (); i++ )
+ {
+ if ( IsWineModule ( *project.modules[i] ) )
+ {
+ UnpackResourcesInModule ( *project.modules[i],
+ verbose );
+ }
+ }
+}
+
+void
+WineResource::UnpackResourcesInModule ( Module& module,
+ bool verbose )
+{
+ string resourceFilename = GetResourceFilename ( module );
+ if ( resourceFilename.length () == 0 )
+ return;
+
+ if ( verbose )
+ {
+ printf ( "Unpacking resources for %s",
+ module.name.c_str () );
+ }
+
+ string outputDirectory = GetDirectory ( module.GetPath () );
+ string parameters = ssprintf ( "-b %s -f -x %s",
+ NormalizeFilename ( outputDirectory ).c_str (),
+ NormalizeFilename ( resourceFilename ).c_str () );
+ string command = bin2res + " " + parameters;
+ int exitcode = system ( command.c_str () );
+ if ( exitcode != 0 )
+ {
+ throw InvocationFailedException ( command,
+ exitcode );
+ }
+}