blob: f9aadee65f9750393c57de5e8a4aaecdca0c21cc [file] [log] [blame]
Tim Peters84457af2006-03-09 01:59:27 +00001#include <windows.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <stdio.h>
Vinay Sajip5182c182012-05-04 20:51:59 +01005#include <io.h>
Tim Peters84457af2006-03-09 01:59:27 +00006
Christian Heimes5b5e81c2007-12-31 16:14:33 +00007#define CMD_SIZE 500
8
Tim Peters84457af2006-03-09 01:59:27 +00009/* This file creates the getbuildinfo.o object, by first
10 invoking subwcrev.exe (if found), and then invoking cl.exe.
11 As a side effect, it might generate PCBuild\getbuildinfo2.c
12 also. If this isn't a subversion checkout, or subwcrev isn't
13 found, it compiles ..\\Modules\\getbuildinfo.c instead.
14
15 Currently, subwcrev.exe is found from the registry entries
16 of TortoiseSVN.
17
18 No attempt is made to place getbuildinfo.o into the proper
19 binary directory. This isn't necessary, as this tool is
20 invoked as a pre-link step for pythoncore, so that overwrites
21 any previous getbuildinfo.o.
22
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +000023 However, if a second argument is provided, this will be used
24 as a temporary directory where any getbuildinfo2.c and
25 getbuildinfo.o files are put. This is useful if multiple
26 configurations are being built in parallel, to avoid them
27 trampling each other's files.
28
Tim Peters84457af2006-03-09 01:59:27 +000029*/
30
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +000031int make_buildinfo2(const char *tmppath)
Tim Peters84457af2006-03-09 01:59:27 +000032{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 struct _stat st;
34 HKEY hTortoise;
35 char command[CMD_SIZE+1];
36 DWORD type, size;
37 if (_stat(".svn", &st) < 0)
38 return 0;
39 /* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */
40 if (_stat("no_subwcrev", &st) == 0)
41 return 0;
42 if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS &&
43 RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS)
44 /* Tortoise not installed */
45 return 0;
46 command[0] = '"'; /* quote the path to the executable */
47 size = sizeof(command) - 1;
48 if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS ||
49 type != REG_SZ)
50 /* Registry corrupted */
51 return 0;
52 strcat_s(command, CMD_SIZE, "bin\\subwcrev.exe");
53 if (_stat(command+1, &st) < 0)
54 /* subwcrev.exe not part of the release */
55 return 0;
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +000056 strcat_s(command, CMD_SIZE, "\" .. ..\\Modules\\getbuildinfo.c \"");
57 strcat_s(command, CMD_SIZE, tmppath); /* quoted tmppath */
58 strcat_s(command, CMD_SIZE, "getbuildinfo2.c\"");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 puts(command); fflush(stdout);
60 if (system(command) < 0)
61 return 0;
62 return 1;
Tim Peters84457af2006-03-09 01:59:27 +000063}
64
Vinay Sajip5182c182012-05-04 20:51:59 +010065const char DELIMS[] = { " \n" };
66
67int get_mercurial_info(char * hgbranch, char * hgtag, char * hgrev, int size)
68{
69 int result = 0;
70 char filename[CMD_SIZE];
71 char cmdline[CMD_SIZE];
72
73 strcpy_s(filename, CMD_SIZE, "tmpXXXXXX");
74 if (_mktemp_s(filename, CMD_SIZE) == 0) {
75 int rc;
76
77 strcpy_s(cmdline, CMD_SIZE, "hg id -bit > ");
78 strcat_s(cmdline, CMD_SIZE, filename);
79 rc = system(cmdline);
80 if (rc == 0) {
81 FILE * fp;
82
83 if (fopen_s(&fp, filename, "r") == 0) {
84 char * cp = fgets(cmdline, CMD_SIZE, fp);
85
86 if (cp) {
87 char * context = NULL;
88 char * tp = strtok_s(cp, DELIMS, &context);
89 if (tp) {
90 strcpy_s(hgrev, size, tp);
91 tp = strtok_s(NULL, DELIMS, &context);
92 if (tp) {
93 strcpy_s(hgbranch, size, tp);
94 tp = strtok_s(NULL, DELIMS, &context);
95 if (tp) {
96 strcpy_s(hgtag, size, tp);
97 result = 1;
98 }
99 }
100 }
101 }
102 fclose(fp);
103 }
104 }
105 _unlink(filename);
106 }
107 return result;
108}
109
Tim Peters84457af2006-03-09 01:59:27 +0000110int main(int argc, char*argv[])
111{
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000112 char command[CMD_SIZE] = "cl.exe -c -D_WIN32 -DUSE_DL_EXPORT -D_WINDOWS -DWIN32 -D_WINDLL ";
113 char tmppath[CMD_SIZE] = "";
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 int do_unlink, result;
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000115 char *tmpdir = NULL;
116 if (argc <= 2 || argc > 3) {
117 fprintf(stderr, "make_buildinfo $(ConfigurationName) [tmpdir]\n");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 return EXIT_FAILURE;
119 }
120 if (strcmp(argv[1], "Release") == 0) {
121 strcat_s(command, CMD_SIZE, "-MD ");
122 }
123 else if (strcmp(argv[1], "Debug") == 0) {
124 strcat_s(command, CMD_SIZE, "-D_DEBUG -MDd ");
125 }
126 else if (strcmp(argv[1], "ReleaseItanium") == 0) {
127 strcat_s(command, CMD_SIZE, "-MD /USECL:MS_ITANIUM ");
128 }
129 else if (strcmp(argv[1], "ReleaseAMD64") == 0) {
130 strcat_s(command, CMD_SIZE, "-MD ");
131 strcat_s(command, CMD_SIZE, "-MD /USECL:MS_OPTERON ");
132 }
133 else {
134 fprintf(stderr, "unsupported configuration %s\n", argv[1]);
135 return EXIT_FAILURE;
136 }
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000137 if (argc > 2) {
138 tmpdir = argv[2];
139 strcat_s(tmppath, _countof(tmppath), tmpdir);
Kristján Valur Jónsson8d28a922010-12-13 03:32:10 +0000140 /* Hack fix for bad command line: If the command is issued like this:
141 * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)"
142 * we will get a trailing quote because IntDir ends with a backslash that then
143 * escapes the final ". To simplify the life for developers, catch that problem
144 * here by cutting it off.
145 * The proper command line, btw is:
146 * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\"
147 * Hooray for command line parsing on windows.
148 */
149 if (strlen(tmppath) > 0 && tmppath[strlen(tmppath)-1] == '"')
150 tmppath[strlen(tmppath)-1] = '\0';
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000151 strcat_s(tmppath, _countof(tmppath), "\\");
152 }
Tim Peters84457af2006-03-09 01:59:27 +0000153
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000154 if ((do_unlink = make_buildinfo2(tmppath))) {
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +0000155 strcat_s(command, CMD_SIZE, "\"");
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000156 strcat_s(command, CMD_SIZE, tmppath);
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +0000157 strcat_s(command, CMD_SIZE, "getbuildinfo2.c\" -DSUBWCREV ");
Vinay Sajip5182c182012-05-04 20:51:59 +0100158 }
159 else {
160 char hgtag[CMD_SIZE];
161 char hgbranch[CMD_SIZE];
162 char hgrev[CMD_SIZE];
163
164 if (get_mercurial_info(hgbranch, hgtag, hgrev, CMD_SIZE)) {
165 strcat_s(command, CMD_SIZE, "-DHGBRANCH=\\\"");
166 strcat_s(command, CMD_SIZE, hgbranch);
167 strcat_s(command, CMD_SIZE, "\\\"");
168
169 strcat_s(command, CMD_SIZE, " -DHGTAG=\\\"");
170 strcat_s(command, CMD_SIZE, hgtag);
171 strcat_s(command, CMD_SIZE, "\\\"");
172
173 strcat_s(command, CMD_SIZE, " -DHGVERSION=\\\"");
174 strcat_s(command, CMD_SIZE, hgrev);
175 strcat_s(command, CMD_SIZE, "\\\" ");
176 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 strcat_s(command, CMD_SIZE, "..\\Modules\\getbuildinfo.c");
Vinay Sajip5182c182012-05-04 20:51:59 +0100178 }
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +0000179 strcat_s(command, CMD_SIZE, " -Fo\"");
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000180 strcat_s(command, CMD_SIZE, tmppath);
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +0000181 strcat_s(command, CMD_SIZE, "getbuildinfo.o\" -I..\\Include -I..\\PC");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 puts(command); fflush(stdout);
183 result = system(command);
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000184 if (do_unlink) {
185 command[0] = '\0';
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +0000186 strcat_s(command, CMD_SIZE, "\"");
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000187 strcat_s(command, CMD_SIZE, tmppath);
Kristján Valur Jónsson60fafa22010-11-22 11:37:06 +0000188 strcat_s(command, CMD_SIZE, "getbuildinfo2.c\"");
Kristján Valur Jónsson33d144a2010-11-03 13:57:00 +0000189 _unlink(command);
190 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 if (result < 0)
192 return EXIT_FAILURE;
193 return 0;
194}