Skip to content

Commit 259d87c

Browse files
mstormogitster
authored andcommitted
Add scripts to generate projects for other buildsystems (MSVC vcproj, QMake)
These scripts generate projects for the MSVC IDE (.vcproj files) or QMake (.pro files), based on the output of a 'make -n MSVC=1 V=1' run. This enables us to simply do the necesarry changes in the Makefile, and you can update the other buildsystems by regenerating the files. Keeping the other buildsystems up-to-date with main development. The generator system is designed to easily drop in pm's for other buildsystems as well, if someone has an itch. However, the focus has been Windows development, so the 'engine' might need patches to support any platform. Also add some .gitignore entries for MSVC files. Signed-off-by: Marius Storm-Olsen <[email protected]> Acked-by: Johannes Sixt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a2c6bf0 commit 259d87c

File tree

8 files changed

+1503
-1
lines changed

8 files changed

+1503
-1
lines changed

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,14 @@ configure
179179
tags
180180
TAGS
181181
cscope*
182+
*.obj
183+
*.lib
184+
*.sln
185+
*.suo
186+
*.ncb
187+
*.vcproj
188+
*.user
189+
*.idb
190+
*.pdb
191+
Debug/
192+
Release/

compat/vcbuild/README

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,18 @@ The Steps of Build Git with VS2008
3333
make common-cmds.h
3434
to generate the common-cmds.h file needed to compile git.
3535

36-
4. Then build Git with the GNU Make Makefile in the Git projects root
36+
4. Then either build Git with the GNU Make Makefile in the Git projects
37+
root
3738
make MSVC=1
39+
or generate Visual Studio solution/projects (.sln/.vcproj) with the
40+
command
41+
perl contrib/buildsystems/generate -g Vcproj
42+
and open and build the solution with the IDE
43+
devenv git.sln /useenv
44+
or build with the IDE build engine directly from the command line
45+
devenv git.sln /useenv /build "Release|Win32"
46+
The /useenv option is required, so Visual Studio picks up the
47+
environment variables for the support libraries required to build
48+
Git, which you set up in step 1.
3849

3950
Done!

