Distributed compilation with Icecream on Cygwin
Andreas Gungl <[email protected]> Tue, 26 Jul 2005 11:10:38 +0200
| Newsgroups | gmane.comp.kde.devel.cygwin |
|---|---|
| Message-ID | <[email protected]> |
Hi, I've discovered Icecream some time ago as a great tool to speed up compilation by using several machines. I've been using it on Linux for quite a while. Now I have a case where I like to use it on Cygwin as well. I don't need the monitor, so there was no need for me to care for X, Qt and KDE on Cygwin. During the process to install and run Icecream on Cygwin, I've probably made all errors one can make. Anyway, I have a running and working Icecream daemon now which allows me to use the power of additional Linux boxes when compiling. To share the results from my work, I've attached my patches against svn trunk (kdenonbeta/icecream/icecream) plus a short description of the installation and potential problems. If there is more interest (or even some help from more experienced developers), it might be possible to make Icecream ready for a really easy build, installation and usage on Cygwin. Thanks for your attention, Andreas PS. Please Cc me when replying, I'm not subscribed to kde-cygwin. _______________________________________________ kde-cygwin mailing list [email protected] https://mail.kde.org/mailman/listinfo/kde-cygwin
icecream-on-cygwin.diff
(text/x-diff, 9.9 KB)
Index: services/comm.h
===================================================================
--- services/comm.h (revision 438822)
+++ services/comm.h (working copy)
@@ -135,7 +135,7 @@
int protocol;
std::string name;
- unsigned short port;
+ uint32_t port;
time_t last_talk;
// NULL <--> channel closed
@@ -234,9 +234,9 @@
Environments versions;
std::string filename;
CompileJob::Language lang;
- unsigned int count; // the number of UseCS messages to answer with - usually 1
+ uint32_t count; // the number of UseCS messages to answer with - usually 1
std::string target;
- unsigned int arg_flags;
+ uint32_t arg_flags;
GetCSMsg () : Msg(M_GET_CS), count( 1 ),arg_flags( 0 ) {}
GetCSMsg (const Environments &envs, const std::string &f, CompileJob::Language _lang, unsigned int _count, std::string _target, unsigned int _arg_flags)
: Msg(M_GET_CS), versions( envs ), filename(f), lang(_lang), count( _count ), target( _target ), arg_flags( _arg_flags )
@@ -247,11 +247,11 @@
class UseCSMsg : public Msg {
public:
- unsigned int job_id;
+ uint32_t job_id;
std::string hostname;
- unsigned int port;
+ uint32_t port;
std::string host_platform;
- unsigned int got_env;
+ uint32_t got_env;
UseCSMsg () : Msg(M_USE_CS) {}
UseCSMsg (std::string platform, std::string host, unsigned int p, unsigned int id, bool gotit)
: Msg(M_USE_CS), job_id(id), hostname (host), port (p), host_platform( platform ), got_env( gotit ) {}
@@ -262,7 +262,7 @@
class GetSchedulerMsg : public Msg {
public:
- unsigned int wants_native;
+ uint32_t wants_native;
GetSchedulerMsg (bool _wants_native = false) : Msg(M_GET_SCHEDULER),
wants_native( _wants_native ) { }
virtual void fill_from_channel (MsgChannel * c);
@@ -272,7 +272,7 @@
class UseSchedulerMsg : public Msg {
public:
std::string hostname;
- unsigned int port;
+ uint32_t port;
std::string nativeVersion;
UseSchedulerMsg () : Msg(M_USE_SCHEDULER), port( 0 ) {}
UseSchedulerMsg (std::string host, unsigned int p, std::string _native)
@@ -324,8 +324,8 @@
class JobBeginMsg : public Msg {
public:
- unsigned int job_id;
- unsigned int stime;
+ uint32_t job_id;
+ uint32_t stime;
JobBeginMsg () : Msg(M_JOB_BEGIN) {}
JobBeginMsg (unsigned int j) : Msg(M_JOB_BEGIN), job_id(j), stime(time(0)) {}
virtual void fill_from_channel (MsgChannel * c);
@@ -334,19 +334,19 @@
class JobDoneMsg : public Msg {
public:
- unsigned int real_msec; /* real time it used */
- unsigned int user_msec; /* user time used */
- unsigned int sys_msec; /* system time used */
- unsigned int pfaults; /* page faults */
+ uint32_t real_msec; /* real time it used */
+ uint32_t user_msec; /* user time used */
+ uint32_t sys_msec; /* system time used */
+ uint32_t pfaults; /* page faults */
int exitcode; /* exit code */
- unsigned int in_compressed;
- unsigned int in_uncompressed;
- unsigned int out_compressed;
- unsigned int out_uncompressed;
+ uint32_t in_compressed;
+ uint32_t in_uncompressed;
+ uint32_t out_compressed;
+ uint32_t out_uncompressed;
- unsigned int job_id;
+ uint32_t job_id;
JobDoneMsg (int job_id = 0, int exitcode = -1);
virtual void fill_from_channel (MsgChannel * c);
virtual void send_to_channel (MsgChannel * c) const;
@@ -355,7 +355,7 @@
class JobLocalBeginMsg : public Msg {
public:
std::string outfile;
- unsigned int stime;
+ uint32_t stime;
JobLocalBeginMsg(const std::string &file = "") : Msg( M_JOB_LOCAL_BEGIN ),
outfile( file ), stime(time(0)) {}
virtual void fill_from_channel (MsgChannel * c);
@@ -365,7 +365,7 @@
#if MIN_PROTOCOL_VERSION < 20
class JobLocalId : public Msg {
public:
- unsigned int job_id;
+ uint32_t job_id;
JobLocalId() : Msg( M_JOB_LOCAL_ID ), job_id(0) {}
JobLocalId( unsigned int j ) : Msg( M_JOB_LOCAL_ID ), job_id( j ) {}
virtual void fill_from_channel (MsgChannel * c);
@@ -375,7 +375,7 @@
class JobLocalDoneMsg : public Msg {
public:
int exitcode; /* exit code */
- unsigned int job_id;
+ uint32_t job_id;
JobLocalDoneMsg (int job_id = 0, int exitcode = -1);
virtual void fill_from_channel (MsgChannel * c);
virtual void send_to_channel (MsgChannel * c) const;
@@ -384,9 +384,9 @@
class LoginMsg : public Msg {
public:
- unsigned int port;
+ uint32_t port;
Environments envs;
- unsigned int max_kids;
+ uint32_t max_kids;
bool chroot_possible;
std::string nodename;
std::string host_platform;
@@ -408,12 +408,12 @@
* linear scale). Load of 1000 means to not schedule
* another job under no circumstances.
*/
- unsigned int load;
+ uint32_t load;
- unsigned int loadAvg1;
- unsigned int loadAvg5;
- unsigned int loadAvg10;
- unsigned int freeMem;
+ uint32_t loadAvg1;
+ uint32_t loadAvg5;
+ uint32_t loadAvg10;
+ uint32_t freeMem;
StatsMsg () : Msg(M_STATS) { load = 0; }
virtual void fill_from_channel (MsgChannel * c);
@@ -439,8 +439,8 @@
class MonGetCSMsg : public GetCSMsg {
public:
- unsigned int job_id;
- unsigned int clientid;
+ uint32_t job_id;
+ uint32_t clientid;
MonGetCSMsg() : GetCSMsg() { // overwrite
type = M_MON_GET_CS;
@@ -457,9 +457,9 @@
class MonJobBeginMsg : public Msg {
public:
- unsigned int job_id;
- unsigned int stime;
- unsigned int hostid;
+ uint32_t job_id;
+ uint32_t stime;
+ uint32_t hostid;
MonJobBeginMsg() : Msg(M_MON_JOB_BEGIN), job_id( 0 ), stime( 0 ), hostid( 0 ) {}
MonJobBeginMsg( unsigned int id, unsigned int time, int _hostid)
: Msg( M_MON_JOB_BEGIN ), job_id( id ), stime( time ), hostid( _hostid ) {}
@@ -481,9 +481,9 @@
class MonLocalJobBeginMsg : public Msg {
public:
- unsigned int job_id;
- unsigned int stime;
- unsigned int hostid;
+ uint32_t job_id;
+ uint32_t stime;
+ uint32_t hostid;
std::string file;
MonLocalJobBeginMsg() : Msg(M_MON_LOCAL_JOB_BEGIN) {}
MonLocalJobBeginMsg( unsigned int id, const std::string &_file, unsigned int time, int _hostid )
@@ -494,7 +494,7 @@
class MonLocalJobDoneMsg : public Msg {
public:
- unsigned int job_id;
+ uint32_t job_id;
MonLocalJobDoneMsg(unsigned int id = 0) : Msg( M_MON_LOCAL_JOB_DONE ), job_id( id ) {}
virtual void fill_from_channel (MsgChannel * c);
virtual void send_to_channel (MsgChannel * c) const;
@@ -502,7 +502,7 @@
class MonStatsMsg : public Msg {
public:
- unsigned int hostid;
+ uint32_t hostid;
std::string statmsg;
MonStatsMsg() : Msg( M_MON_STATS ) {}
MonStatsMsg( int id, const std::string &_statmsg )
Index: services/comm.cpp
===================================================================
--- services/comm.cpp (revision 438822)
+++ services/comm.cpp (working copy)
@@ -361,7 +361,7 @@
MsgChannel::read_environments( Environments &envs )
{
envs.clear();
- unsigned int count;
+ uint32_t count;
readuint32( count );
for ( unsigned int i = 0; i < count; i++ )
{
@@ -379,8 +379,11 @@
{
lzo_uint uncompressed_len;
lzo_uint compressed_len;
- readuint32 (uncompressed_len);
- readuint32 (compressed_len);
+ uint32_t tmp;
+ readuint32 (tmp);
+ uncompressed_len = tmp;
+ readuint32 (tmp);
+ compressed_len = tmp;
/* If there was some input, but nothing compressed, or we don't have
everything to uncompress, there was an error. */
if ((uncompressed_len && !compressed_len)
@@ -751,7 +754,7 @@
{
Msg *m = 0;
enum MsgType type;
- unsigned int t;
+ uint32_t t;
if (timeout > 0 && !wait_for_msg (timeout) ) {
trace() << "blocking && !waiting_for_msg()\n";
return 0;
@@ -1051,7 +1054,7 @@
Msg::fill_from_channel (c);
c->read_environments( versions );
c->read_string (filename);
- unsigned int _lang;
+ uint32_t _lang;
c->readuint32 (_lang);
c->readuint32( count );
c->read_string( target );
@@ -1101,7 +1104,7 @@
CompileFileMsg::fill_from_channel (MsgChannel *c)
{
Msg::fill_from_channel (c);
- unsigned int id, lang;
+ uint32_t id, lang;
list<string> _l1, _l2;
string version;
c->readuint32 (lang);
@@ -1231,7 +1234,7 @@
void JobLocalDoneMsg::fill_from_channel( MsgChannel *c )
{
Msg::fill_from_channel(c);
- unsigned int error = 255;
+ uint32_t error = 255;
c->readuint32(error);
c->readuint32(job_id);
exitcode = ( int )error;
@@ -1249,7 +1252,7 @@
Msg::fill_from_channel(c);
if ( !IS_PROTOCOL_20(c ) )
{
- unsigned int error = 255;
+ uint32_t error = 255;
c->readuint32(error);
}
c->readuint32(job_id);
@@ -1299,7 +1302,7 @@
c->readuint32 (sys_msec);
if ( !IS_PROTOCOL_20( c ) )
{
- unsigned int maxrss, idrss, majflt, nswap;
+ uint32_t maxrss, idrss, majflt, nswap;
c->readuint32 (maxrss);
c->readuint32 (idrss);
c->readuint32 (majflt);
@@ -1354,7 +1357,7 @@
c->read_environments( envs );
c->read_string( nodename );
c->read_string( host_platform );
- unsigned int net_chroot_possible = 0;
+ uint32_t net_chroot_possible = 0;
if ( IS_PROTOCOL_18( c ) )
c->readuint32 (net_chroot_possible);
chroot_possible = net_chroot_possible != 0;
@@ -1380,7 +1383,7 @@
c->readuint32 (load);
if ( !IS_PROTOCOL_19( c ) )
{
- unsigned int dummy;
+ uint32_t dummy;
c->readuint32 (dummy);
c->readuint32 (dummy);
c->readuint32 (dummy);
Index: services/getifaddrs.cpp
===================================================================
--- services/getifaddrs.cpp (revision 438822)
+++ services/getifaddrs.cpp (working copy)
@@ -211,9 +211,16 @@
else if (ifr->ifr_flags & IFF_POINTOPOINT)
{
ifr->ifr_addr = storage[i].addr;
+// Needed on Cygwin
+#ifndef SIOCGIFDSTADDR
+ #define SIOCGIFDSTADDR 0x8917
+#endif
if (ioctl (fd, SIOCGIFDSTADDR, ifr) < 0)
break;
storage[i].broadaddr = ifr->ifr_dstaddr;
+ // FIXME on Cygwin you need to comment the line above
+ // and uncomment the line below
+ // storage[i].broadaddr = ifr->ifr_broadaddr;
}
else
/* Just 'cause. */
icecream-on-cygwin.txt
(text/plain, 2.4 KB)
*** Getting Icecream to work on Cygwin w/o X-server ***
INSTALLATION AND RUNNING
You should get the icecream sources from svn trunk. Tarballs will need
Qt and KDE installed to be able to build the monitor. To go only with the
daemon, you won't need that.
The following steps let you build and install Icecream on Cygwin:
1) Go into the icecream directory holding the Makefile.cvs
2) Remove the monitor's sources "rm -rf mon"
3) Start the build "make -f Makefile.cvs ; configure --prefix=/opt/icecream ; make"
4) Solve any compilation problems (see explanation below)
5) Install the application "make && make install"
Then you can start your icecream daemon, but make sure to run it as root. (You may
want to use ssh to become root on Cygwin. It was a bit tricky for me to find out
how to make that work, but this is another story.)
Use a command line like this:
/opt/icecream/sbin/iceccd.exe -n <net-name> -l /opt/icecream/log/icecream.log
-s <scheduler-host> -vvv -u root
-b /opt/icecream/env
A daemon mode is possible as well, but I started it from command line so I could
easier start and stop (via Ctrl-C) the instance. You can watch the log file using
"tail -f /opt/icecream/log/icecream.log".
If you have problems when running icecream, it may well be that some packages
are not installed on your system. (package "file" in my case). So you may want
to check that.
BUILD PROBLEMS
There are several issues during the build if you use icecream from svn trunk.
I've found:
1) inconsequent uses of uint32_t and unsigned int
2) Missing declarations
3) special .exe handling on Cygwin
1) + 3) are completely fixed in the attached patch. For 2) you have to
adjust the sources manually. I've added comments in the files telling
you what to do on cygwin. If someone is better in autoconf, improvements
are certaily possible.
I've also added a "#define IFF_POINTOPOINT 0x10" to the file
/usr/include/cygwin/if.h because that one was missing.
OPEN ISSUES
I was able to use icecream on cygwin when building on that local machine.
All my other icecream instances in the net were recognized and used.
The cygwin icecream instance showed up properly in the icemon monitor
running on a Linux box.
The other way round (compiling a project on a Linux box and use the cygwin
instance additionally) hasn't worked so far due to problems with the /tmp
directory and permissions on that.