[1/2]tools/winemaker: add project-file support(try3)
André Hentschel
nerv at dawncrow.de
Tue Feb 17 10:08:01 CST 2009
---
tools/winemaker | 761 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 741 insertions(+), 20 deletions(-)
diff --git a/tools/winemaker b/tools/winemaker
index 8c78987..4b8b393 100755
--- a/tools/winemaker
+++ b/tools/winemaker
@@ -3,6 +3,7 @@ use strict;
# Copyright 2000-2004 Francois Gouget for CodeWeavers
# Copyright 2004 Dimitrie O. Paun
+# Copyright 2009 André Hentschel
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -19,7 +20,7 @@ use strict;
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#
-my $version="0.6.0";
+my $version="0.7.0";
use Cwd;
use File::Basename;
@@ -70,6 +71,10 @@ my $OPT_ASK_SKIP=-1;
my $opt_work_dir;
##
+# This is the file in which winemaker will operate if a project file is specified.
+my $opt_work_file;
+
+##
# Make a backup of the files
my $opt_backup;
@@ -819,6 +824,7 @@ sub source_scan_directory($$$$)
}
if ((@$target[$T_FLAGS] & $TF_NOMSVCRT) == 0) {
push @{@$target[$T_LDFLAGS]},"-mno-cygwin";
+ push @{@$target[$T_LDFLAGS]},"-m32";
}
push @{@$project[$P_TARGETS]},$target;
@@ -955,25 +961,712 @@ sub source_scan_directory($$$$)
}
##
-# Scan the source directories in search of things to build
-sub source_scan()
+# Scans the specified project file to:
+# - get a list of targets for this project
+# - get some settings
+# - get the list of source files
+sub source_scan_project_file($$$);
+sub source_scan_project_file($$$)
{
- # If there's a single target then this is going to be the default target
- if (defined $opt_single_target) {
- # Create the main target
- my $main_target=[];
- target_init($main_target);
- @$main_target[$T_NAME]=$opt_single_target;
- @$main_target[$T_TYPE]=$opt_target_type;
+ # a reference to the parent's project
+ my $parent_project=$_[0];
+ # 0 if it is a single project, 1 if it is part of a workspace
+ my $is_sub_project=$_[1];
+ # the name of the project file, with complete path, or without if in
+ # the same directory
+ my $filename=$_[2];
- # Add it to the list
- push @{$main_project[$P_TARGETS]},$main_target;
+ # reference to the project for this file. May not be used
+ my $project;
+ # list of targets found in the current file
+ my %targets;
+ # list of sources found in the current file
+ my @sources_c=();
+ my @sources_cxx=();
+ my @sources_rc=();
+ my @sources_misc=();
+ # true if this directory contains headers
+ my $has_headers=0;
+ # some more settings
+ my $path=dirname($filename);
+ my $prj_target_cflags;
+ my $prj_target_ldflags;
+ my $prj_target_libs;
+ my $prj_name;
+ my $found_cfg=0;
+ my $prj_cfg;
+ my $prj_target_type=1;
+ my @prj_target_options;
+
+ if (!($path=~/\/$/)) {
+ $path=$path."/";
+ }
+
+ if (defined $opt_single_target or $is_sub_project == 0) {
+ # Either there is a single target and thus a single project,
+ # or we are a single project-file for which a project
+ # already exists
+ $project=$parent_project;
+ } else {
+ $project=[];
+ project_init($project,$path);
}
+ my $project_settings=@$project[$P_SETTINGS];
- # The main directory is always going to be there
- push @projects,\@main_project;
+ if ($filename =~ /.dsp$/i) {
+ # First find out what this project file contains:
+ # collect all sources, find targets and settings
+ if (!open(FILEI,$filename)) {
+ print STDERR "error: unable to open $filename for reading:\n";
+ print STDERR " $!\n";
+ return;
+ }
+ my $sfilet;
+ while (<FILEI>) {
+ # Remove any trailing CtrlZ, which isn't strictly in the file
+ if (/\x1A/) {
+ s/\x1A//;
+ last if (/^$/)
+ }
+
+ # Remove any trailing CrLf
+ s/\r\n$/\n/;
+ if (!/\n$/) {
+ # Make sure all lines are '\n' terminated
+ $_ .= "\n";
+ }
+
+ if (/^\# Microsoft Developer Studio Project File - Name=\"([^\"]+)/) {
+ $prj_name="$1.exe";
+ $targets{$prj_name}=1;
+ #print $prj_name;
+ next;
+ } elsif(/^# TARGTYPE/) {
+ if (/[[:space:]]0x0101$/) {
+ # Win32 (x86) Application
+ $prj_target_type=1;
+ }elsif (/[[:space:]]0x0102$/) {
+ # Win32 (x86) Dynamic-Link Library
+ $prj_target_type=3;
+ }elsif (/[[:space:]]0x0103$/) {
+ # Win32 (x86) Console Application
+ $prj_target_type=2;
+ }elsif (/[[:space:]]0x0104$/) {
+ # Win32 (x86) Static Library
+ }
+ next;
+ } elsif(/^# ADD CPP(.*)/ && $found_cfg==1) {
+ $prj_target_cflags=$1;
+ @prj_target_options=split(" /", $prj_target_cflags);
+ $prj_target_cflags="";
+ foreach ( @prj_target_options ) {
+ if($_ eq "") {
+ # empty
+ } elsif(/nologo/) {
+ # Suppress Startup Banner and Information Messages
+ } elsif (/^W0$/) {
+ # Turns off all warning messages
+ $prj_target_cflags=$prj_target_cflags."-w ";
+ } elsif (/^W[123]$/) {
+ # Warning Level
+ $prj_target_cflags=$prj_target_cflags."-W ";
+ } elsif (/^W4$/) {
+ # Warning Level
+ $prj_target_cflags=$prj_target_cflags."-Wall ";
+ } elsif (/^WX$/) {
+ # Warnings As Errors
+ $prj_target_cflags=$prj_target_cflags."-Werror ";
+ } elsif (/^Gm$/) {
+ # Enable Minimal Rebuild
+ } elsif (/^GX$/) {
+ # Enable Exception Handling
+ $prj_target_cflags=$prj_target_cflags."-fexceptions ";
+ } elsif (/^Z[d7iI]$/) {
+ # Debug Info
+ $prj_target_cflags=$prj_target_cflags."-g ";
+ } elsif (/^Od$/) {
+ # Disable Optimizations
+ $prj_target_cflags=$prj_target_cflags."-O0 ";
+ } elsif (/^O1$/) {
+ # Minimize Size
+ $prj_target_cflags=$prj_target_cflags."-Os ";
+ } elsif (/^O2$/) {
+ # Maximize Speed
+ $prj_target_cflags=$prj_target_cflags."-O2 ";
+ } elsif (/^Ob0$/) {
+ # Disables inline Expansion
+ $prj_target_cflags=$prj_target_cflags."-fno-inline ";
+ } elsif (/^Ob1$/) {
+ # In-line Function Expansion
+ } elsif (/^Ob2$/) {
+ # auto In-line Function Expansion
+ $prj_target_cflags=$prj_target_cflags."-finline-functions ";
+ } elsif (/^Oy$/) {
+ # Frame-Pointer Omission
+ $prj_target_cflags=$prj_target_cflags."-fomit-frame-pointer ";
+ } elsif (/^GZ$/) {
+ # Catch Release-Build Errors in Debug Build
+ } elsif (/^M[DLT]d?$/) {
+ # Use Multithreaded Run-Time Library
+ } elsif (/^D\s*\"(.*)\"/) {
+ # Preprocessor Definitions
+ $prj_target_cflags=$prj_target_cflags."-D".$1." ";
+ } elsif (/^I/) {
+ # Additional Include Directories
+ #$prj_target_cflags=$prj_target_cflags."-I" fixpath(option)
+ } elsif (/^U\s*\"(.*)\"/) {
+ # Undefines a previously defined symbol
+ $prj_target_cflags=$prj_target_cflags."-U".$1." ";
+ } elsif (/^Fp/) {
+ # Name .PCH File
+ } elsif (/^F[Rr]/) {
+ # Create .SBR File
+ } elsif (/^YX$/) {
+ # Automatic Use of Precompiled Headers
+ } elsif (/^FD$/) {
+ # Generate File Dependencies
+ } elsif (/^c$/) {
+ # Compile Without Linking
+ # this option is always present and is already specified in the suffix rules
+ } elsif (/^GB$/) {
+ # Blend Optimization
+ $prj_target_cflags=$prj_target_cflags."-mcpu=pentiumpro -D_M_IX86=500 ";
+ } elsif (/^G6$/) {
+ # Pentium Pro Optimization
+ $prj_target_cflags=$prj_target_cflags."-march=pentiumpro -D_M_IX86=600 ";
+ } elsif (/^G5$/) {
+ # Pentium Optimization
+ $prj_target_cflags=$prj_target_cflags."-mcpu=pentium -D_M_IX86=500 ";
+ } elsif (/^G3$/) {
+ # 80386 Optimization
+ $prj_target_cflags=$prj_target_cflags."-mcpu=i386 -D_M_IX86=300 ";
+ } elsif (/^G4$/) {
+ # 80486 Optimization
+ $prj_target_cflags=$prj_target_cflags."-mcpu=i486 -D_M_IX86=400 ";
+ } elsif (/^Yc/) {
+ # Create Precompiled Header
+ } elsif (/^Yu/) {
+ # Use Precompiled Header
+ } elsif (/^Za$/) {
+ # Disable Language Extensions
+ $prj_target_cflags=$prj_target_cflags."-ansi ";
+ } elsif (/^Ze$/) {
+ # Enable Microsoft Extensions
+ } elsif (/^Zm[[:digit:]]+$/) {
+ # Specify Memory Allocation Limit
+ } elsif (/^Zp1$/) {
+ # Packs structures on 1-byte boundaries
+ $prj_target_cflags=$prj_target_cflags."-fpack-struct ";
+ } elsif (/^Zp(2|4|8|16)?$/) {
+ # Struct Member Alignment
+ } else {
+ print "C compiler option $_ not implemented\n";
+ }
+ }
+
+ #print "\nOptions: $prj_target_cflags\n";
+ next;
+ } elsif(/^# ADD LINK32(.*)/ && $found_cfg==1) {
+ $prj_target_ldflags=$1;
+ @prj_target_options=split(" /", $prj_target_ldflags);
+ $prj_target_ldflags="";
+ $prj_target_libs=$prj_target_options[0];
+ #print "\n$prj_target_libs bevor\n";
+ $prj_target_libs=~s/\\/\//g;
+ $prj_target_libs=~s/\.lib//g;
+ $prj_target_libs=~s/\s/ -l/g;
+ #print "\n$prj_target_libs after\n";
+ shift (@prj_target_options);
+ foreach ( @prj_target_options ) {
+ if($_ eq "") {
+ # empty
+ } elsif (/^base:(.*)/) {
+ # Base Address
+ $prj_target_ldflags=$prj_target_ldflags."--image-base ".$1." ";
+ } elsif (/^debug$/) {
+ # Generate Debug Info
+ } elsif (/^dll$/) {
+ # Build a DLL
+ $prj_target_type=3;
+ } elsif (/^incremental:[[:alpha:]]+$/) {
+ # Link Incrmentally
+ } elsif (/^implib:/) {
+ # Name import library
+ } elsif (/^libpath:\"(.*)\"/) {
+ # Additional Libpath
+ push @{@$project_settings[$T_DLL_PATH]},"-L$1";
+ } elsif (/^machine:[[:alnum:]]+$/) {
+ # Specify Target Platform
+ } elsif (/^map/) {
+ # Generate Mapfile
+ if (/^map:(.*)/) {
+ $prj_target_ldflags=$prj_target_ldflags."-Map ".$1." ";
+ } else {
+ $prj_target_ldflags=$prj_target_ldflags."-Map ".$prj_name.".map ";
+ }
+ } elsif(/^nologo$/) {
+ # Suppress Startup Banner and Information Messages
+ } elsif (/^out:/) {
+ # Output File Name
+ # may use it as Target?
+ } elsif (/^pdbtype:/) {
+ # Program Database Storage
+ } elsif (/^subsystem:/) {
+ # Specify Subsystem
+ } elsif (/^version:[[:digit:].]+$/) {
+ # Version Information
+ } else {
+ print "Linker option $_ not implemented\n";
+ }
+ }
+ next;
+ } elsif(/^LIB32=/ && $found_cfg==1) {
+ #$libflag = 1;
+ next;
+ } elsif (/^SOURCE=(.*)$/) {
+ $sfilet=$1;
+ if (($opt_lower == $OPT_LOWER_ALL and $sfilet =~ /[A-Z]/) or ($opt_lower == $OPT_LOWER_UPPERCASE and $sfilet !~ /[a-z]/)) {
+ $sfilet=lc $sfilet; #to lowercase if necessary
+ }
+ $sfilet=~s/\\\\/\\/g; #remove double backslash
+ $sfilet=~s/^\.\\//; #remove starting 'this directory'
+ $sfilet=~s/\\/\//g; #make slashes out of backslashes
+ # if ($sfilet =~ /^((\.\.\/)+)/){
+ # print "Fix files and directories in $1 ? y or n: ";
+ #
+ # if (<STDIN>=~/^y/i) {
+ # fix_file_and_directory_names("$1"); #referenced files in upper directories? fix them!
+ # }
+ # }
+ if ($sfilet =~ /\.(exe|dll)$/i) {
+ $targets{$sfilet}=1;
+ } elsif ($sfilet =~ /\.c$/i and $sfilet !~ /\.(dbg|spec)\.c$/) {
+ push @sources_c,$sfilet;
+ } elsif ($sfilet =~ /\.(cpp|cxx)$/i) {
+ if ($sfilet =~ /^stdafx.cpp$/i && !(@$project_settings[$T_FLAGS] & $TF_NOMFC)) {
+ push @sources_misc,$sfilet;
+ @$project_settings[$T_FLAGS]|=$TF_MFC;
+ } else {
+ push @sources_cxx,$sfilet;
+ }
+ } elsif ($sfilet =~ /\.rc$/i) {
+ push @sources_rc,$sfilet;
+ } elsif ($sfilet =~ /\.(h|hxx|hpp|inl|rc2|dlg)$/i) {
+ $has_headers=1;
+ push @sources_misc,$sfilet;
+ if ($sfilet =~ /^stdafx.h$/i && !(@$project_settings[$T_FLAGS] & $TF_NOMFC)) {
+ @$project_settings[$T_FLAGS]|=$TF_MFC;
+ }
+ }
+ next;
+
+ } elsif(/^# (Begin|End) Source File/) {
+ # Source-Files already handled
+ next;
+ } elsif (/^# (Begin|End) Group/) {
+ # Groups are ignored
+ next;
+ } elsif(/^# (Begin|End) Custom Build/) {
+ # Custom Builds are ignored
+ next;
+
+ } elsif(/^# ADD LIB32 /) {
+ #"ARFLAGS=rus"
+ next;
+ } elsif(/^# Begin Target$/) {
+ # Targets are ignored
+ next;
+ } elsif(/^# End Target$/) {
+ # Targets are ignored
+ next;
+ } elsif(/^!/) {
+ if ($found_cfg == 1) {
+ $found_cfg=0;
+ }
+ if(/IF(.*)\(CFG\)" == "(.*)"/) {
+ if ($2 eq $prj_cfg) {
+ $found_cfg=1;
+ }
+ }
+ next;
+ } elsif(/^CFG=(.*)/) {
+ $prj_cfg=$1;
+ next;
+ }
+
+ else { # Line recognized
+ # print "|\n";
+ }
+ }
+ close(FILEI);
+
+ push @{@$project_settings[$T_LIBRARIES]},$prj_target_libs;
+ push @{@$project_settings[$T_CXXEXTRA]},$prj_target_cflags;
+ push @{@$project_settings[$T_LDFLAGS]},$prj_target_ldflags;
+ } elsif ($filename =~ /.vcproj$/i) {
+ # Import des Moduls XML::Simple
+ use XML::Simple;
+
+ my $project_xml = XMLin($filename, forcearray=>1);
+
+ $targets{$project_xml->{'Name'}.".exe"}=1;
+ my $sfilet;
+ for my $vc_files (@{$project_xml->{'Files'}}) {
+ for my $vc_filter (@{$vc_files->{'Filter'}}) {
+ for my $vc_file (@{$vc_filter->{'File'}}) {
+ $sfilet=$vc_file->{'RelativePath'};
+ if (($opt_lower == $OPT_LOWER_ALL and $sfilet =~ /[A-Z]/) or ($opt_lower == $OPT_LOWER_UPPERCASE and $sfilet !~ /[a-z]/)) {
+ $sfilet=lc $sfilet; #to lowercase if necessary
+ }
+ $sfilet=~s/\\\\/\\/g; #remove double backslash
+ $sfilet=~s/^\.\\//; #remove starting 'this directory'
+ $sfilet=~s/\\/\//g; #make slashes out of backslashes
+ if ($sfilet =~ /\.(exe|dll)$/i) {
+ $targets{$sfilet}=1;
+ } elsif ($sfilet =~ /\.c$/i and $sfilet !~ /\.(dbg|spec)\.c$/) {
+ push @sources_c,$sfilet;
+ } elsif ($sfilet =~ /\.(cpp|cxx)$/i) {
+ if ($sfilet =~ /^stdafx.cpp$/i && !(@$project_settings[$T_FLAGS] & $TF_NOMFC)) {
+ push @sources_misc,$sfilet;
+ @$project_settings[$T_FLAGS]|=$TF_MFC;
+ } else {
+ push @sources_cxx,$sfilet;
+ }
+ } elsif ($sfilet =~ /\.rc$/i) {
+ push @sources_rc,$sfilet;
+ } elsif ($sfilet =~ /\.(h|hxx|hpp|inl|rc2|dlg)$/i) {
+ $has_headers=1;
+ push @sources_misc,$sfilet;
+ if ($sfilet =~ /^stdafx.h$/i && !(@$project_settings[$T_FLAGS] & $TF_NOMFC)) {
+ @$project_settings[$T_FLAGS]|=$TF_MFC;
+ }
+ }
+ }
+ }
+ }
+ $prj_target_cflags="";
+ for my $vc_configurations (@{$project_xml->{'Configurations'}}) {
+ for my $vc_configuration (@{$vc_configurations->{'Configuration'}}) {
+ for my $vc_tool (@{$vc_configuration->{'Tool'}}) {
+ if ($vc_tool->{'Name'} ne 'VCCLCompilerTool') { next; }
+ if (defined $vc_tool->{'Optimization'}) {$prj_target_cflags=$prj_target_cflags."-O".$vc_tool->{'Optimization'}." ";}
+ if (defined $vc_tool->{'WarningLevel'}) {
+ if ($vc_tool->{'WarningLevel'}==0) {
+ $prj_target_cflags=$prj_target_cflags."-w ";
+ } elsif ($vc_tool->{'WarningLevel'}<4) {
+ $prj_target_cflags=$prj_target_cflags."-W ";
+ } elsif ($vc_tool->{'WarningLevel'}==4) {
+ $prj_target_cflags=$prj_target_cflags."-Wall ";
+ } elsif ($vc_tool->{'WarningLevel'} eq "X") {
+ $prj_target_cflags=$prj_target_cflags."-Werror ";
+ }
+ }
+ if (defined $vc_tool->{'PreprocessorDefinitions'}) {
+ $vc_tool->{'PreprocessorDefinitions'}=~s/;/ -D/g;
+ $prj_target_cflags=$prj_target_cflags."-D".$vc_tool->{'PreprocessorDefinitions'}." ";
+ }
+ }
+ last;
+ }
+ }
+
+ push @{@$project_settings[$T_CXXEXTRA]},$prj_target_cflags;
+ }
+
+ if ($has_headers) {
+ push @{@$project_settings[$T_INCLUDE_PATH]},"-I.";
+ }
+
+ my $target_count;
+ $target_count=keys %targets;
+
+
+ # Add this project to the project list, except for
+ # the main project which is already in the list.
+ if ($is_sub_project == 1) {
+ push @projects,$project;
+ }
+
+ # Ask for project-wide options
+ if ($opt_ask_project_options == $OPT_ASK_YES) {
+ my $flag_desc="";
+ if ((@$project_settings[$T_FLAGS] & $TF_MFC)!=0) {
+ $flag_desc="mfc";
+ }
+ print "* Type any project-wide options (-D/-I/-P/-i/-L/-l/--mfc),\n";
+ if (defined $flag_desc) {
+ print "* (currently $flag_desc)\n";
+ }
+ print "* or 'skip' to skip the target specific options,\n";
+ print "* or 'never' to not be asked this question again:\n";
+ while (1) {
+ my $options=<STDIN>;
+ chomp $options;
+ if ($options eq "skip") {
+ $opt_ask_target_options=$OPT_ASK_SKIP;
+ last;
+ } elsif ($options eq "never") {
+ $opt_ask_project_options=$OPT_ASK_NO;
+ last;
+ } elsif (source_set_options($project_settings,$options)) {
+ last;
+ }
+ print "Please re-enter the options:\n";
+ }
+ }
+
+ # - Create the targets
+ # - Check if we have both libraries and programs
+ # - Match each target with source files (sort in reverse
+ # alphabetical order to get the longest matches first)
+ my @local_dlls=();
+ my @local_depends=();
+ my @exe_list=();
+ foreach my $target_name (map (lc, (sort { $b cmp $a } keys %targets))) {
+ # Create the target...
+ my $target=[];
+ target_init($target);
+ @$target[$T_NAME]=$target_name;
+ @$target[$T_FLAGS]|=@$project_settings[$T_FLAGS];
+ if ($target_name =~ /\.dll$/) {
+ @$target[$T_TYPE]=$TT_DLL;
+ push @local_depends,"$target_name.so";
+ push @local_dlls,$target_name;
+ my $canon=canonize($target_name);
+ push @{@$target[$T_LDFLAGS]},("-shared","\$(${canon}_MODULE:%=%.spec)");
+ } else {
+ @$target[$T_TYPE]=$opt_target_type;
+ push @exe_list,$target;
+ push @{@$target[$T_LDFLAGS]},(@$target[$T_TYPE] == $TT_CUIEXE ? "-mconsole" : "-mwindows");
+ }
+ my $basename=$target_name;
+ $basename=~ s/\.(dll|exe)$//i;
+ # This is the default link list of Visual Studio
+ my @std_imports=qw(odbc32 ole32 oleaut32 winspool odbccp32);
+ my @std_libraries=qw(uuid);
+ if ((@$target[$T_FLAGS] & $TF_NODLLS) == 0) {
+ @$target[$T_DLLS]=\@std_imports;
+ @$target[$T_LIBRARIES]=\@std_libraries;
+ } else {
+ @$target[$T_DLLS]=[];
+ @$target[$T_LIBRARIES]=[];
+ }
+ if ((@$target[$T_FLAGS] & $TF_NOMSVCRT) == 0) {
+ push @{@$target[$T_LDFLAGS]},"-mno-cygwin";
+ push @{@$target[$T_LDFLAGS]},"-m32";
+ }
+ push @{@$project[$P_TARGETS]},$target;
+
+ # Ask for target-specific options
+ if ($opt_ask_target_options == $OPT_ASK_YES) {
+ my $flag_desc="";
+ if ((@$target[$T_FLAGS] & $TF_MFC)!=0) {
+ $flag_desc=" (mfc";
+ }
+ if ($flag_desc ne "") {
+ $flag_desc.=")";
+ }
+ print "* Specify any link option (-P/-i/-L/-l/--mfc) specific to the target\n";
+ print "* \"$target_name\"$flag_desc or 'never' to not be asked this question again:\n";
+ while (1) {
+ my $options=<STDIN>;
+ chomp $options;
+ if ($options eq "never") {
+ $opt_ask_target_options=$OPT_ASK_NO;
+ last;
+ } elsif (source_set_options($target,$options)) {
+ last;
+ }
+ print "Please re-enter the options:\n";
+ }
+ }
+ if (@$target[$T_FLAGS] & $TF_MFC) {
+ @$project_settings[$T_FLAGS]|=$TF_MFC;
+ push @{@$target[$T_DLL_PATH]},"\$(MFC_LIBRARY_PATH)";
+ push @{@$target[$T_DLLS]},"mfc.dll";
+ # FIXME: Link with the MFC in the Unix sense, until we
+ # start exporting the functions properly.
+ push @{@$target[$T_LIBRARY_PATH]},"\$(MFC_LIBRARY_PATH)";
+ push @{@$target[$T_LIBRARIES]},"mfc";
+ }
+
+ # Match sources...
+ if ($target_count == 1) {
+ push @{@$target[$T_SOURCES_C]},@{@$project_settings[$T_SOURCES_C]}, at sources_c;
+ @$project_settings[$T_SOURCES_C]=[];
+ @sources_c=();
+
+ push @{@$target[$T_SOURCES_CXX]},@{@$project_settings[$T_SOURCES_CXX]}, at sources_cxx;
+ @$project_settings[$T_SOURCES_CXX]=[];
+ @sources_cxx=();
+
+ push @{@$target[$T_SOURCES_RC]},@{@$project_settings[$T_SOURCES_RC]}, at sources_rc;
+ @$project_settings[$T_SOURCES_RC]=[];
+ @sources_rc=();
+
+ push @{@$target[$T_SOURCES_MISC]},@{@$project_settings[$T_SOURCES_MISC]}, at sources_misc;
+ # No need for sorting these sources
+ @$project_settings[$T_SOURCES_MISC]=[];
+ @sources_misc=();
+ } else {
+ foreach my $source (@sources_c) {
+ if ($source =~ /^$basename/i) {
+ push @{@$target[$T_SOURCES_C]},$source;
+ $source="";
+ }
+ }
+ foreach my $source (@sources_cxx) {
+ if ($source =~ /^$basename/i) {
+ push @{@$target[$T_SOURCES_CXX]},$source;
+ $source="";
+ }
+ }
+ foreach my $source (@sources_rc) {
+ if ($source =~ /^$basename/i) {
+ push @{@$target[$T_SOURCES_RC]},$source;
+ $source="";
+ }
+ }
+ foreach my $source (@sources_misc) {
+ if ($source =~ /^$basename/i) {
+ push @{@$target[$T_SOURCES_MISC]},$source;
+ $source="";
+ }
+ }
+ }
+ @$target[$T_SOURCES_C]=[sort @{@$target[$T_SOURCES_C]}];
+ @$target[$T_SOURCES_CXX]=[sort @{@$target[$T_SOURCES_CXX]}];
+ @$target[$T_SOURCES_RC]=[sort @{@$target[$T_SOURCES_RC]}];
+ @$target[$T_SOURCES_MISC]=[sort @{@$target[$T_SOURCES_MISC]}];
+ }
+ if ($opt_ask_target_options == $OPT_ASK_SKIP) {
+ $opt_ask_target_options=$OPT_ASK_YES;
+ }
+
+ if ((@$project_settings[$T_FLAGS] & $TF_NOMSVCRT) == 0) {
+ push @{@$project_settings[$T_CEXTRA]},"-mno-cygwin";
+ push @{@$project_settings[$T_CXXEXTRA]},"-mno-cygwin";
+ }
+
+ if (@$project_settings[$T_FLAGS] & $TF_MFC) {
+ push @{@$project_settings[$T_INCLUDE_PATH]},"\$(MFC_INCLUDE_PATH)";
+ }
+ # The sources that did not match, if any, go to the extra
+ # source list of the project settings
+ foreach my $source (@sources_c) {
+ if ($source ne "") {
+ push @{@$project_settings[$T_SOURCES_C]},$source;
+ }
+ }
+ @$project_settings[$T_SOURCES_C]=[sort @{@$project_settings[$T_SOURCES_C]}];
+ foreach my $source (@sources_cxx) {
+ if ($source ne "") {
+ push @{@$project_settings[$T_SOURCES_CXX]},$source;
+ }
+ }
+ @$project_settings[$T_SOURCES_CXX]=[sort @{@$project_settings[$T_SOURCES_CXX]}];
+ foreach my $source (@sources_rc) {
+ if ($source ne "") {
+ push @{@$project_settings[$T_SOURCES_RC]},$source;
+ }
+ }
+ @$project_settings[$T_SOURCES_RC]=[sort @{@$project_settings[$T_SOURCES_RC]}];
+ foreach my $source (@sources_misc) {
+ if ($source ne "") {
+ push @{@$project_settings[$T_SOURCES_MISC]},$source;
+ }
+ }
+ @$project_settings[$T_SOURCES_MISC]=[sort @{@$project_settings[$T_SOURCES_MISC]}];
+
+ # Finally if we are building both libraries and programs in
+ # this project, then the programs should be linked with all
+ # the libraries
+ if (@local_dlls > 0 and @exe_list > 0) {
+ foreach my $target (@exe_list) {
+ push @{@$target[$T_DLL_PATH]},"-L.";
+ push @{@$target[$T_DLLS]}, at local_dlls;
+ }
+ }
+}
+
+##
+# Scans the specified workspace file to find the project files
+sub source_scan_workspace_file($);
+sub source_scan_workspace_file($)
+{
+ my $filename=$_[0];
+
+ if (! -e $filename) {
+ return;
+ }
- # Now scan the directory tree looking for source files and, maybe, targets
+ if (!open(FILEIWS,$filename)) {
+ print STDERR "error: unable to open $filename for reading:\n";
+ print STDERR " $!\n";
+ return;
+ }
+
+ my $prj_name;
+ my $prj_path;
+
+ if ($filename =~ /.dsw$/i) {
+ while (<FILEIWS>) {
+ # Remove any trailing CrLf
+ s/\r\n$/\n/;
+
+ # catch a project definition
+ if(/^Project:\s\"(.*)\"=(.*)\s-/) {
+ $prj_name=$1;
+ $prj_path=$2;
+ $prj_path=~s/\\\\/\\/g; #remove double backslash
+ $prj_path=~s/^\.\\//; #remove starting 'this directory'
+ $prj_path=~s/\\/\//g; #make slashes out of backslashes
+ print "Name: $prj_name\nPfad: $prj_path\n";
+ source_scan_project_file(\@main_project,1,$prj_path);
+ next;
+ } elsif(/^#/)
+ {
+ # ignore Comments
+ } elsif(/\w:/)
+ {
+ print STDERR "unknown section $_\n";
+ } elsif(/^Microsoft(.*)Studio(.*)File,\sFormat Version\s(.*)/)
+ {
+ print "\nFileversion: $3\n";
+ }
+ }
+ close(FILEIWS);
+ } elsif ($filename =~ /.sln$/i) {
+ while (<FILEIWS>) {
+ # Remove any trailing CrLf
+ s/\r\n$/\n/;
+
+ # catch a project definition
+ if(/^Project(.*)=\s*"(.*)",\s*"(.*)",\s*"(.*)"/) {
+ $prj_name=$2;
+ $prj_path=$3;
+ $prj_path=~s/\\\\/\\/g; #remove double backslash
+ $prj_path=~s/^\.\\//; #remove starting 'this directory'
+ $prj_path=~s/\\/\//g; #make slashes out of backslashes
+ print "Name: $prj_name\nPfad: $prj_path\n";
+ source_scan_project_file(\@main_project,1,$prj_path);
+ next;
+ } elsif(/^Microsoft(.*)Studio(.*)File,\sFormat Version\s(.*)/)
+ {
+ print "\nFileversion: $3\n";
+ }
+ }
+ close(FILEIWS);
+ }
+
+ @projects=sort { @$a[$P_PATH] cmp @$b[$P_PATH] } @projects;
+}
+
+##
+# Scan the source directories in search of things to build
+sub source_scan()
+{
+ # Scan the directory tree looking for source files and, maybe, targets
print "Scanning the source directories...\n";
source_scan_directory(\@main_project,"","",0);
@@ -1823,7 +2516,7 @@ sub usage()
print STDERR " [-Dmacro[=defn]] [-Idir] [-Pdir] [-idll] [-Ldir] [-llibrary]\n";
print STDERR " [--nodlls] [--nomsvcrt] [--interactive] [--single-target name]\n";
print STDERR " [--generated-files|--nogenerated-files]\n";
- print STDERR " work_directory\n";
+ print STDERR " work_directory|project_file|workspace_file\n";
print STDERR "\nWinemaker is designed to recursively convert all the Windows sources found in\n";
print STDERR "the specified directory so that they can be compiled with Winelib. During this\n";
print STDERR "process it will modify and rename some of the files in that directory.\n";
@@ -1897,8 +2590,13 @@ while (@ARGV>0) {
# Catch errors
} else {
if ($arg ne "--help" and $arg ne "-h" and $arg ne "-?") {
- if (!defined $opt_work_dir) {
+ if (!defined $opt_work_dir and !defined $opt_work_file) {
+ if (-f $arg) {
+ $opt_work_file=$arg;
+ }
+ else {
$opt_work_dir=$arg;
+ }
} else {
print STDERR "error: the work directory, \"$arg\", has already been specified (was \"$opt_work_dir\")\n";
usage();
@@ -1909,10 +2607,10 @@ while (@ARGV>0) {
}
}
-if (!defined $opt_work_dir) {
- print STDERR "error: you must specify the directory containing the sources to be converted\n";
+if (!defined $opt_work_dir and !defined $opt_work_file) {
+ print STDERR "error: you must specify the directory or project file containing the sources to be converted\n";
usage();
-} elsif (!chdir $opt_work_dir) {
+} elsif (defined $opt_work_dir and !chdir $opt_work_dir) {
print STDERR "error: could not chdir to the work directory\n";
print STDERR " $!\n";
usage();
@@ -1927,8 +2625,31 @@ project_init(\@main_project,"");
# Fix the file and directory names
fix_file_and_directory_names(".");
+# If there's a single target then this is going to be the default target
+if (defined $opt_single_target) {
+ # Create the main target
+ my $main_target=[];
+ target_init($main_target);
+ @$main_target[$T_NAME]=$opt_single_target;
+ @$main_target[$T_TYPE]=$opt_target_type;
+
+ # Add it to the list
+ push @{$main_project[$P_TARGETS]},$main_target;
+}
+
+# The main directory is always going to be there
+push @projects,\@main_project;
+
+if (defined $opt_work_dir) {
# Scan the sources to identify the projects and targets
source_scan();
+} elsif (defined $opt_work_file) {
+ if ($opt_work_file =~ /.dsp$/i or $opt_work_file =~ /.vcproj$/i) {
+ source_scan_project_file(\@main_project,0,$opt_work_file);
+ } elsif ($opt_work_file =~ /.dsw$/i or $opt_work_file =~ /.sln$/i) {
+ source_scan_workspace_file($opt_work_file);
+ }
+}
# Fix the source files
if (! $opt_no_source_fix) {
--
1.6.0.4
--------------070703040901030607090400--
More information about the wine-patches
mailing list