contrib/buildsystems/Generators.pm

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package Generators;
2+
require Exporter;
3+
4+
use strict;
5+
use File::Basename;
6+
no strict 'refs';
7+
use vars qw($VERSION @AVAILABLE);
8+
9+
our $VERSION = '1.00';
10+
our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
11+
@ISA = qw(Exporter);
12+
13+
BEGIN {
14+
local(*D);
15+
my $me = $INC{"Generators.pm"};
16+
die "Couldn't find myself in \@INC, which is required to load the generators!" if ("$me" eq "");
17+
$me = dirname($me);
18+
if (opendir(D,"$me/Generators")) {
19+
foreach my $gen (readdir(D)) {
20+
next if ($gen =~ /^\.\.?$/);
21+
require "${me}/Generators/$gen";
22+
$gen =~ s,\.pm,,;
23+
push(@AVAILABLE, $gen);
24+
}
25+
closedir(D);
26+
my $gens = join(', ', @AVAILABLE);
27+
}
28+
29+
push @EXPORT_OK, qw(available);
30+
}
31+
32+
sub available {
33+
return @AVAILABLE;
34+
}
35+
36+
sub generate {
37+
my ($gen, $git_dir, $out_dir, $rel_dir, %build_structure) = @_;
38+
return eval("Generators::${gen}::generate(\$git_dir, \$out_dir, \$rel_dir, \%build_structure)") if grep(/^$gen$/, @AVAILABLE);
39+
die "Generator \"${gen}\" is not available!\nAvailable generators are: @AVAILABLE\n";
40+
}
41+
42+
1;
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package Generators::QMake;
2+
require Exporter;
3+
4+
use strict;
5+
use vars qw($VERSION);
6+
7+
our $VERSION = '1.00';
8+
our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
9+
@ISA = qw(Exporter);
10+
11+
BEGIN {
12+
push @EXPORT_OK, qw(generate);
13+
}
14+
15+
sub generate {
16+
my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
17+
18+
my @libs = @{$build_structure{"LIBS"}};
19+
foreach (@libs) {
20+
createLibProject($_, $git_dir, $out_dir, $rel_dir, %build_structure);
21+
}
22+
23+
my @apps = @{$build_structure{"APPS"}};
24+
foreach (@apps) {
25+
createAppProject($_, $git_dir, $out_dir, $rel_dir, %build_structure);
26+
}
27+
28+
createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
29+
return 0;
30+
}
31+
32+
sub createLibProject {
33+
my ($libname, $git_dir, $out_dir, $rel_dir, %build_structure) = @_;
34+
print "Generate $libname lib project\n";
35+
$rel_dir = "../$rel_dir";
36+
37+
my $sources = join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"LIBS_${libname}_SOURCES"}})));
38+
my $defines = join(" \\\n\t", sort(@{$build_structure{"LIBS_${libname}_DEFINES"}}));
39+
my $includes= join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"LIBS_${libname}_INCLUDES"}})));
40+
my $cflags = join(" ", sort(@{$build_structure{"LIBS_${libname}_CFLAGS"}}));
41+
42+
my $cflags_debug = $cflags;
43+
$cflags_debug =~ s/-MT/-MTd/;
44+
$cflags_debug =~ s/-O.//;
45+
46+
my $cflags_release = $cflags;
47+
$cflags_release =~ s/-MTd/-MT/;
48+
49+
my @tmp = @{$build_structure{"LIBS_${libname}_LFLAGS"}};
50+
my @tmp2 = ();
51+
foreach (@tmp) {
52+
if (/^-LTCG/) {
53+
} elsif (/^-L/) {
54+
$_ =~ s/^-L/-LIBPATH:$rel_dir\//;
55+
}
56+
push(@tmp2, $_);
57+
}
58+
my $lflags = join(" ", sort(@tmp));
59+
60+
my $target = $libname;
61+
$target =~ s/\//_/g;
62+
$defines =~ s/-D//g;
63+
$defines =~ s/"/\\\\"/g;
64+
$includes =~ s/-I//g;
65+
mkdir "$target" || die "Could not create the directory $target for lib project!\n";
66+
open F, ">$target/$target.pro" || die "Could not open $target/$target.pro for writing!\n";
67+
print F << "EOM";
68+
TEMPLATE = lib
69+
TARGET = $target
70+
DESTDIR = $rel_dir
71+
72+
CONFIG -= qt
73+
CONFIG += static
74+
75+
QMAKE_CFLAGS =
76+
QMAKE_CFLAGS_RELEASE = $cflags_release
77+
QMAKE_CFLAGS_DEBUG = $cflags_debug
78+
QMAKE_LIBFLAGS = $lflags
79+
80+
DEFINES += \\
81+
$defines
82+
83+
INCLUDEPATH += \\
84+
$includes
85+
86+
SOURCES += \\
87+
$sources
88+
EOM
89+
close F;
90+
}
91+
92+
sub createAppProject {
93+
my ($appname, $git_dir, $out_dir, $rel_dir, %build_structure) = @_;
94+
print "Generate $appname app project\n";
95+
$rel_dir = "../$rel_dir";
96+
97+
my $sources = join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"APPS_${appname}_SOURCES"}})));
98+
my $defines = join(" \\\n\t", sort(@{$build_structure{"APPS_${appname}_DEFINES"}}));
99+
my $includes= join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"APPS_${appname}_INCLUDES"}})));
100+
my $cflags = join(" ", sort(@{$build_structure{"APPS_${appname}_CFLAGS"}}));
101+
102+
my $cflags_debug = $cflags;
103+
$cflags_debug =~ s/-MT/-MTd/;
104+
$cflags_debug =~ s/-O.//;
105+
106+
my $cflags_release = $cflags;
107+
$cflags_release =~ s/-MTd/-MT/;
108+
109+
my $libs;
110+
foreach (sort(@{$build_structure{"APPS_${appname}_LIBS"}})) {
111+
$_ =~ s/\//_/g;
112+
$libs .= " $_";
113+
}
114+
my @tmp = @{$build_structure{"APPS_${appname}_LFLAGS"}};
115+
my @tmp2 = ();
116+
foreach (@tmp) {
117+
# next if ($_ eq "-NODEFAULTLIB:MSVCRT.lib");
118+
if (/^-LTCG/) {
119+
} elsif (/^-L/) {
120+
$_ =~ s/^-L/-LIBPATH:$rel_dir\//;
121+
}
122+
push(@tmp2, $_);
123+
}
124+
my $lflags = join(" ", sort(@tmp));
125+
126+
my $target = $appname;
127+
$target =~ s/\.exe//;
128+
$target =~ s/\//_/g;
129+
$defines =~ s/-D//g;
130+
$defines =~ s/"/\\\\"/g;
131+
$includes =~ s/-I//g;
132+
mkdir "$target" || die "Could not create the directory $target for app project!\n";
133+
open F, ">$target/$target.pro" || die "Could not open $target/$target.pro for writing!\n";
134+
print F << "EOM";
135+
TEMPLATE = app
136+
TARGET = $target
137+
DESTDIR = $rel_dir
138+
139+
CONFIG -= qt embed_manifest_exe
140+
CONFIG += console
141+
142+
QMAKE_CFLAGS =
143+
QMAKE_CFLAGS_RELEASE = $cflags_release
144+
QMAKE_CFLAGS_DEBUG = $cflags_debug
145+
QMAKE_LFLAGS = $lflags
146+
LIBS = $libs
147+
148+
DEFINES += \\
149+
$defines
150+
151+
INCLUDEPATH += \\
152+
$includes
153+
154+
win32:QMAKE_LFLAGS += -LIBPATH:$rel_dir
155+
else: QMAKE_LFLAGS += -L$rel_dir
156+
157+
SOURCES += \\
158+
$sources
159+
EOM
160+
close F;
161+
}
162+
163+
sub createGlueProject {
164+
my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
165+
my $libs = join(" \\ \n", map("\t$_|$_.pro", @{$build_structure{"LIBS"}}));
166+
my $apps = join(" \\ \n", map("\t$_|$_.pro", @{$build_structure{"APPS"}}));
167+
$libs =~ s/\.a//g;
168+
$libs =~ s/\//_/g;
169+
$libs =~ s/\|/\//g;
170+
$apps =~ s/\.exe//g;
171+
$apps =~ s/\//_/g;
172+
$apps =~ s/\|/\//g;
173+
174+
my $filename = $out_dir;
175+
$filename =~ s/.*\/([^\/]+)$/$1/;
176+
$filename =~ s/\/$//;
177+
print "Generate glue project $filename.pro\n";
178+
open F, ">$filename.pro" || die "Could not open $filename.pro for writing!\n";
179+
print F << "EOM";
180+
TEMPLATE = subdirs
181+
CONFIG += ordered
182+
SUBDIRS += \\
183+
$libs \\
184+
$apps
185+
EOM
186+
close F;
187+
}
188+
189+
1;

0 commit comments

Comments
 (0)