aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/mhmake/mhmake.vcproj12
-rw-r--r--tools/mhmake/src/Makefile.am3
-rw-r--r--tools/mhmake/src/build.cpp201
-rw-r--r--tools/mhmake/src/commandqueue.cpp69
-rw-r--r--tools/mhmake/src/commandqueue.h10
-rw-r--r--tools/mhmake/src/fileinfo.h5
-rw-r--r--tools/mhmake/src/functions.cpp7
-rw-r--r--tools/mhmake/src/mhmakefileparser.cpp61
-rw-r--r--tools/mhmake/src/mhmakefileparser.h30
-rw-r--r--tools/mhmake/src/util.cpp8
10 files changed, 290 insertions, 116 deletions
diff --git a/tools/mhmake/mhmake.vcproj b/tools/mhmake/mhmake.vcproj
index 83ba31e6d..b8ea6a674 100644
--- a/tools/mhmake/mhmake.vcproj
+++ b/tools/mhmake/mhmake.vcproj
@@ -984,11 +984,19 @@
Filter="cpp;h"
>
<File
- RelativePath="$(OutDir)\mhmakeLexer.cpp"
+ RelativePath="$(OutDir)\mhmakelexer.cpp"
>
</File>
<File
- RelativePath="$(OutDir)\mhmakeParser.cpp"
+ RelativePath="$(OutDir)\mhmakelexer.h"
+ >
+ </File>
+ <File
+ RelativePath="$(OutDir)\mhmakeparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(OutDir)\mhmakeparser.h"
>
</File>
</Filter>
diff --git a/tools/mhmake/src/Makefile.am b/tools/mhmake/src/Makefile.am
index be46f3bd6..0478f1645 100644
--- a/tools/mhmake/src/Makefile.am
+++ b/tools/mhmake/src/Makefile.am
@@ -1,5 +1,6 @@
SRCS = mhmakeparser.y mhmakelexer.l mhmake.cpp mhmakefileparser.cpp util.cpp \
- functions.cpp fileinfo.cpp rule.cpp md5.c build.cpp curdir.cpp
+ functions.cpp fileinfo.cpp rule.cpp md5.c build.cpp curdir.cpp \
+ commandqueue.cpp
if DEBUG
bin_PROGRAMS=mhmake_dbg
diff --git a/tools/mhmake/src/build.cpp b/tools/mhmake/src/build.cpp
index d14f00ff3..064ffe6c9 100644
--- a/tools/mhmake/src/build.cpp
+++ b/tools/mhmake/src/build.cpp
@@ -333,7 +333,7 @@ static bool DeleteDir(const string &Dir,const string WildSearch="*",bool bRemove
string Pattern=Dir+OSPATHSEP+WildSearch;
#ifdef WIN32
WIN32_FIND_DATA FindData;
- HANDLE hFind=FindFirstFile(Pattern.c_str(),&FindData);
+ mh_pid_t hFind=FindFirstFile(Pattern.c_str(),&FindData);
if (hFind==INVALID_HANDLE_VALUE)
{
return Error;
@@ -389,7 +389,7 @@ static bool DeleteDir(const string &Dir,const string WildSearch="*",bool bRemove
}
/*****************************************************************************/
-HANDLE mhmakefileparser::DeleteFiles(const string &Params) const
+mh_pid_t mhmakefileparser::DeleteFiles(const string &Params) const
{
bool IgnoreError=false;
vector< refptr<fileinfo> > Files;
@@ -405,7 +405,7 @@ HANDLE mhmakefileparser::DeleteFiles(const string &Params) const
else
{
cerr << "Invalid option "<<Params[1]<<" in del statement\n";
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
}
else
@@ -448,11 +448,11 @@ HANDLE mhmakefileparser::DeleteFiles(const string &Params) const
if (-1==remove(FileName.c_str()) && !IgnoreError)
{
cerr << "Error deleting "<<FileName<<endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
}
}
- return (HANDLE)0;
+ return (mh_pid_t)0;
}
/*****************************************************************************/
@@ -500,7 +500,7 @@ static bool CopyDir(refptr<fileinfo> pDir,refptr<fileinfo> pDest,const string Wi
string Pattern=pDir->GetFullFileName()+OSPATHSEP+WildSearch;
#ifdef WIN32
WIN32_FIND_DATA FindData;
- HANDLE hFind=FindFirstFile(Pattern.c_str(),&FindData);
+ mh_pid_t hFind=FindFirstFile(Pattern.c_str(),&FindData);
if (hFind==INVALID_HANDLE_VALUE)
{
return false;
@@ -554,7 +554,7 @@ exit:
for (int i=0; i<Res.gl_pathc; i++)
{
- refptr<fileinfo> pSrc=GetFileInfo(Res.gl_pathv[i]);
+ refptr<fileinfo> pSrc=GetFileInfo(Res.gl_pathv[i],pDir);
if (pSrc->IsDir())
{
*(strrchr(Res.gl_pathv[i],'/'))='\0';
@@ -585,7 +585,7 @@ exit:
}
else
{
- Error = CopyFile(GetFileInfo(Res.gl_pathv[i]),pDest);
+ Error = CopyFile(GetFileInfo(Res.gl_pathv[i],pDir),pDest);
if (!Error) goto exit;
}
}
@@ -598,7 +598,7 @@ exit:
}
/*****************************************************************************/
-HANDLE mhmakefileparser::EchoCommand(const string &Params) const
+mh_pid_t mhmakefileparser::EchoCommand(const string &Params) const
{
// Find the first > character
size_t Pos=Params.find_first_of('>');
@@ -628,7 +628,7 @@ HANDLE mhmakefileparser::EchoCommand(const string &Params) const
if (!pfFile)
{
cerr << "Error opening file "<<Filename<<endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
int Begin=0;
while (Params[Begin]==' ' || Params[Begin] == '\t') Begin++; // Strip leading white space
@@ -636,15 +636,15 @@ HANDLE mhmakefileparser::EchoCommand(const string &Params) const
if (EchoStr.length()!=fwrite(EchoStr.c_str(),1,EchoStr.length(),pfFile))
{
cerr << "Error writing file "<<Filename<<endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
fclose(pfFile);
}
- return (HANDLE)0;
+ return (mh_pid_t)0;
}
/*****************************************************************************/
-HANDLE mhmakefileparser::CopyFiles(const string &Params) const
+mh_pid_t mhmakefileparser::CopyFiles(const string &Params) const
{
vector< refptr<fileinfo> > Files;
@@ -662,7 +662,7 @@ HANDLE mhmakefileparser::CopyFiles(const string &Params) const
if (NrSrcs>1 && !pDest->IsDir())
{
cerr << "copy: Destination must be a directory when more then one source : "<<Params<<endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
for (size_t i=0; i<NrSrcs; i++)
@@ -684,7 +684,7 @@ HANDLE mhmakefileparser::CopyFiles(const string &Params) const
if (!CopyDir(pSrc->GetDir(), pDest, pSrc->GetName()))
{
cerr << "copy: Error copying directory: " << Params << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
}
else
@@ -692,17 +692,17 @@ HANDLE mhmakefileparser::CopyFiles(const string &Params) const
if (!CopyFile(pSrc,pDest))
{
cerr << "copy: Error copying file: " << Params << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
}
}
- return (HANDLE)0;
+ return (mh_pid_t)0;
}
/*****************************************************************************/
-HANDLE mhmakefileparser::TouchFiles(const string &Params) const
+mh_pid_t mhmakefileparser::TouchFiles(const string &Params) const
{
vector< refptr<fileinfo> > Files;
@@ -722,7 +722,7 @@ HANDLE mhmakefileparser::TouchFiles(const string &Params) const
if (pFile->IsDir())
{
cerr << "touch: Cannot touch a directory: " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
if (pFile->Exists())
{
@@ -743,7 +743,7 @@ HANDLE mhmakefileparser::TouchFiles(const string &Params) const
if (fstat (fd, &st) < 0)
{
cerr << "touch: Cannot stat file " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
}
@@ -753,14 +753,14 @@ HANDLE mhmakefileparser::TouchFiles(const string &Params) const
if (fd>=0 && close(fd) < 0)
{
cerr << "touch: Error closing file " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
/*Re-Create an empty file */
pFile=fopen(FileName.c_str(),"wb");
if (!pFile)
{
cerr << "touch: Cannot create file: " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
fclose(pFile);
}
@@ -770,22 +770,22 @@ HANDLE mhmakefileparser::TouchFiles(const string &Params) const
if (Ret!=sizeof(c) && Ret!=EOF)
{
cerr << "touch: Cannot read file " << FileName << ": "<<Ret<<endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
if (lseek (fd, (off_t) 0, SEEK_SET) < 0)
{
cerr << "touch: Error changing file pointer " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
if (write (fd, &c, sizeof c) != sizeof(c))
{
cerr << "touch: Error writing file " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
if (close (fd) < 0)
{
cerr << "touch: Error closing file " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
}
}
@@ -796,13 +796,13 @@ HANDLE mhmakefileparser::TouchFiles(const string &Params) const
if (!pFile)
{
cerr << "touch: Cannot create file: " << FileName << endl;
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
fclose(pFile);
}
pFile->InvalidateDate();
}
- return (HANDLE)0;
+ return (mh_pid_t)0;
}
/*****************************************************************************/
@@ -983,7 +983,7 @@ string mhmakefileparser::GetFullCommand(string Command)
return pFound->second;
}
-HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const
+mh_pid_t mhmakefileparser::OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const
{
string FullCommandLine;
string ComSpec=GetComspec();
@@ -1012,12 +1012,12 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
if (pOutput || g_Quiet)
{
- HANDLE hChildStdinRd;
- HANDLE hChildStdinWr;
- HANDLE hChildStdoutRd;
- HANDLE hChildStdoutWr;
- HANDLE hChildStdinWrDup;
- HANDLE hChildStdoutRdDup;
+ mh_pid_t hChildStdinRd;
+ mh_pid_t hChildStdinWr;
+ mh_pid_t hChildStdoutRd;
+ mh_pid_t hChildStdoutWr;
+ mh_pid_t hChildStdinWrDup;
+ mh_pid_t hChildStdoutRdDup;
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
@@ -1026,7 +1026,7 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
- return false;
+ return (mh_pid_t)-1;
/* Create new output read handle and the input write handle. Set
* the inheritance properties to FALSE. Otherwise, the child inherits
@@ -1035,17 +1035,17 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, DUPLICATE_SAME_ACCESS);
- if (!fSuccess) return false;
+ if (!fSuccess) return (mh_pid_t)-1;
/* Close the inheritable version of ChildStdin that we're using. */
CloseHandle(hChildStdinWr);
if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
- return false;
+ return (mh_pid_t)-1;
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup, 0,
FALSE, DUPLICATE_SAME_ACCESS);
- if (!fSuccess) return false;
+ if (!fSuccess) return (mh_pid_t)-1;
CloseHandle(hChildStdoutRd);
int hStdIn = _open_osfhandle((long)hChildStdinWrDup, _O_WRONLY|_O_TEXT);
@@ -1068,8 +1068,8 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
throw ErrorMessage;
}
delete[] pFullCommand;
- if (!CloseHandle(hChildStdinRd)) return false;
- if (!CloseHandle(hChildStdoutWr)) return false;
+ if (!CloseHandle(hChildStdinRd)) return (mh_pid_t)-1;
+ if (!CloseHandle(hChildStdoutWr)) return (mh_pid_t)-1;
CloseHandle(ProcessInfo.hThread);
char Buf[256];
@@ -1092,13 +1092,13 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
if (IgnoreError)
{
cerr << "Error running command: "<<Command<<", but ignoring error\n";
- return (HANDLE)0; // Ignore error
+ return (mh_pid_t)0; // Ignore error
}
else
- return (HANDLE)-1;
+ return (mh_pid_t)-1;
}
CloseHandle(ProcessInfo.hProcess);
- return (HANDLE)0;
+ return (mh_pid_t)0;
}
else
{
@@ -1116,9 +1116,6 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
return ProcessInfo.hProcess;
}
#else
- int pipeto[2]; /* pipe to feed the exec'ed program input */
- int pipefrom[2]; /* pipe to get the exec'ed program output */
-
if (Command.substr(0,ComSpec.size())==ComSpec)
{
string tmpCommand=Command.substr(ComSpec.size(),Command.size());
@@ -1132,28 +1129,28 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
if (pOutput || g_Quiet)
{
+ int pipeto[2]; /* pipe to feed the exec'ed program input */
+ int pipefrom[2]; /* pipe to get the exec'ed program output */
+
pipe( pipeto );
pipe( pipefrom );
- }
- pid_t ID=vfork();
- if (ID==-1)
- {
- if (IgnoreError)
+ pid_t ID=vfork();
+ if (ID==-1)
{
- cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
- return true; // Ignore error
+ if (IgnoreError)
+ {
+ cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
}
- else
- return false;
- }
- else if (ID==0)
- {
- int argc;
- const char **pargv;
-
- if (pOutput || g_Quiet)
+ else if (ID==0)
{
+ int argc;
+ const char **pargv;
+
dup2( pipeto[0], STDIN_FILENO );
dup2( pipefrom[1], STDOUT_FILENO );
/* close unnecessary pipe descriptors for a clean environment */
@@ -1161,15 +1158,17 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
close( pipeto[1] );
close( pipefrom[0] );
close( pipefrom[1] );
- }
- poptParseArgvString(FullCommandLine.c_str(), &argc, &pargv);
- execv(pargv[0],(char *const*)pargv);
- _exit (EXIT_FAILURE);
- }
- else
- {
- if (pOutput || g_Quiet)
+ poptParseArgvString(FullCommandLine.c_str(), &argc, &pargv);
+ chdir(m_MakeDir->GetFullFileName().c_str());
+ if (m_pEnv)
+ execve(pargv[0],(char *const*)pargv,m_pEnv);
+ else
+ execv(pargv[0],(char *const*)pargv);
+ free(pargv);
+ _exit (EXIT_FAILURE);
+ }
+ else
{
/* Close unused pipe ends. This is especially important for the
* pipefrom[1] write descriptor, otherwise readFromPipe will never
@@ -1183,16 +1182,16 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
if (IgnoreError)
{
cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
- return true; // Ignore error
+ return (mh_pid_t)0; // Ignore error
}
else
- return false;
+ return (mh_pid_t)-1;
}
else if (ID2==0)
{
/* Close pipe write descriptor, or we will never know when the
- * writer process closes its end of the pipe and stops feeding the
- * exec'ed program. */
+ * writer process closes its end of the pipe and stops feeding the
+ * exec'ed program. */
close( pipeto[1] );
char Buf[256];
int Nbr;
@@ -1216,21 +1215,55 @@ HANDLE mhmakefileparser::OsExeCommand(const string &Command, const string &Param
int Status;
waitpid(ID2,&Status,0); // Wait until the reading of the output is finished
}
+
+ int Status;
+ int Ret=waitpid(ID,&Status,0);
+ if (Ret!=ID || Status)
+ {
+ if (IgnoreError)
+ {
+ cerr << "Error running command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
+ }
}
- int Status;
- int Ret=waitpid(ID,&Status,0);
- if (Ret!=ID || Status)
+ }
+ else
+ { // No pOutput
+ pid_t ID=fork();
+ if (ID==-1)
{
if (IgnoreError)
{
- cerr << "Error running command: "<<Command<<", but ignoring error\n";
- return true; // Ignore error
+ cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
}
else
- return false;
+ return (mh_pid_t)-1;
+ }
+ else if (ID==0)
+ {
+ int argc;
+ const char **pargv;
+
+ poptParseArgvString(FullCommandLine.c_str(), &argc, &pargv);
+ chdir(m_MakeDir->GetFullFileName().c_str());
+ if (m_pEnv)
+ execve(pargv[0],(char *const*)pargv,m_pEnv);
+ else
+ execv(pargv[0],(char *const*)pargv);
+ free(pargv);
+ _exit (EXIT_FAILURE);
+ }
+ else
+ {
+ return (mh_pid_t)ID;
}
}
- return true;
+
+ return (mh_pid_t)0;
#endif
}
@@ -1278,7 +1311,7 @@ string EscapeQuotes(const string &Params)
#endif
///////////////////////////////////////////////////////////////////////////////
-HANDLE mhmakefileparser::ExecuteCommand(string Command, bool &IgnoreError, string *pOutput)
+mh_pid_t mhmakefileparser::ExecuteCommand(string Command, bool &IgnoreError, string *pOutput)
{
bool Echo=true;
IgnoreError=false;
@@ -1398,7 +1431,7 @@ HANDLE mhmakefileparser::ExecuteCommand(string Command, bool &IgnoreError, strin
#ifdef _DEBUG
}
#endif
- return (HANDLE)0; /* No Error */
+ return (mh_pid_t)0; /* No Error */
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/tools/mhmake/src/commandqueue.cpp b/tools/mhmake/src/commandqueue.cpp
index 484d577a5..ae7645708 100644
--- a/tools/mhmake/src/commandqueue.cpp
+++ b/tools/mhmake/src/commandqueue.cpp
@@ -23,14 +23,67 @@
#include "commandqueue.h"
#include "mhmakeparser.h"
+#ifndef WIN32
+
+#define INFINITE 0
+#define FALSE 0
+
+static int Status;
+unsigned WaitForMultipleObjects(int Nbr, mh_pid_t *phProcesses, int, int)
+{
+ mh_pid_t ID=waitpid(0,&Status,0);
+ for (int i=0; i<Nbr; i++)
+ {
+ if (ID==phProcesses[i])
+ return i;
+ }
+ return -1;
+}
+
+typedef unsigned DWORD;
+
+int GetExitCodeProcess(mh_pid_t hProcess, DWORD *pExitCode)
+{
+ *pExitCode=Status;
+ return true;
+}
+
+#define CloseHandle(Handle)
+
+#endif
+
+
commandqueue::commandqueue() :
m_NrActiveEntries(0)
{
+#ifdef WIN32
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
m_MaxNrCommandsInParallel=SysInfo.dwNumberOfProcessors;
+#else
+ FILE *pFile=fopen("/proc/cpuinfo","r");
+ const char *pProc="\nprocessor";
+ int cur=1;
+ int NrProcs=0;
+ while (!feof(pFile))
+ {
+ char In=fgetc(pFile);
+ if (In==pProc[cur])
+ {
+ cur++;
+ if (!pProc[cur])
+ {
+ NrProcs++;
+ cur=0;
+ }
+ }
+ else
+ cur=0;
+ }
+ m_MaxNrCommandsInParallel=NrProcs;
+#endif
- m_pActiveProcesses=new HANDLE[m_MaxNrCommandsInParallel];
+ m_pActiveProcesses=new mh_pid_t[m_MaxNrCommandsInParallel];
m_pActiveEntries= new activeentry[m_MaxNrCommandsInParallel];
}
@@ -44,11 +97,11 @@ void commandqueue::SetNrParallelBuilds(unsigned NrParallelBuilds)
{
if (m_NrActiveEntries)
throw("Changing of number of parallel builds is only allowed when no commands are executing");
- NrParallelBuilds=max(1,NrParallelBuilds);
+ NrParallelBuilds=max(1u,NrParallelBuilds);
m_MaxNrCommandsInParallel=NrParallelBuilds;
delete [] m_pActiveProcesses;
delete [] m_pActiveEntries;
- m_pActiveProcesses=new HANDLE[NrParallelBuilds];
+ m_pActiveProcesses=new mh_pid_t[NrParallelBuilds];
m_pActiveEntries= new activeentry[NrParallelBuilds];
}
@@ -86,7 +139,7 @@ void commandqueue::RemoveActiveEntry(unsigned Entry)
/* Start to execute next command, return true when command is completely executed
upon return */
-bool commandqueue::StartExecuteNextCommand(activeentry *pActiveEntry, HANDLE *pActiveProcess)
+bool commandqueue::StartExecuteNextCommand(activeentry *pActiveEntry, mh_pid_t *pActiveProcess)
{
refptr<fileinfo> pTarget=pActiveEntry->pTarget;
mhmakeparser *pMakefile=pTarget->GetRule()->GetMakefile();
@@ -106,8 +159,8 @@ bool commandqueue::StartExecuteNextCommand(activeentry *pActiveEntry, HANDLE *pA
if (!g_GenProjectTree)
{
#endif
- HANDLE hProcess=pMakefile->ExecuteCommand(Command,pActiveEntry->IgnoreError);
- if (hProcess==(HANDLE)-1)
+ mh_pid_t hProcess=pMakefile->ExecuteCommand(Command,pActiveEntry->IgnoreError);
+ if (hProcess==(mh_pid_t)-1)
{
ThrowCommandExecutionError(pActiveEntry);
}
@@ -235,7 +288,7 @@ mh_time_t commandqueue::WaitForTarget(const refptr<fileinfo> &pTarget)
while (1)
{
// First wait until one of the processes that are running is finished
- DWORD Ret=WaitForMultipleObjects(m_NrActiveEntries,m_pActiveProcesses,FALSE,INFINITE);
+ unsigned Ret=WaitForMultipleObjects(m_NrActiveEntries,m_pActiveProcesses,FALSE,INFINITE);
if (Ret>=m_NrActiveEntries)
throw("fatal error: unexpected return value of WaitForMultipleObjects " + stringify(Ret));
activeentry *pActiveEntry=&m_pActiveEntries[Ret];
@@ -244,7 +297,7 @@ mh_time_t commandqueue::WaitForTarget(const refptr<fileinfo> &pTarget)
// First check the error code of the command
DWORD ExitCode=0;
- HANDLE hProcess=m_pActiveProcesses[Ret];
+ mh_pid_t hProcess=m_pActiveProcesses[Ret];
if (!GetExitCodeProcess(hProcess,&ExitCode) || ExitCode)
{
if (pActiveEntry->IgnoreError)
diff --git a/tools/mhmake/src/commandqueue.h b/tools/mhmake/src/commandqueue.h
index 1e70e3cb6..7480d63dd 100644
--- a/tools/mhmake/src/commandqueue.h
+++ b/tools/mhmake/src/commandqueue.h
@@ -23,6 +23,12 @@
#include "fileinfo.h"
+#ifdef WIN32
+typedef HANDLE mh_pid_t;
+#else
+typedef pid_t mh_pid_t;
+#endif
+
class commandqueue
{
struct activeentry
@@ -36,7 +42,7 @@ class commandqueue
private:
queue< refptr<fileinfo> > m_Queue;
unsigned m_MaxNrCommandsInParallel;
- HANDLE *m_pActiveProcesses;
+ mh_pid_t *m_pActiveProcesses;
activeentry *m_pActiveEntries;
unsigned m_NrActiveEntries;
@@ -44,7 +50,7 @@ private:
void ThrowCommandExecutionError(activeentry *pActiveEntry);
void RemoveActiveEntry(unsigned Entry);
bool StartExecuteCommands(const refptr<fileinfo> &pTarget);
- bool StartExecuteNextCommand(activeentry *pActiveEntry, HANDLE *pActiveProcess);
+ bool StartExecuteNextCommand(activeentry *pActiveEntry, mh_pid_t *pActiveProcess);
void TargetBuildFinished(activeentry *pActiveEntry);
public:
diff --git a/tools/mhmake/src/fileinfo.h b/tools/mhmake/src/fileinfo.h
index 146ade02b..16ca414e2 100644
--- a/tools/mhmake/src/fileinfo.h
+++ b/tools/mhmake/src/fileinfo.h
@@ -81,10 +81,7 @@ class mh_time
bool operator < (const mh_time &Src);
public:
mh_time(){m_Time=DATENOTVALID;}
-#ifdef WIN32
- mh_time(unsigned __int64 Time) : m_Time((unsigned long)(Time&0xffffffff)) {}
- mh_time(__int64 Time) : m_Time((unsigned long)(Time&0xffffffff)) {}
-#endif
+ mh_time(time_t Time) : m_Time((unsigned long)Time) {}
mh_time(unsigned long Time) : m_Time(Time) {}
mh_time(const mh_time &Time) : m_Time(Time.m_Time) {}
diff --git a/tools/mhmake/src/functions.cpp b/tools/mhmake/src/functions.cpp
index b4ea64783..b1a5f7a46 100644
--- a/tools/mhmake/src/functions.cpp
+++ b/tools/mhmake/src/functions.cpp
@@ -378,17 +378,18 @@ string mhmakefileparser::f_wildcard(const string & Arg) const
_findclose(hFile);
#else
glob_t Res;
- if (glob (FileSpec.c_str(), GLOB_ERR|GLOB_NOSORT|GLOB_MARK, NULL, &Res))
+ if (glob (FileSpec->GetFullFileName().c_str(), GLOB_ERR|GLOB_NOSORT|GLOB_MARK, NULL, &Res))
return g_EmptyString;
string Ret=g_EmptyString;
string SepStr=g_EmptyString;
+ string CheckSpec=FileSpec->GetName();
for (int i=0; i<Res.gl_pathc; i++)
{
- if (PercentMatch(Res.gl_pathv[i],FileSpec,NULL,'*'))
+ if (PercentMatch(Res.gl_pathv[i],CheckSpec,NULL,'*'))
{
Ret+=SepStr;
- Ret+=Res.gl_pathv[i];
+ Ret+=GetFileInfo(Res.gl_pathv[i],Dir)->GetQuotedFullFileName();
SepStr=g_SpaceString;
}
}
diff --git a/tools/mhmake/src/mhmakefileparser.cpp b/tools/mhmake/src/mhmakefileparser.cpp
index 76e43f475..e9d50a704 100644
--- a/tools/mhmake/src/mhmakefileparser.cpp
+++ b/tools/mhmake/src/mhmakefileparser.cpp
@@ -415,12 +415,21 @@ void mhmakefileparser::PrintVariables(bool Expand) const
if (m_pEnv)
{
cout << "Environment overruled:\n";
+#ifdef WIN32
char *pEnv=m_pEnv;
while (*pEnv)
{
cout<<pEnv<<endl;
pEnv+=strlen(pEnv)+1;
}
+#else
+ char **pEnv=m_pEnv;
+ while (*pEnv)
+ {
+ cout<<*pEnv<<endl;
+ pEnv++;
+ }
+#endif
}
}
#endif
@@ -871,6 +880,7 @@ bool mhmakefileparser::SkipHeaderFile(const string &FileName)
///////////////////////////////////////////////////////////////////////////////
void mhmakefileparser::SetExport(const string &Var, const string &Val)
{
+#ifdef WIN32
if (!m_pEnv)
{
/* Environment not created yet, so create one */
@@ -930,6 +940,57 @@ void mhmakefileparser::SetExport(const string &Var, const string &Val)
*pEnv++='\0';
*pEnv++='\0';
m_EnvLen+=Extra;
+#else
+ if (!m_pEnv)
+ {
+ /* Environment not created yet, so create one */
+ char **pEnv=environ;
+ char **pEnd=pEnv;
+ int Len=1;
+ while (*pEnd)
+ {
+ Len++;
+ pEnd++;
+ }
+ m_EnvLen=Len;
+ m_pEnv=(char**)malloc(Len*sizeof(pEnv));
+ int i=0;
+ while (*pEnv)
+ {
+ m_pEnv[i]=strdup(*pEnv);
+ i++;
+ pEnv++;
+ }
+ m_pEnv[i]=NULL;
+ }
+ /* First check if the variable is in the environment, if so replace it */
+ char **pEnv=m_pEnv;
+ while (*pEnv)
+ {
+ const char *pVar=Var.c_str();
+ char *pStart=*pEnv;
+ char *pTmp=pStart;
+ while (*pTmp!='=' && *pTmp==*pVar)
+ {
+ pTmp++; pVar++;
+ }
+ if (*pTmp=='=' && !*pVar)
+ {
+ free(*pEnv);
+ *pEnv=strdup((Var+"="+Val).c_str());
+ break;
+ }
+ pEnv++;
+ }
+ if (!*pEnv)
+ {
+ // Add it at the end of the list
+ m_pEnv=(char**)realloc(m_pEnv,(m_EnvLen+1)*sizeof(*pEnv));
+ m_pEnv[m_EnvLen-1]=strdup((Var+"="+Val).c_str());
+ m_pEnv[m_EnvLen++]=NULL;
+ }
+
+#endif
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/tools/mhmake/src/mhmakefileparser.h b/tools/mhmake/src/mhmakefileparser.h
index acf27987b..43bcad538 100644
--- a/tools/mhmake/src/mhmakefileparser.h
+++ b/tools/mhmake/src/mhmakefileparser.h
@@ -81,7 +81,7 @@ protected:
fileinfoarray m_IncludedMakefiles;
refptr<fileinfoarray> m_pIncludeDirs;
string m_IncludeDirs;
-
+
bool m_DoubleColonRule;
bool m_AutoDepsDirty;
bool m_ForceAutoDepRescan;
@@ -92,7 +92,11 @@ protected:
bool m_RebuildAll; /* true when to rebuild all targets of this makefile */
set<string> m_UsedEnvVars; // Array containing a list of variables that are taken from the environment (This is used for rebuild checking)
+#ifdef WIN32
char *m_pEnv; // New environment in case the makefile exports variables
+#else
+ char **m_pEnv; // New environment in case the makefile exports variables
+#endif
int m_EnvLen; // Current length of m_pEnv
map< refptr<fileinfo>, set< refptr<fileinfo> > > m_AutoDeps;
@@ -125,7 +129,10 @@ public:
}
/* Needed if you only want to use the searchcommand and execommand functions */
- mhmakefileparser(const refptr<fileinfo> &pMakeDir) : m_MakeDir(pMakeDir), m_pEnv(NULL)
+ mhmakefileparser(const refptr<fileinfo> &pMakeDir) :
+ m_MakeDir(pMakeDir)
+ , m_AutoDepsDirty(false)
+ , m_pEnv(NULL)
{}
static void SetNrParallelBuilds(int NrParallelBuilds)
@@ -201,6 +208,11 @@ public:
virtual ~mhmakefileparser()
{
SaveAutoDepsFile();
+#ifndef WIN32
+ char **pEnv=m_pEnv;
+ if (pEnv)
+ while (*pEnv) free(*pEnv++);
+#endif
free(m_pEnv);
}
virtual int yylex(void);
@@ -325,8 +337,8 @@ public:
}
void AddRule();
- HANDLE ExecuteCommand(string Command, bool &IgnoreError, string *pOutput=NULL);
- HANDLE ExecuteCommand(string Command, string *pOutput=NULL)
+ mh_pid_t ExecuteCommand(string Command, bool &IgnoreError, string *pOutput=NULL);
+ mh_pid_t ExecuteCommand(string Command, string *pOutput=NULL)
{
bool IgnoreError;
return ExecuteCommand(Command, IgnoreError, pOutput);
@@ -337,14 +349,14 @@ public:
static void InitBuildTime();
void SplitToItems(const string &String, vector< refptr<fileinfo> > &Items) const;
- HANDLE DeleteFiles(const string &Params) const;
- HANDLE CopyFiles(const string &Params) const;
- HANDLE TouchFiles(const string &Params) const;
- HANDLE EchoCommand(const string &Params) const;
+ mh_pid_t DeleteFiles(const string &Params) const;
+ mh_pid_t CopyFiles(const string &Params) const;
+ mh_pid_t TouchFiles(const string &Params) const;
+ mh_pid_t EchoCommand(const string &Params) const;
string SearchCommand(const string &Command, const string &Extension="") const;
const string &GetPythonExe() const;
int SearchPath(void *NotUsed, const char *szCommand, const char *pExt, int Len, char *szFullCommand,char **pFilePart) const;
- HANDLE OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const;
+ mh_pid_t OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const;
};
diff --git a/tools/mhmake/src/util.cpp b/tools/mhmake/src/util.cpp
index 9d8b9510e..79a0424da 100644
--- a/tools/mhmake/src/util.cpp
+++ b/tools/mhmake/src/util.cpp
@@ -19,13 +19,15 @@
/* $Rev$ */
#include "stdafx.h"
-#include <WinIoCtl.h>
#include "rule.h"
#include "util.h"
#include "mhmakeparser.h"
#ifdef WIN32
+
+#include <WinIoCtl.h>
+
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
typedef struct {
@@ -112,7 +114,7 @@ void PrintVersionInfo(void)
static const char VersionStr[]="\
mhmake : GNU compatible make tool with extensions\n\
version: "MHMAKEVER"\n\
-Remarks and bug reports -> Marc Haesen\n\
+Remarks and bug reports -> marha@sourceforge.net\n\
";
cerr << VersionStr;
exit(1);
@@ -303,7 +305,7 @@ loadedmakefile::loadedmakefile_statics::loadedmakefile_statics()
if (FindData.dwReserved0==IO_REPARSE_TAG_MOUNT_POINT)
{
HANDLE hDir = ::CreateFile(m_MhMakeConf->GetFullFileName().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
-
+
BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; // We need a large buffer
REPARSE_MOUNTPOINT_DATA_BUFFER& ReparseBuffer = (REPARSE_MOUNTPOINT_DATA_BUFFER&)buf;
DWORD dwRet;