From bcpierce at cis.upenn.edu Sun Jul 12 12:07:30 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Sun, 12 Jul 2009 12:07:30 -0400 Subject: [Unison-hackers] Testing Message-ID: (please ignore) From bcpierce at seas.upenn.edu Sun Jul 12 12:28:34 2009 From: bcpierce at seas.upenn.edu (bcpierce@seas.upenn.edu) Date: Sun, 12 Jul 2009 12:28:34 -0400 Subject: [Unison-hackers] [unison-svn] r370 - trunk/src Message-ID: <200907121628.n6CGSYWZ004686@yaws.seas.upenn.edu> Author: bcpierce Date: 2009-07-12 12:28:33 -0400 (Sun, 12 Jul 2009) New Revision: 370 Modified: trunk/src/RECENTNEWS Log: Test post-commit hook Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-12 16:14:32 UTC (rev 369) +++ trunk/src/RECENTNEWS 2009-07-12 16:28:33 UTC (rev 370) @@ -1,10 +1,5 @@ CHANGES FROM VERSION 2.36.-27 -Tiny changes - -------------------------------- -CHANGES FROM VERSION 2.36.-27 - * Fixed bug with case insensitive mode on a case sensitive filesystem: - if file "a/a" is created on one replica and directory "A" is created on the other, the file failed to be synchronized the first From vouillon at seas.upenn.edu Mon Jul 13 08:38:43 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Mon, 13 Jul 2009 08:38:43 -0400 Subject: [Unison-hackers] [unison-svn] r371 - trunk/src Message-ID: <200907131238.n6DCchfL023887@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-13 08:38:43 -0400 (Mon, 13 Jul 2009) New Revision: 371 Modified: trunk/src/RECENTNEWS trunk/src/mkProjectInfo.ml trunk/src/remote.ml Log: * Clean-up in remote.ml * Dead-lock free flow control mechanism Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-12 16:28:33 UTC (rev 370) +++ trunk/src/RECENTNEWS 2009-07-13 12:38:43 UTC (rev 371) @@ -1,5 +1,11 @@ CHANGES FROM VERSION 2.36.-27 +* Clean-up in remote.ml +* Dead-lock free flow control mechanism + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * Fixed bug with case insensitive mode on a case sensitive filesystem: - if file "a/a" is created on one replica and directory "A" is created on the other, the file failed to be synchronized the first Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-12 16:28:33 UTC (rev 370) +++ trunk/src/mkProjectInfo.ml 2009-07-13 12:38:43 UTC (rev 371) @@ -89,3 +89,4 @@ + Modified: trunk/src/remote.ml =================================================================== --- trunk/src/remote.ml 2009-07-12 16:28:33 UTC (rev 370) +++ trunk/src/remote.ml 2009-07-13 12:38:43 UTC (rev 371) @@ -33,6 +33,15 @@ Scanf.sscanf Sys.ocaml_version "%d.%d" (fun maj min -> (maj = 3 && min >= 11) || maj > 3) +(* + Flow-control mechanism (only active under windows). + Only one side is allowed to send messages at any given time. + Once it has finished sending messages, a special message is sent + meaning that the destination is now allowed to send messages. +*) +let needFlowControl = windowsHack +let readOrWrite = needFlowControl && not recent_ocaml + (****) let intSize = 5 @@ -65,10 +74,10 @@ (* LOW-LEVEL IO *) (*************************************************************************) -let lost_connection () = +let lostConnection () = Lwt.fail (Util.Fatal "Lost connection with the server") -let catch_io_errors th = +let catchIoErrors th = Lwt.catch th (fun e -> match e with @@ -77,63 +86,66 @@ (* Windows may also return the following errors... *) | Unix.Unix_error(Unix.EINVAL, _, _) -> (* Client has closed its end of the connection *) - lost_connection () + lostConnection () | _ -> Lwt.fail e) (****) -type connection = - { inputChannel : Unix.file_descr; - inputBuffer : string; - mutable inputLength : int; - outputChannel : Unix.file_descr; - outputBuffer : string; - mutable outputLength : int; - outputQueue : (Bytearray.t * int * int) list Queue.t; - mutable pendingOutput : bool; - mutable flowControl : bool; - mutable canWrite : bool; - mutable tokens : int; - mutable reader : unit Lwt.t option } - let receivedBytes = ref 0. let emittedBytes = ref 0. -let inputBuffer_size = 8192 +(****) -let fill_inputBuffer conn = - assert (conn.inputLength = 0); - catch_io_errors +(* I/O buffers *) + +type ioBuffer = + { channel : Unix.file_descr; + buffer : string; + mutable length : int } + +let bufferSize = 16384 +(* No point in making this larger, as the Ocaml Unix library uses a + buffer of this size *) + +let makeBuffer ch = + { channel = ch; buffer = String.create bufferSize; length = 0 } + +(****) + +(* Low-level inputs *) + +let fillInputBuffer conn = + assert (conn.length = 0); + catchIoErrors (fun () -> - Lwt_unix.read conn.inputChannel conn.inputBuffer 0 inputBuffer_size - >>= (fun len -> + Lwt_unix.read conn.channel conn.buffer 0 bufferSize >>= fun len -> debugV (fun() -> if len = 0 then Util.msg "grab: EOF\n" else Util.msg "grab: %s\n" - (String.escaped (String.sub conn.inputBuffer 0 len))); + (String.escaped (String.sub conn.buffer 0 len))); if len = 0 then - lost_connection () + lostConnection () else begin receivedBytes := !receivedBytes +. float len; - conn.inputLength <- len; + conn.length <- len; Lwt.return () - end)) + end) -let rec grab_rec conn s pos len = - if conn.inputLength = 0 then begin - fill_inputBuffer conn >>= (fun () -> - grab_rec conn s pos len) +let rec grabRec conn s pos len = + if conn.length = 0 then begin + fillInputBuffer conn >>= fun () -> + grabRec conn s pos len end else begin - let l = min (len - pos) conn.inputLength in - Bytearray.blit_from_string conn.inputBuffer 0 s pos l; - conn.inputLength <- conn.inputLength - l; - if conn.inputLength > 0 then - String.blit conn.inputBuffer l conn.inputBuffer 0 conn.inputLength; + let l = min (len - pos) conn.length in + Bytearray.blit_from_string conn.buffer 0 s pos l; + conn.length <- conn.length - l; + if conn.length > 0 then + String.blit conn.buffer l conn.buffer 0 conn.length; if pos + l < len then - grab_rec conn s (pos + l) len + grabRec conn s (pos + l) len else Lwt.return () end @@ -141,215 +153,216 @@ let grab conn s len = assert (len > 0); assert (Bytearray.length s <= len); - grab_rec conn s 0 len + grabRec conn s 0 len -let peek_without_blocking conn = - String.sub conn.inputBuffer 0 conn.inputLength +let peekWithoutBlocking conn = + String.sub conn.buffer 0 conn.length (****) -let outputBuffer_size = 8192 +(* Low-level outputs *) -let rec send_output conn = - catch_io_errors +let rec sendOutput conn = + catchIoErrors (fun () -> - Lwt_unix.write - conn.outputChannel conn.outputBuffer 0 conn.outputLength - >>= (fun len -> + Lwt_unix.write conn.channel conn.buffer 0 conn.length >>= fun len -> debugV (fun() -> Util.msg "dump: %s\n" - (String.escaped (String.sub conn.outputBuffer 0 len))); + (String.escaped (String.sub conn.buffer 0 len))); emittedBytes := !emittedBytes +. float len; - conn.outputLength <- conn.outputLength - len; - if conn.outputLength > 0 then + conn.length <- conn.length - len; + if conn.length > 0 then String.blit - conn.outputBuffer len conn.outputBuffer 0 conn.outputLength; - Lwt.return ())) + conn.buffer len conn.buffer 0 conn.length; + Lwt.return ()) -let rec fill_buffer_2 conn s pos len = - if conn.outputLength = outputBuffer_size then - send_output conn >>= (fun () -> - fill_buffer_2 conn s pos len) +let rec fillBuffer2 conn s pos len = + if conn.length = bufferSize then + sendOutput conn >>= fun () -> + fillBuffer2 conn s pos len else begin - let l = min (len - pos) (outputBuffer_size - conn.outputLength) in - Bytearray.blit_to_string s pos conn.outputBuffer conn.outputLength l; - conn.outputLength <- conn.outputLength + l; + let l = min (len - pos) (bufferSize - conn.length) in + Bytearray.blit_to_string s pos conn.buffer conn.length l; + conn.length <- conn.length + l; if pos + l < len then - fill_buffer_2 conn s (pos + l) len + fillBuffer2 conn s (pos + l) len else Lwt.return () end -let bufReg = Lwt_util.make_region 1 - -let rec fill_buffer conn l = +let rec fillBuffer conn l = match l with (s, pos, len) :: rem -> assert (pos >= 0); assert (len >= 0); assert (pos <= Bytearray.length s - len); - fill_buffer_2 conn s pos len >>= (fun () -> - fill_buffer conn rem) + fillBuffer2 conn s pos len >>= fun () -> + fillBuffer conn rem | [] -> Lwt.return () -let fill_buffer conn l = - Lwt_util.run_in_region bufReg 1 (fun () -> fill_buffer conn l) -let send_output conn = - Lwt_util.run_in_region bufReg 1 (fun () -> send_output conn) +let rec flushBuffer conn = + if conn.length > 0 then + sendOutput conn >>= fun () -> + flushBuffer conn + else + Lwt.return () +(****) -let blockedStream = ref None +(* Output scheduling *) -let rec streamWaitForWrite conn = - if conn.canWrite then Lwt.return () else begin - debugE (fun() -> Util.msg "Stream: waiting for write token\n"); - let w = Lwt.wait () in - blockedStream := Some w; - w >>= fun () -> - debugE (fun() -> Util.msg "Stream: restarting\n"); - streamWaitForWrite conn - end +type kind = Normal | Idle | Last | Urgent -let restartStream () = - match !blockedStream with - Some w -> blockedStream := None; Lwt.wakeup w () - | None -> () +type outputQueue = + { mutable available : bool; + mutable canWrite : bool; + mutable flowControl : bool; + writes : (kind * (unit -> unit Lwt.t) * unit Lwt.t) Queue.t; + urgentWrites : (kind * (unit -> unit Lwt.t) * unit Lwt.t) Queue.t; + idleWrites : (kind * (unit -> unit Lwt.t) * unit Lwt.t) Queue.t; + flush : outputQueue -> unit Lwt.t } -(* - Flow-control mechanism (only active under windows). - Only one side is allowed to send message at any given time. - Once it has finished sending message, a special message is sent - meaning that the destination is now allowed to send messages. - A side is allowed to send any number of messages, but will then - not be allowed to send before having received the same number of - messages. - This way, there can be no dead-lock with both sides trying - simultaneously to send some messages. Furthermore, multiple - messages can still be coalesced. -*) -let needFlowControl = windowsHack +let rec performOutputRec q (kind, action, res) = + action () >>= fun () -> + if kind = Last then begin + assert (q.canWrite); + if q.flowControl then q.canWrite <- false + end; + Lwt.wakeup res (); + popOutputQueues q -let rec flush_buffer_simpl conn = - if conn.outputLength > 0 then - send_output conn >>= fun () -> - flush_buffer_simpl conn - else - Lwt.return () - -(* Loop until the output buffer is empty *) -let rec flush_buffer conn = - if conn.tokens <= 0 && conn.canWrite then begin - assert conn.flowControl; - conn.canWrite <- false; - debugE (fun() -> Util.msg "Sending write token\n"); - (* Special message allowing the other side to write *) - fill_buffer conn [encodeInt 0] >>= (fun () -> - flush_buffer conn) >>= (fun () -> - if windowsHack then begin - debugE (fun() -> Util.msg "Restarting reader\n"); - match conn.reader with - None -> - () - | Some r -> - conn.reader <- None; - Lwt.wakeup r () - end; - Lwt.return ()) - end else if conn.outputLength > 0 then - send_output conn >>= (fun () -> - flush_buffer conn) +and popOutputQueues q = + if not (Queue.is_empty q.urgentWrites) then + performOutputRec q (Queue.take q.urgentWrites) + else if not (Queue.is_empty q.writes) && q.canWrite then + performOutputRec q (Queue.take q.writes) + else if not (Queue.is_empty q.idleWrites) && q.canWrite then + performOutputRec q (Queue.take q.idleWrites) else begin - conn.pendingOutput <- false; + q.available <- true; + (* Flush asynchronously the output *) + Lwt.ignore_result (q.flush q); Lwt.return () end -(* Send all pending messages *) -let rec dump_rec conn = - try - let l = Queue.take conn.outputQueue in - fill_buffer conn l >>= (fun () -> - if conn.flowControl then conn.tokens <- conn.tokens - 1; - debugE (fun () -> Util.msg "Remaining tokens: %d\n" conn.tokens); - dump_rec conn) - with Queue.Empty -> - (* We wait a bit before flushing everything, so that other packets - send just afterwards can be coalesced *) - Lwt_unix.yield () >>= (fun () -> - if not (Queue.is_empty conn.outputQueue) then - dump_rec conn - else begin - flush_buffer conn >>= fun () -> - if not (Queue.is_empty conn.outputQueue) then - signalSomethingToWrite conn; +(* Perform an output action in an atomic way *) +let performOutput q kind action = + if q.available && (kind = Urgent || q.canWrite) then begin + q.available <- false; + performOutputRec q (kind, action, Lwt.wait ()) + end else begin + let res = Lwt.wait () in + Queue.add (kind, action, res) + (match kind with + Urgent -> q.urgentWrites + | Normal -> q.writes + | Idle -> q.idleWrites + | Last -> assert false); + res + end + +let allowWrites q = + assert (not q.canWrite); + q.canWrite <- true; + q.available <- false; + (* We yield to let the receiving thread restart and to let some time + to the requests to be processed *) + Lwt.ignore_result (Lwt_unix.yield () >>= fun () -> popOutputQueues q) + + +let disableFlowControl q = + q.flowControl <- false; + if not q.canWrite then allowWrites q + +let outputQueueIsEmpty q = q.available + +let makeOutputQueue isServer flush = + { available = true; canWrite = isServer; flowControl = true; + writes = Queue.create (); urgentWrites = Queue.create (); + idleWrites = Queue.create (); + flush = flush } + +(****) + +type connection = + { inputBuffer : ioBuffer; + outputBuffer : ioBuffer; + outputQueue : outputQueue; + receiver : (unit -> unit Lwt.t) option ref } + +let maybeFlush receiver pendingFlush q buf = + (* We return immediately if a flush is already scheduled, or if the + output buffer is already empty. *) + (* If we are doing flow control and we can write, we need to send + a write token even when the buffer is empty. *) + if + !pendingFlush || (buf.length = 0 && not (q.flowControl && q.canWrite)) + then + Lwt.return () + else begin + pendingFlush := true; + (* Wait a bit, in case there are some new requests being processed *) + Lwt_unix.yield () >>= fun () -> + pendingFlush := false; + (* If there are other writes scheduled, we do not flush yet *) + if outputQueueIsEmpty q then begin + performOutput q Last + (fun () -> + if q.flowControl then begin + debugE (fun() -> Util.msg "Sending write token\n"); + fillBuffer buf [encodeInt 0] >>= fun () -> + flushBuffer buf + end else + flushBuffer buf) >>= fun () -> + (* Restart the reader thread if needed *) + match !receiver with + None -> Lwt.return () + | Some f -> f () + end else Lwt.return () - end) + end -(* Start the thread that write all pending messages, if this thread is - not running at this time *) -and signalSomethingToWrite conn = - if not conn.canWrite && conn.pendingOutput then - debugE - (fun () -> Util.msg "Something to write, but no write token (%d)\n" - conn.tokens); - if not conn.pendingOutput && conn.canWrite then begin - conn.pendingOutput <- true; - Lwt.ignore_result (dump_rec conn) - end; - if conn.canWrite then restartStream () +let makeConnection isServer inCh outCh = + let pendingFlush = ref false in + let receiver = ref None in + let outputBuffer = makeBuffer outCh in + { inputBuffer = makeBuffer inCh; + outputBuffer = outputBuffer; + outputQueue = + makeOutputQueue isServer + (fun q -> maybeFlush receiver pendingFlush q outputBuffer); + receiver = receiver } -(* Add a message to the output queue and schedule its emission *) -(* A message is a list of fragments of messages, represented by triplets - (string, position in string, length) *) +(* Send message [l] *) let dump conn l = - Queue.add l conn.outputQueue; - signalSomethingToWrite conn; - Lwt.return () + performOutput + conn.outputQueue Normal (fun () -> fillBuffer conn.outputBuffer l) -(* Invoked when a special message is received from the other side, - allowing this side to send messages *) -let allowWrites conn = - if conn.flowControl then begin - assert (conn.pendingOutput = false); - assert (not conn.canWrite); - conn.canWrite <- true; - debugE (fun () -> Util.msg "Received write token (%d)\n" conn.tokens); - (* Flush pending messages, if there are any *) - signalSomethingToWrite conn - end +(* Send message [l] when idle *) +let dumpIdle conn l = + performOutput + conn.outputQueue Idle (fun () -> fillBuffer conn.outputBuffer l) -(* Invoked when a special message is received from the other side, - meaning that the other side does not block on write, and that - therefore there can be no dead-lock. *) -let disableFlowControl conn = - debugE (fun () -> Util.msg "Flow control disabled\n"); - conn.flowControl <- false; - conn.canWrite <- true; - conn.tokens <- 1; - (* We are allowed to write, so we flush pending messages, if there - are any *) - signalSomethingToWrite conn +(* Send message [l], even if write are disabled. This is used for + aborting rapidly a stream. This works as long as only one small + message is written at a time (the write will succeed as the pipe + will not be full) *) +let dumpUrgent conn l = + performOutput conn.outputQueue Urgent + (fun () -> + fillBuffer conn.outputBuffer l >>= fun () -> + flushBuffer conn.outputBuffer) (****) (* Initialize the connection *) -let setupIO in_ch out_ch = +let setupIO isServer inCh outCh = if not windowsHack then begin - Unix.set_nonblock in_ch; - Unix.set_nonblock out_ch + Unix.set_nonblock inCh; + Unix.set_nonblock outCh end; - { inputChannel = in_ch; - inputBuffer = String.create inputBuffer_size; - inputLength = 0; - outputChannel = out_ch; - outputBuffer = String.create outputBuffer_size; - outputLength = 0; - outputQueue = Queue.create (); - pendingOutput = false; - flowControl = true; - canWrite = true; - tokens = 1; - reader = None } + makeConnection isServer inCh outCh (* XXX *) module Thread = struct @@ -558,12 +571,12 @@ let receivePacket conn = (* Get the length of the packet *) let int_buf = Bytearray.create intSize in - grab conn int_buf intSize >>= (fun () -> + grab conn.inputBuffer int_buf intSize >>= (fun () -> let length = decodeInt int_buf 0 in assert (length >= 0); (* Get packet *) let buf = Bytearray.create length in - grab conn buf length >>= (fun () -> + grab conn.inputBuffer buf length >>= (fun () -> (debugE (fun () -> let start = if length > 10 then (Bytearray.sub buf 0 10) ^ "..." @@ -622,8 +635,7 @@ if not !streamAbortedDst then begin streamAbortedDst := true; let request = encodeInt id :: marshalHeader StreamAbort [] in - fill_buffer conn request >>= fun () -> - flush_buffer_simpl conn + dumpUrgent conn request end else Lwt.return () @@ -665,63 +677,56 @@ (* Receiving thread: read a message and dispatch it to the right thread or create a new thread to process requests. *) let rec receive conn = - (if windowsHack && conn.canWrite && not recent_ocaml then - let wait = Lwt.wait () in - assert (conn.reader = None); - conn.reader <- Some wait; - wait - else - Lwt.return ()) >>= (fun () -> - debugE (fun () -> Util.msg "Waiting for next message\n"); - (* Get the message ID *) - let id = Bytearray.create intSize in - grab conn id intSize >>= (fun () -> - let num_id = decodeInt id 0 in - if num_id = 0 then begin - debugE (fun () -> Util.msg "Received the write permission\n"); - allowWrites conn; - receive conn + if readOrWrite && conn.outputQueue.canWrite then begin + conn.receiver := Some (fun () -> receive conn); Lwt.return () end else begin - if conn.flowControl then conn.tokens <- conn.tokens + 1; - debugE - (fun () -> Util.msg "Message received (id: %d) (tokens: %d)\n" - num_id conn.tokens); - (* Read the header *) - receivePacket conn >>= (fun buf -> - let req = unmarshalHeader buf in - begin match req with - Request cmdName -> - receivePacket conn >>= (fun buf -> - (* We yield before starting processing the request. - This way, the request may call [Lwt_unix.run] and this will - not block the receiving thread. *) - Lwt.ignore_result - (Lwt_unix.yield () >>= (fun () -> - processRequest conn id cmdName buf)); - receive conn) - | NormalResult -> - receivePacket conn >>= (fun buf -> - Lwt.wakeup (find_receiver num_id) buf; - receive conn) - | TransientExn s -> - debugV (fun() -> Util.msg "receive: Transient remote error '%s']" s); - Lwt.wakeup_exn (find_receiver num_id) (Util.Transient s); - receive conn - | FatalExn s -> - debugV (fun() -> Util.msg "receive: Fatal remote error '%s']" s); - Lwt.wakeup_exn (find_receiver num_id) (Util.Fatal ("Server: " ^ s)); - receive conn - | Stream cmdName -> - receivePacket conn >>= fun buf -> - if conn.flowControl then conn.tokens <- conn.tokens - 1; - processStream conn id cmdName buf >>= fun () -> - receive conn - | StreamAbort -> - if conn.flowControl then conn.tokens <- conn.tokens - 1; - streamAbortedSrc := num_id; - receive conn + debugE (fun () -> Util.msg "Waiting for next message\n"); + (* Get the message ID *) + let id = Bytearray.create intSize in + grab conn.inputBuffer id intSize >>= (fun () -> + let num_id = decodeInt id 0 in + if num_id = 0 then begin + debugE (fun () -> Util.msg "Received the write permission\n"); + allowWrites conn.outputQueue; + receive conn + end else begin + debugE + (fun () -> Util.msg "Message received (id: %d)\n" num_id); + (* Read the header *) + receivePacket conn >>= (fun buf -> + let req = unmarshalHeader buf in + begin match req with + Request cmdName -> + receivePacket conn >>= (fun buf -> + (* We yield before starting processing the request. + This way, the request may call [Lwt_unix.run] and this will + not block the receiving thread. *) + Lwt.ignore_result + (Lwt_unix.yield () >>= (fun () -> + processRequest conn id cmdName buf)); + receive conn) + | NormalResult -> + receivePacket conn >>= (fun buf -> + Lwt.wakeup (find_receiver num_id) buf; + receive conn) + | TransientExn s -> + debugV (fun() -> Util.msg "receive: Transient remote error '%s']" s); + Lwt.wakeup_exn (find_receiver num_id) (Util.Transient s); + receive conn + | FatalExn s -> + debugV (fun() -> Util.msg "receive: Fatal remote error '%s']" s); + Lwt.wakeup_exn (find_receiver num_id) (Util.Fatal ("Server: " ^ s)); + receive conn + | Stream cmdName -> + receivePacket conn >>= fun buf -> + processStream conn id cmdName buf >>= fun () -> + receive conn + | StreamAbort -> + streamAbortedSrc := num_id; + receive conn + end) end) - end)) + end let wait_for_reply id = let res = Lwt.wait () in @@ -867,15 +872,13 @@ serverStreams := Util.StringMap.add cmdName server !serverStreams; (* Create a client function and return it *) let client conn id serverArgs = - if !streamAbortedSrc = id then raise (Util.Transient "Streaming aborted"); - streamWaitForWrite conn >>= fun () -> debugE (fun () -> Util.msg "Sending stream chunk (id: %d)\n" id); if !streamAbortedSrc = id then raise (Util.Transient "Streaming aborted"); let request = encodeInt id :: marshalHeader (Stream cmdName) (marshalArgs serverArgs []) in - fill_buffer conn request + dumpIdle conn request in fun conn sender -> if not (Prefs.read streamingActivated) then @@ -886,9 +889,7 @@ Lwt.try_bind (fun () -> Lwt_util.run_in_region streamReg 1 - (fun () -> - Lwt_unix.yield () >>= fun () -> - sender (fun v -> client conn id v))) + (fun () -> sender (fun v -> client conn id v))) (fun v -> ping conn id >>= fun () -> Lwt.return v) (fun e -> ping conn id >>= fun () -> Lwt.fail e) end @@ -903,11 +904,11 @@ if pos = len then Lwt.return () else begin - (grab conn buffer 1 >>= (fun () -> + (grab conn.inputBuffer buffer 1 >>= (fun () -> if buffer.{0} <> connectionHeader.[pos] then let prefix = String.sub connectionHeader 0 pos ^ Bytearray.to_string buffer in - let rest = peek_without_blocking conn in + let rest = peekWithoutBlocking conn.inputBuffer in Lwt.fail (Util.Fatal ("Received unexpected header from the server:\n \ @@ -934,7 +935,7 @@ *) let negociateFlowControlLocal conn () = - if not needFlowControl then disableFlowControl conn; + if not needFlowControl then disableFlowControl conn.outputQueue; Lwt.return needFlowControl let negociateFlowControlRemote = @@ -955,8 +956,7 @@ let initConnection in_ch out_ch = if not windowsHack then ignore(Sys.set_signal Sys.sigpipe Sys.Signal_ignore); - let conn = setupIO in_ch out_ch in - conn.canWrite <- false; + let conn = setupIO false in_ch out_ch in checkHeader conn (Bytearray.create 1) 0 (String.length connectionHeader) >>= (fun () -> Lwt.ignore_result (receive conn); @@ -1293,7 +1293,7 @@ Trace.runningasserver := true; (* Send header indicating to the client that it has successfully connected to the server *) - let conn = setupIO in_ch out_ch in + let conn = setupIO true in_ch out_ch in try Lwt_unix.run (dump conn [(Bytearray.of_string connectionHeader, 0, From vouillon at seas.upenn.edu Mon Jul 13 18:26:15 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Mon, 13 Jul 2009 18:26:15 -0400 Subject: [Unison-hackers] [unison-svn] r372 - in trunk/src: . lwt Message-ID: <200907132226.n6DMQGuK005242@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-13 18:26:15 -0400 (Mon, 13 Jul 2009) New Revision: 372 Modified: trunk/src/RECENTNEWS trunk/src/copy.ml trunk/src/copy.mli trunk/src/lwt/lwt_util.ml trunk/src/mkProjectInfo.ml trunk/src/transfer.ml trunk/src/transfer.mli trunk/src/transport.ml trunk/src/uigtk2.ml trunk/src/update.ml trunk/src/update.mli Log: * When a file transfer fails, turn off fastcheck for this file on the next sync. * Limit the number of simultaneous transfer using rsync (as the rsync algorithm can use a large amount of memory when processing huge files) * Raise the number of concurrent threads, as there is not much reason to leave it low anymore. Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/RECENTNEWS 2009-07-13 22:26:15 UTC (rev 372) @@ -1,5 +1,16 @@ CHANGES FROM VERSION 2.36.-27 +* When a file transfer fails, turn off fastcheck for this file on the + next sync. +* Limit the number of simultaneous transfer using rsync + (as the rsync algorithm can use a large amount of memory when + processing huge files) +* Raise the number of concurrent threads, as there is not much reason + to leave it low anymore. + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * Clean-up in remote.ml * Dead-lock free flow control mechanism Modified: trunk/src/copy.ml =================================================================== --- trunk/src/copy.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/copy.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -42,6 +42,11 @@ (****) +(* From update.ml *) +(* (there is a dependency loop between copy.ml and update.ml...) *) +let excelFile = ref (fun _ -> false) +let markPossiblyUpdated = ref (fun _ _ -> ()) + (* Check whether the source file has been modified during synchronization *) let checkContentsChangeLocal fspathFrom pathFrom archDesc archDig archStamp archRess paranoid = @@ -55,9 +60,7 @@ let dataClearlyUnchanged = not clearlyModified && Props.same_time info.Fileinfo.desc archDesc -(*FIX: should export from update.ml? - && not (excelFile path) -*) + && not (!excelFile pathFrom) && match archStamp with Some (Fileinfo.InodeStamp inode) -> info.Fileinfo.inode = inode | Some (Fileinfo.CtimeStamp ctime) -> true @@ -71,13 +74,15 @@ if dataClearlyUnchanged && ressClearlyUnchanged then begin if paranoid then begin let newDig = Os.fingerprint fspathFrom pathFrom info in - if archDig <> newDig then + if archDig <> newDig then begin + !markPossiblyUpdated fspathFrom pathFrom; raise (Util.Transient (Printf.sprintf "The source file %s\n\ has been modified but the fast update detection mechanism\n\ failed to detect it. Try running once with the fastcheck\n\ option set to 'no'." (Fspath.toPrintString (Fspath.concat fspathFrom pathFrom)))) + end end end else if clearlyModified @@ -403,6 +408,12 @@ | Some fd -> fd +let rsyncReg = Lwt_util.make_region (40 * 1024) +let rsyncThrottle useRsync sz f = + if not useRsync then f () else + let l = Transfer.Rsync.memoryFootprint sz in + Lwt_util.run_in_region rsyncReg l f + let transferFileContents connFrom fspathFrom pathFrom fspathTo pathTo realPathTo update fileKind srcFileSize id = @@ -412,19 +423,26 @@ let infd = ref None in let showProgress count = Uutil.showProgress id (Uutil.Filesize.ofInt count) "r" in - let (bi, decompr) = + + let destFileSize = match update with - `Update (destFileDataSize, destFileRessSize) - when Prefs.read rsyncActivated - && - let destFileSize = - match fileKind with - `DATA -> destFileDataSize - | `RESS -> destFileRessSize - in - Transfer.Rsync.aboveRsyncThreshold destFileSize - && - Transfer.Rsync.aboveRsyncThreshold srcFileSize -> + `Copy -> + Uutil.Filesize.zero + | `Update (destFileDataSize, destFileRessSize) -> + match fileKind with + `DATA -> destFileDataSize + | `RESS -> destFileRessSize + in + let useRsync = + Prefs.read rsyncActivated + && + Transfer.Rsync.aboveRsyncThreshold destFileSize + && + Transfer.Rsync.aboveRsyncThreshold srcFileSize + in + rsyncThrottle useRsync destFileSize (fun () -> + let (bi, decompr) = + if useRsync then Util.convertUnixErrorsToTransient "preprocessing file" (fun () -> @@ -444,7 +462,7 @@ Transfer.Rsync.rsyncDecompress ifd fd showProgress ti in if eof then begin close_out fd; outfd := None end)) - | _ -> + else (None, (* Simple generic decompressor *) fun ti -> @@ -452,23 +470,23 @@ destinationFd fspathTo pathTo fileKind srcFileSize outfd id in let eof = Transfer.receive fd showProgress ti in if eof then begin close_out fd; outfd := None end) - in - let file_id = Remote.newMsgId () in - Lwt.catch - (fun () -> - decompressor := Remote.MsgIdMap.add file_id decompr !decompressor; - compressRemotely connFrom - (bi, fspathFrom, pathFrom, fileKind, srcFileSize, id, file_id) - >>= fun () -> - decompressor := - Remote.MsgIdMap.remove file_id !decompressor; (* For GC *) - close_all infd outfd; - Lwt.return ()) - (fun e -> - decompressor := - Remote.MsgIdMap.remove file_id !decompressor; (* For GC *) - close_all_no_error infd outfd; - Lwt.fail e) + in + let file_id = Remote.newMsgId () in + Lwt.catch + (fun () -> + decompressor := Remote.MsgIdMap.add file_id decompr !decompressor; + compressRemotely connFrom + (bi, fspathFrom, pathFrom, fileKind, srcFileSize, id, file_id) + >>= fun () -> + decompressor := + Remote.MsgIdMap.remove file_id !decompressor; (* For GC *) + close_all infd outfd; + Lwt.return ()) + (fun e -> + decompressor := + Remote.MsgIdMap.remove file_id !decompressor; (* For GC *) + close_all_no_error infd outfd; + Lwt.fail e)) (****) @@ -739,8 +757,6 @@ f () else let bufSz = bufferSize (max (Props.length desc) (Osx.ressLength ress)) in - (* This must be on the client: any lock on the server side may result - in a deadlock under windows *) Lwt_util.run_in_region transferFileReg bufSz f (****) Modified: trunk/src/copy.mli =================================================================== --- trunk/src/copy.mli 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/copy.mli 2009-07-13 22:26:15 UTC (rev 372) @@ -27,3 +27,8 @@ -> Uutil.Filesize.t (* fork length *) -> Uutil.File.t option (* file's index in UI (for progress bars), as appropriate *) -> unit + +(* From update.ml *) +(* (there is a dependency loop between copy.ml and update.ml...) *) +val excelFile : (Path.local -> bool) ref +val markPossiblyUpdated : (Fspath.t -> Path.local -> unit) ref Modified: trunk/src/lwt/lwt_util.ml =================================================================== --- trunk/src/lwt/lwt_util.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/lwt/lwt_util.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -66,7 +66,7 @@ let leave_region reg sz = try - if reg.count > reg.size then raise Queue.Empty; + if reg.count - sz >= reg.size then raise Queue.Empty; let (w, sz') = Queue.take reg.waiters in reg.count <- reg.count - sz + sz'; Lwt.wakeup w () Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/mkProjectInfo.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -90,3 +90,4 @@ + Modified: trunk/src/transfer.ml =================================================================== --- trunk/src/transfer.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/transfer.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -364,6 +364,14 @@ Trace.showTimer timer; bi + (* Expected size of the [rsync_block_info] datastructure (in KiB). *) + (* The calculation here are for a 64 bit architecture. *) + (* When serialized, the datastructure takes currently 24 bytes per block. *) + (* In theory, 12 byte per block should be enough! *) + let memoryFootprint sz = + Int64.to_int + (min (Int64.div (Uutil.Filesize.toInt64 sz) 716800L) 16384L) + * 72 (*** DECOMPRESSION ***) Modified: trunk/src/transfer.mli =================================================================== --- trunk/src/transfer.mli 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/transfer.mli 2009-07-13 22:26:15 UTC (rev 372) @@ -77,6 +77,9 @@ (* Built from the old file by the destination computer *) type rsync_block_info + (* Expected size of the [rsync_block_info] datastructure (in KiB). *) + val memoryFootprint : Uutil.Filesize.t -> int + (* Compute block informations from the old file *) val rsyncPreprocess : in_channel (* old file descriptor *) Modified: trunk/src/transport.ml =================================================================== --- trunk/src/transport.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/transport.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -36,16 +36,18 @@ assert false let maxthreads = - Prefs.createInt "maxthreads" 20 + Prefs.createInt "maxthreads" 0 "!maximum number of simultaneous file transfers" - ("This preference controls how much concurrency is allowed during" - ^ " the transport phase. Normally, it should be set reasonably high " - ^ "(default is 20) to maximize performance, but when Unison is used " - ^ "over a low-bandwidth link it may be helpful to set it lower (e.g. " - ^ "to 1) so that Unison doesn't soak up all the available bandwidth." - ) + ("This preference controls how much concurrency is allowed during \ + the transport phase. Normally, it should be set reasonably high \ + to maximize performance, but when Unison is used over a \ + low-bandwidth link it may be helpful to set it lower (e.g. \ + to 1) so that Unison doesn't soak up all the available bandwidth. \ + The default is the special value 0, which mean 20 threads \ + when file content streaming is desactivated and 1000 threads \ + when it is activated.") -let actionReg = Lwt_util.make_region (Prefs.read maxthreads) +let actionReg = Lwt_util.make_region 50 (* Logging for a thread: write a message before and a message after the execution of the thread. *) @@ -76,13 +78,16 @@ Printf.sprintf "[END] %s\n" lwtShortDescription) let doAction fromRoot fromPath fromContents toRoot toPath toContents id = - Lwt_util.resize_region actionReg (Prefs.read maxthreads); (* When streaming, we can transfer many file simultaneously: as the contents of only one file is transferred in one direction at any time, little ressource is consumed this way. *) - Lwt_util.resize_region Files.copyReg - (if Prefs.read Remote.streamingActivated then 4000 else - Prefs.read maxthreads); + let limit = + let n = Prefs.read maxthreads in + if n > 0 then n else + if Prefs.read Remote.streamingActivated then 1000 else 20 + in + Lwt_util.resize_region actionReg limit; + Lwt_util.resize_region Files.copyReg limit; Lwt_util.run_in_region actionReg 1 (fun () -> if not !Trace.sendLogMsgsToStderr then Trace.statusDetail (Path.toString toPath); Modified: trunk/src/uigtk2.ml =================================================================== --- trunk/src/uigtk2.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/uigtk2.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -2047,6 +2047,15 @@ ~callback:(fun () -> getLock synchronize) ()); + (* Does not quite work: too slow, and Files.copy must be modifed to + support an interruption without error. *) + (* + ignore (actionBar#insert_button ~text:"Stop" + ~icon:((GMisc.image ~stock:`STOP ())#coerce) + ~tooltip:"Exit Unison" + ~callback:Abort.all ()); + *) + (********************************************************************* Rescan button *********************************************************************) Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/update.ml 2009-07-13 22:26:15 UTC (rev 372) @@ -38,13 +38,10 @@ time the format is modified *) (*FIX: also make Jerome's suggested change about file times (see his mesg in unison-pending email folder). *) -(*FIX: one should also store whether we are in case-insensitive mode - in the archive and check the mode has not changed when the archive - is loaded *) (*FIX: we could also drop the use of 8.3-style filenames on Windows, next time the format is changed *) -(* FIX: Another thing we should really consider doing is leaving a flag - in the archive when a file transfer fails and turning off fastcheck +(* FIX: use a special stamp rather than the current hack to leave a flag + in the archive when a file transfer fails so as to turn off fastcheck for this file on the next sync. *) (*FIX: consider changing the way case-sensitivity mode is stored in the archive *) @@ -1834,6 +1831,51 @@ (* Make sure no change has happened *) (*************************************************************************) +let fastCheckMiss path desc ress oldDesc oldRess = + useFastChecking() + && + Props.same_time desc oldDesc + && + Props.length desc = Props.length oldDesc + && + not (excelFile path) + && + Osx.ressUnchanged oldRess ress None true + +let doMarkPossiblyUpdated arch = + match arch with + ArchiveFile (desc, dig, stamp, ress) -> + (* It would be cleaner to have a special stamp for this *) + ArchiveFile (desc, dig, Fileinfo.InodeStamp (-1), ress) + | _ -> + (* Should not happen, actually. But this is hard to test... *) + arch + +let markPossiblyUpdated fspath path = + debug (fun() -> + Util.msg "markPossiblyUpdated %s %s\n" + (Fspath.toDebugString fspath) (Path.toString path)); + let root = thisRootsGlobalName fspath in + let archive = getArchive root in + let archive = + updatePathInArchive archive fspath Path.empty path + (fun arch _ -> doMarkPossiblyUpdated arch) in + setArchiveLocal root archive + +let rec markPossiblyUpdatedRec fspath path ui = + match ui with + Updates (File (desc, ContentsUpdated (_, _, ress)), + Previous (`FILE, oldDesc, _, oldRess)) -> + if fastCheckMiss path desc ress oldDesc oldRess then + markPossiblyUpdated fspath path + | Updates (Dir (_, uiChildren, _, _), _) -> + List.iter + (fun (nm, uiChild) -> + markPossiblyUpdatedRec fspath (Path.child path nm) uiChild) + uiChildren + | _ -> + () + let reportUpdate warnFastCheck explanation = let msg = "Destination updated during synchronization\n" ^ explanation ^ @@ -1861,16 +1903,7 @@ (Path.toString path)) | Updates (File (desc, ContentsUpdated (_, _, ress)), Previous (`FILE, oldDesc, _, oldRess)) -> - reportUpdate - (useFastChecking() - && - Props.same_time desc oldDesc - && - Props.length desc = Props.length oldDesc - && - not (excelFile path) - && - Osx.ressUnchanged oldRess ress None true) + reportUpdate (fastCheckMiss path desc ress oldDesc oldRess) (Format.sprintf "The contents of file %s has been modified\n" (Path.toString path)) | Updates (File (_, ContentsUpdated _), _) -> @@ -1911,6 +1944,7 @@ let archive = updateArchiveRec ui archive in (* ...and check that this is a good description of what's out in the world *) let (_, uiNew) = buildUpdateRec archive fspath localPath false in + markPossiblyUpdatedRec fspath pathInArchive uiNew; explainUpdate pathInArchive uiNew (*****************************************************************************) @@ -1987,3 +2021,10 @@ let archive = getArchive root in let (_, subArch) = getPathInArchive archive Path.empty path in updateSizeRec subArch ui + +(*****) + +(* There is a dependency loop between copy.ml and update.ml... *) +let _ = +Copy.excelFile := excelFile; +Copy.markPossiblyUpdated := markPossiblyUpdated Modified: trunk/src/update.mli =================================================================== --- trunk/src/update.mli 2009-07-13 12:38:43 UTC (rev 371) +++ trunk/src/update.mli 2009-07-13 22:26:15 UTC (rev 372) @@ -38,6 +38,9 @@ (* Check that no updates has taken place in a given place of the filesystem *) val checkNoUpdates : Fspath.t -> Path.local -> Common.updateItem -> unit +(* Turn off fastcheck for the given file on the next sync. *) +val markPossiblyUpdated : Fspath.t -> Path.local -> unit + (* Save to disk the archive updates *) val commitUpdates : unit -> unit From list-ener at strank.info Tue Jul 14 10:58:26 2009 From: list-ener at strank.info (Stefan Rank) Date: Tue, 14 Jul 2009 16:58:26 +0200 Subject: [Unison-hackers] Experiences with unicode support synching Mac-Lin Message-ID: <4A5C9D12.80609@strank.info> Hi everybody, I'd like to provide some feedback to the developers regarding the preliminary unicode support in unison trunk. Short version: - It works (so far) - It would be great to automatically convert filenames created on a Mac (NFD) to the NFC normal-form used on Linux (by convention) when this file is first synched (and therefore created by unison on the Linux side). Long version: I compiled the recent trunk (-r 368) on Mac (text and macnew ui) and Linux (text only). Compiling the GUI on Mac OS required small patches to not attempt compiling a backwards compatible binary for 10.4 as this would fail:: "MINOSXVERSION=10.5" in src/Makefile.OCaml "SDKROOT = /Developer/SDKs/MacOSX10.5.sdk" 3x in src/uimacnew/uimacnew.xcodeproj/project.pbxproj (only one is necessary, see recent emails on the list) With "unicode = true" in the profile, this now preserves all my filenames, even those with the crazy characters. I still had non-utf8 filenames on Linux (mostly created previously by unison). unison-text will abort with an error message in this case. unison-gui will fail silently. For some cases, it will show empty no-synch lines. (Sorry, I don't remember the details now.) To get rid of these troublemakers on Linux, the convmv script is very helpful: http://www.j3e.de/linux/convmv/ The actual command for my case (recursively in the current dir):: convmv -r -f iso-8859-15 -t utf8 --nfc . (choose an appropriate 'from' encoding, add --notest to actually do it) Files created on the Mac and transferred to Linux are created there in utf-8 NFD. You can then easily/accidentally create an "identical" utf-8 NFC file. ls will show you two identical filenames. (For filenames with umlauts/accented characters, tab-completion can help to distinguish which file is which since only the composed version of the filename will complete if you type the base character and hit tab.) To convert NFD filenames on Linux to NFC, convmv comes to the rescue again:: convmv -r -f utf8 -t utf8 --nfc --replace . (again, add --notest to actually do it) Ideally, as suggested above, files could be created as NFC on Linux when first synched from a Mac. cheers, stefan From vouillon at seas.upenn.edu Wed Jul 15 11:01:32 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Wed, 15 Jul 2009 11:01:32 -0400 Subject: [Unison-hackers] [unison-svn] r373 - in trunk/src: . ubase Message-ID: <200907151501.n6FF1WtJ028901@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-15 11:01:31 -0400 (Wed, 15 Jul 2009) New Revision: 373 Added: trunk/src/ubase/proplist.ml trunk/src/ubase/proplist.mli Modified: trunk/src/.depend trunk/src/BUGS.txt trunk/src/Makefile.OCaml trunk/src/RECENTNEWS trunk/src/TODO.txt trunk/src/case.ml trunk/src/case.mli trunk/src/common.ml trunk/src/files.ml trunk/src/globals.ml trunk/src/globals.mli trunk/src/mkProjectInfo.ml trunk/src/name.ml trunk/src/name.mli trunk/src/path.ml trunk/src/path.mli trunk/src/uigtk2.ml trunk/src/uimacbridgenew.ml trunk/src/update.ml Log: * GTK UI: disabled scrolling to the first unfinished item during transport. It goes way too fast when lot of small files are synchronized, and it makes it impossible to browse the file list during transport. * Fixed computation of the amount of data to transfer: property updates should count for zero. * Mac GUI: use Unicode.protect to ensure that all string displayed are encoded in UTF-8. * In Unicode case-insensitive mode, use filenames in NFC normal form when tranferring files * Added a property list at the end of the archive file. This is a better way to extend the format than the hack currently used to store the case-sensitivity mode. Modified: trunk/src/.depend =================================================================== --- trunk/src/.depend 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/.depend 2009-07-15 15:01:31 UTC (rev 373) @@ -244,15 +244,17 @@ path.cmx os.cmx main.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx \ globals.cmx fspath.cmx files.cmx common.cmx clroot.cmx uimacbridgenew.cmo: xferhint.cmi uutil.cmi ubase/util.cmi update.cmi \ - uicommon.cmi transport.cmi ubase/trace.cmi terminal.cmi system.cmi \ - stasher.cmi ubase/safelist.cmi remote.cmi recon.cmi ubase/prefs.cmi \ - path.cmi os.cmi main.cmo lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi \ - globals.cmi fspath.cmi files.cmi common.cmi clroot.cmi + unicode.cmi uicommon.cmi transport.cmi ubase/trace.cmi terminal.cmi \ + system.cmi stasher.cmi ubase/safelist.cmi remote.cmi recon.cmi \ + ubase/prefs.cmi path.cmi os.cmi main.cmo lwt/lwt_util.cmi \ + lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi files.cmi common.cmi \ + clroot.cmi uimacbridgenew.cmx: xferhint.cmx uutil.cmx ubase/util.cmx update.cmx \ - uicommon.cmx transport.cmx ubase/trace.cmx terminal.cmx system.cmx \ - stasher.cmx ubase/safelist.cmx remote.cmx recon.cmx ubase/prefs.cmx \ - path.cmx os.cmx main.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx \ - globals.cmx fspath.cmx files.cmx common.cmx clroot.cmx + unicode.cmx uicommon.cmx transport.cmx ubase/trace.cmx terminal.cmx \ + system.cmx stasher.cmx ubase/safelist.cmx remote.cmx recon.cmx \ + ubase/prefs.cmx path.cmx os.cmx main.cmx lwt/lwt_util.cmx \ + lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx files.cmx common.cmx \ + clroot.cmx uitext.cmo: uutil.cmi ubase/util.cmi update.cmi uicommon.cmi transport.cmi \ ubase/trace.cmi system.cmi ubase/safelist.cmi remote.cmi recon.cmi \ ubase/prefs.cmi path.cmi lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi \ @@ -267,14 +269,16 @@ unicode_tables.cmx: update.cmo: xferhint.cmi uutil.cmi ubase/util.cmi tree.cmi ubase/trace.cmi \ system.cmi stasher.cmi ubase/safelist.cmi remote.cmi props.cmi \ - ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi name.cmi ubase/myMap.cmi \ - lwt/lwt_unix.cmi lwt/lwt.cmi lock.cmi globals.cmi fspath.cmi fs.cmi \ - fingerprint.cmi fileinfo.cmi common.cmi case.cmi update.cmi + ubase/proplist.cmi ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi \ + name.cmi ubase/myMap.cmi lwt/lwt_unix.cmi lwt/lwt.cmi lock.cmi \ + globals.cmi fspath.cmi fs.cmi fingerprint.cmi fileinfo.cmi copy.cmi \ + common.cmi case.cmi update.cmi update.cmx: xferhint.cmx uutil.cmx ubase/util.cmx tree.cmx ubase/trace.cmx \ system.cmx stasher.cmx ubase/safelist.cmx remote.cmx props.cmx \ - ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx name.cmx ubase/myMap.cmx \ - lwt/lwt_unix.cmx lwt/lwt.cmx lock.cmx globals.cmx fspath.cmx fs.cmx \ - fingerprint.cmx fileinfo.cmx common.cmx case.cmx update.cmi + ubase/proplist.cmx ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx \ + name.cmx ubase/myMap.cmx lwt/lwt_unix.cmx lwt/lwt.cmx lock.cmx \ + globals.cmx fspath.cmx fs.cmx fingerprint.cmx fileinfo.cmx copy.cmx \ + common.cmx case.cmx update.cmi uutil.cmo: ubase/util.cmi ubase/trace.cmi ubase/projectInfo.cmo uutil.cmi uutil.cmx: ubase/util.cmx ubase/trace.cmx ubase/projectInfo.cmx uutil.cmi xferhint.cmo: ubase/util.cmi ubase/trace.cmi ubase/prefs.cmi path.cmi os.cmi \ @@ -303,6 +307,8 @@ ubase/prefs.cmi ubase/projectInfo.cmo: ubase/projectInfo.cmx: +ubase/proplist.cmo: ubase/util.cmi ubase/proplist.cmi +ubase/proplist.cmx: ubase/util.cmx ubase/proplist.cmi ubase/rx.cmo: ubase/rx.cmi ubase/rx.cmx: ubase/rx.cmi ubase/safelist.cmo: ubase/safelist.cmi @@ -325,6 +331,7 @@ lwt/pqueue.cmi: ubase/myMap.cmi: ubase/prefs.cmi: ubase/util.cmi system.cmi +ubase/proplist.cmi: ubase/rx.cmi: ubase/safelist.cmi: ubase/trace.cmi: ubase/prefs.cmi Modified: trunk/src/BUGS.txt =================================================================== --- trunk/src/BUGS.txt 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/BUGS.txt 2009-07-15 15:01:31 UTC (rev 373) @@ -137,13 +137,3 @@ Interactively adding an ignore pattern for src will not make src/RECENTNEWS immediately disappear (as it does not directly match the pattern)... - -[Mar 2002] When transferring by copying, copies on the remote side are - not taken into account by the progress meter. - -progress bar calculation is not quite right -- e.g. dir sizes are not - always accurate? - [One needs to consider simultaneously the archive and the update to - compute the size a directory (consider a directory with some - updates deep inside] - [also, Diff has an effect on the progress bar!] Modified: trunk/src/Makefile.OCaml =================================================================== --- trunk/src/Makefile.OCaml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/Makefile.OCaml 2009-07-15 15:01:31 UTC (rev 373) @@ -198,7 +198,7 @@ \ ubase/projectInfo.cmo ubase/myMap.cmo ubase/safelist.cmo \ ubase/uprintf.cmo ubase/util.cmo ubase/uarg.cmo \ - ubase/prefs.cmo ubase/trace.cmo \ + ubase/prefs.cmo ubase/trace.cmo ubase/proplist.cmo \ \ lwt/pqueue.cmo lwt/lwt.cmo lwt/lwt_util.cmo lwt/lwt_unix.cmo \ \ Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/RECENTNEWS 2009-07-15 15:01:31 UTC (rev 373) @@ -1,5 +1,21 @@ CHANGES FROM VERSION 2.36.-27 +* GTK UI: disabled scrolling to the first unfinished item during transport. + It goes way too fast when lot of small files are synchronized, and it + makes it impossible to browse the file list during transport. +* Fixed computation of the amount of data to transfer: property updates + should count for zero. +* Mac GUI: use Unicode.protect to ensure that all string displayed are + encoded in UTF-8. +* In Unicode case-insensitive mode, use filenames in NFC normal form + when tranferring files +* Added a property list at the end of the archive file. This is a + better way to extend the format than the hack currently used to + store the case-sensitivity mode. + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * When a file transfer fails, turn off fastcheck for this file on the next sync. * Limit the number of simultaneous transfer using rsync Modified: trunk/src/TODO.txt =================================================================== --- trunk/src/TODO.txt 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/TODO.txt 2009-07-15 15:01:31 UTC (rev 373) @@ -44,8 +44,6 @@ * Rsync debugging - - R can't run with debugging (even in 2.13) -- Alan cannot reproduce - - when using socket mode under windows, upon completion of the first external rsync call, the connection to the server is dropped (the server gets an EOF and closes the connection; the client sees a @@ -232,13 +230,7 @@ to respond to the prompts in the textual ui. is that explained somewhere? a few typos i noticed: "with t fast", "nison", "off of". -** what happens when we ssh through loopback and sync the same - directory? - ===> Needs to be thought about. In particular, what is the name of the - archive in this case? Could they ever be exactly the same? - ===> Try it and see. - * SMALL FUNCTIONALITY IMPROVEMENTS * ================================ @@ -246,10 +238,6 @@ root = ~/bla instead of requiring me to give an absolute path to my home dir. -**** The archive should indicate whether it is case-dependant or not. - (This is important for correctness -- if the case-insensitive flag is - set differently on different runs, things can get very confused!) - *** [Marcus Sundman, 2008] Unison can't propagate changes in read-only folders. The correct way to do it is to temporarily add write permissions for the user to the folder, then do the changes and then @@ -342,17 +330,6 @@ tolerate it, but the window could be eliminated entirely by allowing socket connections to require a nonce. -** Would be nice to transfer directories "incrementally" rather than - atomically (i.e., if Unison is interrupted during the transfer of a - directory, the partially-transferred directory should persist). Is - this allowed by the specification? (If so, then it should just become - the default behavior.) - ===> BCP and William Lovas have discussed how to do this, but it is - not all that straightforward. - -** we should reload the current preference file (if it's changed, at least) - when we restart - ** An idea for the interface to the external merge functionality: created a general mechanism for invoking external functionality... - in profile, declare a command of the form @@ -450,6 +427,7 @@ time=true, you get a zillion conflicts... ==> This is probably a good idea, but I'm a little scared of all the messages we'd get from upgrading users + ==> Also, "make" can get confused when the 'time' option is set * Maybe we should write debugging and tracing information to stdout instead of stderr? @@ -512,6 +490,7 @@ On one server (Saul), Unison seems to use HUGE amounts of memory (250Mb resident), while on my laptop it's much less. WTF? + ==> Is that real memory or virtual memory? [Ben Wong, Aug 2002] Why not make unison fall back to addversionno if it would otherwise bomb out with an incorrect version number? That way I @@ -602,12 +581,6 @@ to be transferred, and a warning signal (display in red or something) if these exceed the current setting of maxdelete. -Might be nice to provide an option that says "if you're propagating a - newly created directory and something goes wrong with something inside - it, just ignore the file that failed and keep going with the rest of - the directory." [We probably don't want to continue in all cases (for - instance, when the disk is full)] - Would be nice to be able to run unison in a special mode like this unison -relocate //old-host1//path1 //old-host2//path2 \ //new-host1//path1 //new-host2//path2 @@ -816,7 +789,7 @@ [Perdita Stevens, Perdita.Stevens at dcs.ed.ac.uk, Mar 14 2002] ===> It's not trivial (involves some subtle stuff about our RPC implementation and the single-thread nature of the GUI), but might - not be impossible either. + not be impossible either. "Quit" during synchronization should abort all current operations (so that temporary files are deleted) before exiting. Modified: trunk/src/case.ml =================================================================== --- trunk/src/case.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/case.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -138,6 +138,7 @@ method normalizePattern s = s method caseInsensitiveMatch = false method normalizeMatchedString s = s + method normalizeFilename s = s method badEncoding s = false end @@ -149,6 +150,7 @@ method normalizePattern s = s method caseInsensitiveMatch = true method normalizeMatchedString s = s + method normalizeFilename s = s method badEncoding s = false end @@ -160,6 +162,7 @@ method normalizePattern p = Unicode.normalize p method caseInsensitiveMatch = false method normalizeMatchedString s = Unicode.normalize s + method normalizeFilename s = Unicode.compose s method badEncoding s = not (Unicode.check_utf_8 s) end Modified: trunk/src/case.mli =================================================================== --- trunk/src/case.mli 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/case.mli 2009-07-15 15:01:31 UTC (rev 373) @@ -7,12 +7,21 @@ type mode val ops : unit -> - < mode : mode; modeDesc : string; - compare : string -> string -> int; - hash : string -> int; - normalizePattern : string -> string; - caseInsensitiveMatch : bool; + < mode : mode; modeDesc : string; (* Current mode *) + compare : string -> string -> int; (* Comparison function *) + hash : string -> int; (* Hash function compatible with + the comparison function *) + normalizePattern : string -> string; (* Normalize a pattern *) + caseInsensitiveMatch : bool; (* Whether pattern matching + should be done in a case + insensitive way *) normalizeMatchedString : string -> string; - badEncoding : string -> bool > + (* Put the string in some form + suitable for pattern matching *) + normalizeFilename : string -> string; (* Convert a filename into + its preferred form + (NFC for Unicode). *) + badEncoding : string -> bool > (* Test whether the string uses + the correct encoding *) val init : bool -> unit Modified: trunk/src/common.ml =================================================================== --- trunk/src/common.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/common.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -168,7 +168,10 @@ let riLength ri = match ri.replicas with - Different {rc1 = rc1; rc2 = rc2; direction = dir} -> + Different {rc1 = {status= `Unchanged | `PropsChanged}; + rc2 = {status= `Unchanged | `PropsChanged}} -> + Uutil.Filesize.zero (* No contents propagated *) + | Different {rc1 = rc1; rc2 = rc2; direction = dir} -> begin match dir with Replica1ToReplica2 -> rcLength rc1 rc2 | Replica2ToReplica1 -> rcLength rc2 rc1 Modified: trunk/src/files.ml =================================================================== --- trunk/src/files.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/files.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -396,6 +396,19 @@ (* Calculate target paths *) setupTargetPaths rootTo pathTo >>= fun (workingDir, realPathTo, tempPathTo, localPathTo) -> + (* When in Unicode case-insensitive mode, we want to create files + with NFC normal-form filenames. *) + let realPathTo = + match update with + `Update _ -> + realPathTo + | `Copy -> + match Path.deconstructRev realPathTo with + None -> + assert false + | Some (name, parentPath) -> + Path.child parentPath (Name.normalize name) + in (* Calculate source path *) Update.translatePath rootFrom pathFrom >>= fun localPathFrom -> let errors = ref [] in @@ -445,9 +458,10 @@ let childThreads = Update.NameMap.mapi (fun name child -> + let nameTo = Name.normalize name in copyRec (Path.child pFrom name) - (Path.child pTo name) - (Path.child realPTo name) + (Path.child pTo nameTo) + (Path.child realPTo nameTo) child) children in Modified: trunk/src/globals.ml =================================================================== --- trunk/src/globals.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/globals.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -228,7 +228,7 @@ let () = Prefs.alias confirmBigDeletes "confirmbigdeletes" -let ignore = +let ignorePred = Pred.create "ignore" ("Including the preference \\texttt{-ignore \\ARG{pathspec}} causes Unison to " ^ "completely ignore paths that match \\ARG{pathspec} (as well as their " @@ -238,7 +238,7 @@ ^ "details on ignoring paths is found in" ^ " \\sectionref{ignore}{Ignoring Paths}.") -let ignorenot = +let ignorenotPred = Pred.create "ignorenot" ("This preference overrides the preference \\texttt{ignore}. It gives a list of patterns @@ -260,12 +260,12 @@ let shouldIgnore p = let p = Path.toString p in - (Pred.test ignore p) && not (Pred.test ignorenot p) + (Pred.test ignorePred p) && not (Pred.test ignorenotPred p) let addRegexpToIgnore re = - let oldRE = Pred.extern ignore in + let oldRE = Pred.extern ignorePred in let newRE = re::oldRE in - Pred.intern ignore newRE + Pred.intern ignorePred newRE let merge = Pred.create "merge" ~advanced:true Modified: trunk/src/globals.mli =================================================================== --- trunk/src/globals.mli 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/globals.mli 2009-07-15 15:01:31 UTC (rev 373) @@ -73,6 +73,8 @@ (* Predicates on paths *) val shouldIgnore : 'a Path.path -> bool val shouldMerge : 'a Path.path -> bool +val ignorePred : Pred.t +val ignorenotPred : Pred.t (* Be careful calling this to add new patterns to be ignored: Its value does NOT persist when a new profile is loaded, so it has to be called again whenever this happens. *) Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/mkProjectInfo.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -91,3 +91,4 @@ + Modified: trunk/src/name.ml =================================================================== --- trunk/src/name.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/name.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -39,6 +39,8 @@ let hash n = (Case.ops())#hash n +let normalize n = (Case.ops())#normalizeFilename n + (****) let badEncoding s = (Case.ops())#badEncoding s Modified: trunk/src/name.mli =================================================================== --- trunk/src/name.mli 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/name.mli 2009-07-15 15:01:31 UTC (rev 373) @@ -10,5 +10,7 @@ val eq : t -> t -> bool val hash : t -> int +val normalize : t -> t + val badEncoding : t -> bool val badFile : t -> bool Modified: trunk/src/path.ml =================================================================== --- trunk/src/path.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/path.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -194,7 +194,7 @@ let hash p = Hashtbl.hash p (* Pref controlling whether symlinks are followed. *) -let follow = Pred.create "follow" +let followPred = Pred.create "follow" ("Including the preference \\texttt{-follow \\ARG{pathspec}} causes Unison to \ treat symbolic links matching \\ARG{pathspec} as `invisible' and \ behave as if the object pointed to by the link had appeared literally \ @@ -205,7 +205,7 @@ let followLink path = (Util.osType = `Unix || Util.isCygwin) - && Pred.test follow (toString path) + && Pred.test followPred (toString path) let magic p = p let magic' p = p Modified: trunk/src/path.mli =================================================================== --- trunk/src/path.mli 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/path.mli 2009-07-15 15:01:31 UTC (rev 373) @@ -34,6 +34,7 @@ val hash : local -> int val followLink : local -> bool +val followPred : Pred.t val magic : t -> local val magic' : local -> t Added: trunk/src/ubase/proplist.ml =================================================================== --- trunk/src/ubase/proplist.ml (rev 0) +++ trunk/src/ubase/proplist.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -0,0 +1,36 @@ +(* Unison file synchronizer: src/ubase/proplist.ml *) +(* Copyright 1999-2009, Benjamin C. Pierce + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*) + +type 'a key = string +type t = Obj.t Util.StringMap.t + +let names = ref Util.StringSet.empty + +let register nm = + if (Util.StringSet.mem nm !names) then + raise (Util.Fatal + (Format.sprintf "Property lists: %s already registered!" nm)); + names := Util.StringSet.add nm !names; + nm + +let empty = Util.StringMap.empty + +let mem = Util.StringMap.mem + +let find (k : 'a key) m : 'a = Obj.obj (Util.StringMap.find k m) + +let add (k : 'a key) (v : 'a) m = Util.StringMap.add k (Obj.repr v) m Added: trunk/src/ubase/proplist.mli =================================================================== --- trunk/src/ubase/proplist.mli (rev 0) +++ trunk/src/ubase/proplist.mli 2009-07-15 15:01:31 UTC (rev 373) @@ -0,0 +1,12 @@ +(* Unison file synchronizer: src/ubase/proplist.mli *) +(* Copyright 1999-2009, Benjamin C. Pierce (see COPYING for details) *) + +type 'a key +type t + +val register : string -> 'a key + +val empty : t +val mem : 'a key -> t -> bool +val find : 'a key -> t -> 'a +val add : 'a key -> 'a -> t -> t Modified: trunk/src/uigtk2.ml =================================================================== --- trunk/src/uigtk2.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/uigtk2.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -1429,6 +1429,7 @@ adj#set_value (min v (upper -. adj#page_size)); end in +(* let makeFirstUnfinishedVisible pRiInFocus = let im = Array.length !theState in let rec find i = @@ -1438,6 +1439,7 @@ | _ -> find (i+1) in find 0 in +*) let updateDetails () = begin match !current with @@ -1650,6 +1652,8 @@ let totalBytesToTransfer = ref Uutil.Filesize.zero in let totalBytesTransferred = ref Uutil.Filesize.zero in + let t0 = ref 0. in + let t1 = ref 0. in let lastFrac = ref 0. in let displayGlobalProgress v = if v = 0. || abs_float (v -. !lastFrac) > 1. then begin @@ -1657,10 +1661,18 @@ progressBar#set_fraction (max 0. (min 1. (v /. 100.))) end; (* - if v > 0.5 then - progressBar#set_text (Util.percent2string v) - else - progressBar#set_text ""; + let t = Unix.gettimeofday () in + if t -. !t1 >= 1. then begin + t1 := t; + let remTime = + if v <= 0. then "" + else if v >= 100. then "00:00 ETA" + else + let t = truncate ((!t1 -. !t0) *. (100. -. v) /. v +. 0.5) in + Format.sprintf "%02d:%02d ETA" (t / 60) (t mod 60) + in + progressBar#set_text remTime + end *) in @@ -1677,6 +1689,7 @@ let initGlobalProgress b = totalBytesToTransfer := b; totalBytesTransferred := Uutil.Filesize.zero; + t0 := Unix.gettimeofday (); t1 := !t0; displayGlobalProgress 0. in @@ -1963,11 +1976,16 @@ showProgress (Uutil.File.ofLine i) rem "done"; theSI.whatHappened <- Some (res, !textDetailed); fastRedisplay i; +(* JV (7/09): It does not seem that useful to me to scroll the display + to make the first unfinished item visible. The scrolling is way + too fast, and it makes it impossible to browse the list. *) +(* sync_action := Some (fun () -> makeFirstUnfinishedVisible pRiThisRound; sync_action := None); +*) gtk_sync false; return ()) | Some _ -> @@ -2160,7 +2178,8 @@ item.bytesToTransfer <- len; initGlobalProgress len; Uicommon.showDiffs item.ri - (fun title text -> messageBox ~title (transcode text)) + (fun title text -> + messageBox ~title:(transcode title) (transcode text)) Trace.status (Uutil.File.ofLine i); displayGlobalProgress 0.; fastRedisplay i) Modified: trunk/src/uimacbridgenew.ml =================================================================== --- trunk/src/uimacbridgenew.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/uimacbridgenew.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -19,7 +19,7 @@ mutable statusMessage : string option };; let theState = ref [| |];; -let unisonDirectory() = System.fspathToPrintString Os.unisonDir +let unisonDirectory() = System.fspathToString Os.unisonDir ;; Callback.register "unisonDirectory" unisonDirectory;; @@ -56,6 +56,7 @@ (* Defined in MyController.m, used to redisplay the table when the status for a row changes *) external displayStatus : string -> unit = "displayStatus";; +let displayStatus s = displayStatus (Unicode.protect s);; (* Called to create callback threads which wait on the C side for callbacks. @@ -345,12 +346,16 @@ Callback.register "unisonInit2" unisonInit2;; let unisonRiToDetails ri = - match ri.whatHappened with - Some (Util.Failed s) -> (Path.toString ri.ri.path1) ^ "\n" ^ s - | _ -> (Path.toString ri.ri.path1) ^ "\n" ^ (Uicommon.details2string ri.ri " ");; + Unicode.protect + (match ri.whatHappened with + Some (Util.Failed s) -> + Path.toString ri.ri.path1 ^ "\n" ^ s + | _ -> + Path.toString ri.ri.path1 ^ "\n" ^ + Uicommon.details2string ri.ri " ");; Callback.register "unisonRiToDetails" unisonRiToDetails;; -let unisonRiToPath ri = Path.toString ri.ri.path1;; +let unisonRiToPath ri = Unicode.protect (Path.toString ri.ri.path1);; Callback.register "unisonRiToPath" unisonRiToPath;; let rcToString rc = @@ -372,6 +377,8 @@ Callback.register "unisonRiToRight" unisonRiToRight;; let unisonRiToFileSize ri = + (*FIX: will not work with files and directory larger than 1 GiB on + 32bit machines! *) Uutil.Filesize.toInt (riLength ri.ri);; Callback.register "unisonRiToFileSize" unisonRiToFileSize;; @@ -420,7 +427,7 @@ let unisonRiToProgress ri = match (ri.statusMessage, ri.whatHappened,ri.ri.replicas) with (None,None,_) -> "" - | (Some s,None,_) -> s + | (Some s,None,_) -> Unicode.protect s | (_,_,Different {direction = Conflict}) -> "" | (_,_,Problem _) -> "" | (_,Some Util.Succeeded,_) -> "done" @@ -428,6 +435,8 @@ Callback.register "unisonRiToProgress" unisonRiToProgress;; let unisonRiToBytesTransferred ri = + (*FIX: will not work when transferring more than 1 GiB on 32bit + machines! *) Uutil.Filesize.toInt ri.bytesTransferred;; Callback.register "unisonRiToBytesTransferred" unisonRiToBytesTransferred;; @@ -436,6 +445,9 @@ (* Defined in MyController.m, used to show diffs *) external displayDiff : string -> string -> unit = "displayDiff";; external displayDiffErr : string -> unit = "displayDiffErr";; +let displayDiff title text = + displayDiff (Unicode.protect title) (Unicode.protect text);; +let displayDiffErr err = displayDiffErr (Unicode.protect err) (* If only properties have changed, we can't diff or merge. 'Can't diff' is produced (uicommon.ml) if diff is attemped @@ -648,10 +660,10 @@ | _ -> assert false (* BOGUS? *);; let unisonFirstRootString() = let replica1, replica2 = roots2niceStrings 32 (Globals.roots()) in - replica1;; + Unicode.protect replica1;; let unisonSecondRootString() = let replica1, replica2 = roots2niceStrings 32 (Globals.roots()) in - replica2;; + Unicode.protect replica2;; Callback.register "unisonFirstRootString" unisonFirstRootString;; Callback.register "unisonSecondRootString" unisonSecondRootString;; @@ -698,5 +710,6 @@ | Unix.Unix_error(ue,s1,s2) -> Printf.sprintf "Unix error(%s,%s,%s)" (Unix.error_message ue) s1 s2 | _ -> Printexc.to_string e;; -Callback.register "unisonExnInfo" unisonExnInfo;; +Callback.register "unisonExnInfo" + (fun e -> Unicode.protect (unisonExnInfo e));; Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-13 22:26:15 UTC (rev 372) +++ trunk/src/update.ml 2009-07-15 15:01:31 UTC (rev 373) @@ -45,6 +45,7 @@ for this file on the next sync. *) (*FIX: consider changing the way case-sensitivity mode is stored in the archive *) +(*FIX: we should use only one Marshal.from_channel *) let archiveFormat = 22 module NameMap = MyMap.Make (Name) @@ -326,7 +327,7 @@ and roots (second line) match skip the third line (time stamp), and read in the archive *) let loadArchiveLocal fspath (thisRoot: string) : - (archive * int * string) option = + (archive * int * string * Proplist.t) option = debug (fun() -> Util.msg "Loading archive from %s\n" (System.fspathToDebugString fspath)); Util.convertUnixErrorsToFatal "loading archive" (fun () -> @@ -360,8 +361,15 @@ try let ((archive, hash, magic) : archive * int * string) = Marshal.from_channel c in + let properties = + try + ignore (input_char c); (* Marker *) + Marshal.from_channel c + with End_of_file -> + Proplist.empty + in close_in c; - Some (archive, hash, magic) + Some (archive, hash, magic, properties) with Failure s -> raise (Util.Fatal (Printf.sprintf "Archive file seems damaged (%s): \ throw away archives on both machines and try again" s)) @@ -372,7 +380,7 @@ None)) (* Inverse to loadArchiveLocal *) -let storeArchiveLocal fspath thisRoot archive hash magic = +let storeArchiveLocal fspath thisRoot archive hash magic properties = debug (fun() -> Util.msg "Saving archive in %s\n" (System.fspathToDebugString fspath)); Util.convertUnixErrorsToFatal "saving archive" (fun () -> @@ -389,6 +397,9 @@ (Util.time2string (Util.time())) ((Case.ops())#modeDesc)); Marshal.to_channel c (archive, hash, magic) [Marshal.No_sharing]; + output_char c '\000'; (* Marker that indicates that the archive + is followed by a property list *) + Marshal.to_channel c properties [Marshal.No_sharing]; close_out c) (* Remove the archieve under the root path [fspath] with archiveVersion [v] *) @@ -482,6 +493,17 @@ debug (fun () -> Printf.eprintf "Setting archive for %s\n" thisRoot); Hashtbl.replace archiveCache thisRoot archive +(* archiveCache: map(rootGlobalName, property list) *) +let archivePropCache = Hashtbl.create 7 + +(* Retrieve an archive property list from the cache *) +let getArchiveProps (thisRoot: string): Proplist.t = + Hashtbl.find archivePropCache thisRoot + +(* Update the property list cache. *) +let setArchivePropsLocal (thisRoot: string) (props: Proplist.t) = + Hashtbl.replace archivePropCache thisRoot props + let fileUnchanged oldInfo newInfo = oldInfo.Fileinfo.typ = `FILE && newInfo.Fileinfo.typ = `FILE && @@ -575,10 +597,11 @@ Lwt.return (Some (0, "")) else begin match loadArchiveLocal arcFspath thisRoot with - Some (arch, hash, magic) -> + Some (arch, hash, magic, properties) -> let info' = Fileinfo.get' arcFspath in if fileUnchanged info info' then begin setArchiveLocal thisRoot arch; + setArchivePropsLocal thisRoot properties; Hashtbl.replace archiveInfoCache thisRoot info; Lwt.return (Some (hash, magic)) end else @@ -590,14 +613,16 @@ end end else begin match loadArchiveLocal arcFspath thisRoot with - Some (arch, hash, magic) -> + Some (arch, hash, magic, properties) -> setArchiveLocal thisRoot arch; + setArchivePropsLocal thisRoot properties; let info = Fileinfo.get' arcFspath in Hashtbl.replace archiveInfoCache thisRoot info; Lwt.return (Some (hash, magic)) | None -> (* No archive found *) setArchiveLocal thisRoot NoArchive; + setArchivePropsLocal thisRoot Proplist.empty; Hashtbl.remove archiveInfoCache thisRoot; Lwt.return (Some (0, "")) end) @@ -1281,8 +1306,8 @@ Error ("Two or more files on a case-sensitive system have names \ identical except for case. They cannot be synchronized to a \ - case-insensitive file system. (" ^ - Path.toString path' ^ ")") + case-insensitive file system. (File '" ^ + Path.toString path' ^ "')") in updates := (nm, uiChild) :: !updates; archive @@ -1495,6 +1520,32 @@ (ArchiveDir (desc, NameMap.add name' arch otherChildren), updates) +(* All the predicates that may change the set of files scanned during + update detection *) +let updatePredicates = + [("immutable", immutable); ("immutablenot", immutablenot); + ("ignore", Globals.ignorePred); ("ignorenot", Globals.ignorenotPred); + ("follow", Path.followPred)] + +let predKey : (string * string list) list Proplist.key = + Proplist.register "update predicates" + +let checkNoUpdatePredicateChange thisRoot = + let props = getArchiveProps thisRoot in + let oldPreds = try Proplist.find predKey props with Not_found -> [] in + let newPreds = + List.map (fun (nm, p) -> (nm, Pred.extern p)) updatePredicates in +(* +List.iter + (fun (nm, l) -> + Format.eprintf "%s at ." nm; + List.iter (fun s -> Format.eprintf " %s at ." s) l) +newPreds; +Format.eprintf "==> %b at ." (oldPreds = newPreds); +*) + setArchivePropsLocal thisRoot (Proplist.add predKey newPreds props); + oldPreds = newPreds + (* for the given path, find the archive and compute the list of update items; as a side effect, update the local archive w.r.t. time-stamps for unchanged files *) @@ -1509,6 +1560,7 @@ deleted. --BCP 2006 *) let (arcName,thisRoot) = archiveName fspath MainArch in let archive = getArchive thisRoot in + let _ = checkNoUpdatePredicateChange thisRoot in let (archive, updates) = Safelist.fold_right (fun path (arch, upd) -> @@ -1590,8 +1642,9 @@ Format.print_flush(); **) let archiveHash = checkArchive true [] archive 0 in + let props = getArchiveProps root in storeArchiveLocal - (Os.fileInUnisonDir newName) root archive archiveHash magic; + (Os.fileInUnisonDir newName) root archive archiveHash magic props; Lwt.return (Some archiveHash) let prepareCommitOnRoot From Jerome.Vouillon at pps.jussieu.fr Wed Jul 15 11:20:39 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Wed, 15 Jul 2009 17:20:39 +0200 Subject: [Unison-hackers] Experiences with unicode support synching Mac-Lin In-Reply-To: <4A5C9D12.80609@strank.info> References: <4A5C9D12.80609@strank.info> Message-ID: <20090715152039.GB12895@pps.jussieu.fr> Hi Stefan, Thanks a lot for your feedback! I have made some changes accordingly. Could you test them? On Tue, Jul 14, 2009 at 04:58:26PM +0200, Stefan Rank wrote: > - It would be great to automatically convert filenames created on > a Mac (NFD) to the NFC normal-form used on Linux (by convention) > when this file is first synched (and therefore created by unison > on the Linux side). Unison should now do this. > With "unicode = true" in the profile, this now preserves all my > filenames, even those with the crazy characters. I am wondering whether I should make "unicode = true" the default now. That should eventually be the case. Besides, that should not be a problem when synchronizing with a Mac. However, when synchronizing between Windows and Unix, filename are currently ISO-8859-1 encoded on the Unix side. So Windows users may have some surprises when upgrading... > I still had non-utf8 filenames on Linux (mostly created previously by > unison). > unison-text will abort with an error message in this case. > unison-gui will fail silently. For some cases, it will show empty > no-synch lines. (Sorry, I don't remember the details now.) I suspect the issue is that we did not make sure that the strings sent to the GUI were Unicode encoded. I have tried to fix that. Regards, -- Jerome From Jerome.Vouillon at pps.jussieu.fr Wed Jul 15 11:24:28 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Wed, 15 Jul 2009 17:24:28 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <4A5C9D12.80609@strank.info> References: <4A5C9D12.80609@strank.info> Message-ID: <20090715152428.GC12895@pps.jussieu.fr> > Compiling the GUI on Mac OS required small patches to not attempt > compiling a backwards compatible binary for 10.4 as this would fail:: > > "MINOSXVERSION=10.5" in src/Makefile.OCaml > "SDKROOT = /Developer/SDKs/MacOSX10.5.sdk" > 3x in src/uimacnew/uimacnew.xcodeproj/project.pbxproj > (only one is necessary, see recent emails on the list) We should really fix this issue. I'm wondering what the best changes are so that: - Alan can easily build binaries compatible with Mac OS X 10.4, - the GUI can be compiled out of the box by everybody else. -- Jerome From alan.schmitt at polytechnique.org Wed Jul 15 11:39:42 2009 From: alan.schmitt at polytechnique.org (Alan Schmitt) Date: Wed, 15 Jul 2009 17:39:42 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090715152428.GC12895@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> Message-ID: <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> On Wed, Jul 15, 2009 at 5:24 PM, Jerome Vouillon < Jerome.Vouillon at pps.jussieu.fr> wrote: > > Compiling the GUI on Mac OS required small patches to not attempt > > compiling a backwards compatible binary for 10.4 as this would fail:: > > > > "MINOSXVERSION=10.5" in src/Makefile.OCaml > > "SDKROOT = /Developer/SDKs/MacOSX10.5.sdk" > > 3x in src/uimacnew/uimacnew.xcodeproj/project.pbxproj > > (only one is necessary, see recent emails on the list) > > We should really fix this issue. I'm wondering what the best changes > are so that: > - Alan can easily build binaries compatible with Mac OS X 10.4, > - the GUI can be compiled out of the box by everybody else. I thought I fixed this a while ago (revision 358 where I incorporated the patch from Martin von Gagern). Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.seas.upenn.edu/pipermail/unison-hackers/attachments/20090715/9fddaf2e/attachment.htm From Jerome.Vouillon at pps.jussieu.fr Wed Jul 15 12:12:08 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Wed, 15 Jul 2009 18:12:08 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> Message-ID: <20090715161207.GA14834@pps.jussieu.fr> On Wed, Jul 15, 2009 at 05:39:42PM +0200, Alan Schmitt wrote: > On Wed, Jul 15, 2009 at 5:24 PM, Jerome Vouillon < > Jerome.Vouillon at pps.jussieu.fr> wrote: > > > > Compiling the GUI on Mac OS required small patches to not attempt > > > compiling a backwards compatible binary for 10.4 as this would fail:: > > > > > > "MINOSXVERSION=10.5" in src/Makefile.OCaml > > > "SDKROOT = /Developer/SDKs/MacOSX10.5.sdk" > > > 3x in src/uimacnew/uimacnew.xcodeproj/project.pbxproj > > > (only one is necessary, see recent emails on the list) > > > > We should really fix this issue. I'm wondering what the best changes > > are so that: > > - Alan can easily build binaries compatible with Mac OS X 10.4, > > - the GUI can be compiled out of the box by everybody else. > > I thought I fixed this a while ago (revision 358 where I incorporated > the patch from Martin > von Gagern). I have reports from Russel Winder and now Stefan Rank that this does not work. I guess they do not have the 10.4 SDK installed. Maybe we should put back "MINOSXVERSION=10.5" in the Makefile? Also, the argument "-sdk macosx$(MINOSXVERSION)" to the "xcode" command does not seem to work. Maybe the SDKROOT definitions in src/uimacnew/uimacnew.xcodeproj/project.pbxproj take precedence, and we should just remove them? -- Jerome From list-ener at strank.info Wed Jul 15 12:13:57 2009 From: list-ener at strank.info (Stefan Rank) Date: Wed, 15 Jul 2009 18:13:57 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> Message-ID: <4A5E0045.8070301@strank.info> on 2009-07-15 17:39 Alan Schmitt said the following: > On Wed, Jul 15, 2009 at 5:24 PM, Jerome Vouillon > > > wrote: > > > Compiling the GUI on Mac OS required small patches to not attempt > > compiling a backwards compatible binary for 10.4 as this would fail:: > > > > "MINOSXVERSION=10.5" in src/Makefile.OCaml > > "SDKROOT = /Developer/SDKs/MacOSX10.5.sdk" > > 3x in src/uimacnew/uimacnew.xcodeproj/project.pbxproj > > (only one is necessary, see recent emails on the list) > > We should really fix this issue. I'm wondering what the best changes > are so that: > - Alan can easily build binaries compatible with Mac OS X 10.4, > - the GUI can be compiled out of the box by everybody else. > > > I thought I fixed this a while ago (revision 358 where I incorporated the patch from Martin > von Gagern). Indeed, the build just now worked out of the box, both text and gui, after a make clean. Sorry for the noise. Still I had errors when first compiling that looked very much like 'wrong SDK'... but I guess they must have been related to ocaml 3.11 then. I managed to build a gui version with 3.11 by applying the above changes, but I had to downgrade to version 3.10.2 anyway to avoid the 'child process' bug in 3.11. stefan From alan.schmitt at polytechnique.org Wed Jul 15 12:22:54 2009 From: alan.schmitt at polytechnique.org (Alan Schmitt) Date: Wed, 15 Jul 2009 18:22:54 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090715161207.GA14834@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <20090715161207.GA14834@pps.jussieu.fr> Message-ID: <25ec8ca60907150922tb649be0p28baa572200eaa89@mail.gmail.com> On Wed, Jul 15, 2009 at 6:12 PM, Jerome Vouillon < Jerome.Vouillon at pps.jussieu.fr> wrote: > Maybe we should put back "MINOSXVERSION=10.5" in the Makefile? > Also, the argument "-sdk macosx$(MINOSXVERSION)" to the "xcode" > command does not seem to work. Maybe the SDKROOT definitions in > src/uimacnew/uimacnew.xcodeproj/project.pbxproj > take precedence, and we should just remove them? > I'm fine with all of this, but I won't have time to do it (and test it) before the end of August. Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.seas.upenn.edu/pipermail/unison-hackers/attachments/20090715/9573db1e/attachment.htm From list-ener at strank.info Wed Jul 15 17:18:39 2009 From: list-ener at strank.info (Stefan Rank) Date: Wed, 15 Jul 2009 23:18:39 +0200 Subject: [Unison-hackers] Experiences with unicode support synching Mac-Lin In-Reply-To: <20090715152039.GB12895@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152039.GB12895@pps.jussieu.fr> Message-ID: <4A5E47AF.4090008@strank.info> on 2009-07-15 17:20 Jerome Vouillon said the following: > Hi Stefan, > > Thanks a lot for your feedback! I have made some changes accordingly. > Could you test them? > > On Tue, Jul 14, 2009 at 04:58:26PM +0200, Stefan Rank wrote: >> - It would be great to automatically convert filenames created on >> a Mac (NFD) to the NFC normal-form used on Linux (by convention) >> when this file is first synched (and therefore created by unison >> on the Linux side). > > Unison should now do this. Works as expected. Thanks a lot! >> With "unicode = true" in the profile, this now preserves all my >> filenames, even those with the crazy characters. > > I am wondering whether I should make "unicode = true" the default now. I would vote for yes, but... > That should eventually be the case. Besides, that should not be a > problem when synchronizing with a Mac. However, when synchronizing > between Windows and Unix, filename are currently ISO-8859-1 encoded on > the Unix side. So Windows users may have some surprises when > upgrading... ...I think this can of worms calls for a transition period. :-) >> I still had non-utf8 filenames on Linux (mostly created previously by >> unison). >> unison-text will abort with an error message in this case. >> unison-gui will fail silently. For some cases, it will show empty >> no-synch lines. (Sorry, I don't remember the details now.) > > I suspect the issue is that we did not make sure that the strings sent > to the GUI were Unicode encoded. I have tried to fix that. Thanks again, stefan From vouillon at seas.upenn.edu Thu Jul 16 15:33:15 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Thu, 16 Jul 2009 15:33:15 -0400 Subject: [Unison-hackers] [unison-svn] r374 - in trunk/src: . ubase Message-ID: <200907161933.n6GJXFYB000383@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-16 15:33:15 -0400 (Thu, 16 Jul 2009) New Revision: 374 Modified: trunk/src/RECENTNEWS trunk/src/mkProjectInfo.ml trunk/src/props.ml trunk/src/props.mli trunk/src/ubase/myMap.ml trunk/src/update.ml trunk/src/uutil.ml trunk/src/uutil.mli Log: * Experimental update detection optimization: do not read the contents of unchanged directories * MyMap.map and MyMap.mapi now iterate in increasing order (rather than in an unspecified way) Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/RECENTNEWS 2009-07-16 19:33:15 UTC (rev 374) @@ -1,5 +1,13 @@ CHANGES FROM VERSION 2.36.-27 +* Experimental update detection optimization: + do not read the contents of unchanged directories +* MyMap.map and MyMap.mapi now iterate in increasing order + (rather than in an unspecified way) + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * GTK UI: disabled scrolling to the first unfinished item during transport. It goes way too fast when lot of small files are synchronized, and it makes it impossible to browse the file list during transport. Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/mkProjectInfo.ml 2009-07-16 19:33:15 UTC (rev 374) @@ -92,3 +92,4 @@ + Modified: trunk/src/props.ml =================================================================== --- trunk/src/props.ml 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/props.ml 2009-07-16 19:33:15 UTC (rev 374) @@ -761,3 +761,28 @@ let perms p = Perm.extract p.perm let syncModtimes = Time.sync + +(* ------------------------------------------------------------------------- *) +(* Directory change stamps *) +(* ------------------------------------------------------------------------- *) + +(* We are reusing the directory length to store a flag indicating that + the directory is unchanged *) + +type dirChangedStamp = Uutil.Filesize.t + +let freshDirStamp () = + let t = + (Unix.gettimeofday () +. sqrt 2. *. float (Unix.getpid ())) *. 1000. + in + Uutil.Filesize.ofFloat t + +let changedDirStamp = Uutil.Filesize.zero + +let setDirChangeFlag p stamp inode = + let stamp = Uutil.Filesize.add stamp (Uutil.Filesize.ofInt inode) in + (setLength p stamp, length p <> stamp) + +let dirMarkedUnchanged p stamp inode = + let stamp = Uutil.Filesize.add stamp (Uutil.Filesize.ofInt inode) in + stamp <> changedDirStamp && length p = stamp Modified: trunk/src/props.mli =================================================================== --- trunk/src/props.mli 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/props.mli 2009-07-16 19:33:15 UTC (rev 374) @@ -29,3 +29,11 @@ val dirDefault : t val syncModtimes : bool Prefs.t + +(* We are reusing the directory length to store a flag indicating that + the directory is unchanged *) +type dirChangedStamp +val freshDirStamp : unit -> dirChangedStamp +val changedDirStamp : dirChangedStamp +val setDirChangeFlag : t -> dirChangedStamp -> int -> t * bool +val dirMarkedUnchanged : t -> dirChangedStamp -> int -> bool Modified: trunk/src/ubase/myMap.ml =================================================================== --- trunk/src/ubase/myMap.ml 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/ubase/myMap.ml 2009-07-16 19:33:15 UTC (rev 374) @@ -164,11 +164,19 @@ let rec map f = function Empty -> Empty - | Node(l, v, d, r, h) -> Node(map f l, v, f d, map f r, h) + | Node(l, v, d, r, h) -> + let l' = map f l in + let d' = f d in + let r' = map f r in + Node(l', v, d', r', h) let rec mapi f = function Empty -> Empty - | Node(l, v, d, r, h) -> Node(mapi f l, v, f v d, mapi f r, h) + | Node(l, v, d, r, h) -> + let l' = mapi f l in + let d' = f v d in + let r' = mapi f r in + Node(l', v, d', r', h) let rec mapii f = function Empty -> Empty Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/update.ml 2009-07-16 19:33:15 UTC (rev 374) @@ -1019,6 +1019,11 @@ let immutablenot = Pred.create "immutablenot" ~advanced:true ("This preference overrides {\\tt immutable}.") +type fastCheckInfos = + { fastCheck : bool; + dirFastCheck : bool; + dirStamp : Props.dirChangedStamp } + (** Status display **) let bigFileLength = 10 * 1024 @@ -1092,6 +1097,60 @@ | NoArchive -> absentInfo +(* Check whether the directory immediate children may have changed *) +let rec noChildChange childUpdates = + match childUpdates with + [] -> + true + | (_, Updates (File _, Previous (`FILE, _, _, _))) :: rem + | (_, Updates (Dir _, Previous (`DIRECTORY, _, _, _))) :: rem + | (_, Updates (Symlink _, Previous (`SYMLINK, _, _, _))) :: rem -> + noChildChange rem + | _ -> + false + +(* Check whether the directory contents is different from what is in + the archive *) +let directoryCheckContentUnchanged + currfspath path info archDesc childUpdates fastCheckInfos = + if + noChildChange childUpdates + && + let (info', dataUnchanged, ressUnchanged) = + Fileinfo.unchanged currfspath path info in + dataUnchanged + then begin + let (archDesc, updated) = + let inode = + match Fileinfo.stamp info with Fileinfo.InodeStamp i -> i | _ -> 0 in + Props.setDirChangeFlag archDesc fastCheckInfos.dirStamp inode in + let updated = + updated || not (Props.same_time info.Fileinfo.desc archDesc) in + if updated then + debugverbose (fun()-> + Util.msg "Contents of directory %s marked unchanged\n" + (Fspath.toDebugString (Fspath.concat currfspath path))); + (Props.setTime archDesc (Props.time info.Fileinfo.desc), updated) + end else begin + let (archDesc, updated) = + Props.setDirChangeFlag archDesc Props.changedDirStamp 0 in + if updated then + debugverbose (fun()-> + Util.msg "Contents of directory %s marked changed\n" + (Fspath.toDebugString (Fspath.concat currfspath path))); + (archDesc, updated) + end + +(* Check whether the list of children of a directory is clearly unchanged *) +let dirContentsClearlyUnchanged info archDesc fastCheckInfos = + fastCheckInfos.dirFastCheck + && + let inode = + match Fileinfo.stamp info with Fileinfo.InodeStamp i -> i | _ -> 0 in + Props.dirMarkedUnchanged archDesc fastCheckInfos.dirStamp inode + && + Props.same_time info.Fileinfo.desc archDesc + (* Check whether a file's permissions have not changed *) let isPropUnchanged info archiveDesc = Props.similar info.Fileinfo.desc archiveDesc @@ -1256,20 +1315,46 @@ remain unchanged, the second a named list of updates; also returns whether the directory is now empty *) let rec buildUpdateChildren - fspath path (archChi: archive NameMap.t) fastCheck + fspath path (archChi: archive NameMap.t) unchangedChildren fastCheckInfos : archive NameMap.t option * (Name.t * Common.updateItem) list * bool = showStatusDir path; - let t = Trace.startTimerQuietly - (Printf.sprintf "checking %s" (Path.toString path)) in let skip = Pred.test immutable (Path.toString path) && not (Pred.test immutablenot (Path.toString path)) in -(* -if skip then (None, [], false) else -let curChildren = ref (NameMap.fold (fun nm _ rem -> (nm, `Ok) :: rem) archChi []) in -*) + if unchangedChildren then begin + if skip then begin + if Prefs.read Xferhint.xferbycopying then + NameMap.iter + (fun nm archive -> + match archive with + ArchiveFile (archDesc, archDig, archStamp, archRess) -> + Xferhint.insertEntry (fspath, Path.child path nm) archDig + | _ -> + ()) + archChi; + (None, [], false) + end else begin + let updates = ref [] in + let archUpdated = ref false in + let handleChild nm archive = + let path' = Path.child path nm in + showStatus path'; + let (arch,uiChild) = + buildUpdateRec archive fspath path' fastCheckInfos in + if uiChild <> NoUpdates then + updates := (nm, uiChild) :: !updates; + match arch with + None -> archive + | Some arch -> archUpdated := true; arch + in + let newChi = NameMap.mapi handleChild archChi in + (* The Recon module relies on the updates to be sorted *) + ((if !archUpdated then Some newChi else None), + Safelist.rev !updates, false) + end + end else let curChildren = ref (getChildren fspath path) in let emptied = not (NameMap.is_empty archChi) && !curChildren = [] in let updates = ref [] in @@ -1294,7 +1379,7 @@ archive end else begin let (arch,uiChild) = - buildUpdateRec archive fspath path' fastCheck in + buildUpdateRec archive fspath path' fastCheckInfos in if uiChild <> NoUpdates then updates := (nm, uiChild) :: !updates; match arch with @@ -1353,12 +1438,11 @@ let arch = handleChild nm NoArchive st in assert (arch = NoArchive)) !curChildren; - Trace.showTimer t; (* The Recon module relies on the updates to be sorted *) ((if !archUpdated then Some newChi else None), Safelist.rev !updates, emptied) -and buildUpdateRec archive currfspath path fastCheck = +and buildUpdateRec archive currfspath path fastCheckInfos = try debug (fun() -> Util.msg "buildUpdate: %s\n" @@ -1375,7 +1459,7 @@ | (`FILE, ArchiveFile (archDesc, archDig, archStamp, archRess)) -> checkContentsChange currfspath path info archive - archDesc archDig archStamp archRess fastCheck + archDesc archDig archStamp archRess fastCheckInfos.fastCheck | (`FILE, _) -> debug (fun() -> Util.msg " buildUpdate -> Updated file\n"); None, @@ -1411,11 +1495,20 @@ (PropsSame, archDesc) else (PropsUpdated, info.Fileinfo.desc) in + let unchanged = + dirContentsClearlyUnchanged info archDesc fastCheckInfos in let (newChildren, childUpdates, emptied) = - buildUpdateChildren currfspath path prevChildren fastCheck in + buildUpdateChildren + currfspath path prevChildren unchanged fastCheckInfos in + let (archDesc, updated) = + directoryCheckContentUnchanged + currfspath path info archDesc childUpdates fastCheckInfos in (begin match newChildren with - Some ch -> Some (ArchiveDir (archDesc, ch)) - | None -> None + Some ch -> + Some (ArchiveDir (archDesc, ch)) + | None -> + if updated then Some (ArchiveDir (archDesc, prevChildren)) + else None end, if childUpdates <> [] || permchange = PropsUpdated then Updates (Dir (desc, childUpdates, permchange, emptied), @@ -1425,7 +1518,8 @@ | (`DIRECTORY, _) -> debug (fun() -> Util.msg " buildUpdate -> New directory\n"); let (newChildren, childUpdates, _) = - buildUpdateChildren currfspath path NameMap.empty fastCheck in + buildUpdateChildren + currfspath path NameMap.empty false fastCheckInfos in (None, Updates (Dir (info.Fileinfo.desc, childUpdates, PropsUpdated, false), oldInfoOf archive)) @@ -1436,12 +1530,17 @@ archive, which is the old archive with time stamps updated appropriately (i.e., for those files whose contents remain unchanged). *) -let rec buildUpdate archive fspath fullpath here path = +let rec buildUpdate archive fspath fullpath here path dirStamp = match Path.deconstruct path with None -> showStatus here; + let fastCheckInfos = + { fastCheck = useFastChecking (); + dirFastCheck = useFastChecking (); + dirStamp = dirStamp } + in let (arch, ui) = - buildUpdateRec archive fspath here (useFastChecking()) in + buildUpdateRec archive fspath here fastCheckInfos in (begin match arch with None -> archive | Some arch -> arch @@ -1509,7 +1608,8 @@ (Props.dummy, NoArchive, NameMap.empty) in let (arch, updates) = - buildUpdate child fspath fullpath (Path.child here name') path' + buildUpdate + child fspath fullpath (Path.child here name') path' dirStamp in (* We need to put a directory in the archive here for path translation. This is fine because we check that there @@ -1529,6 +1629,9 @@ let predKey : (string * string list) list Proplist.key = Proplist.register "update predicates" +let rsrcKey : bool Proplist.key = Proplist.register "rsrc pref" +let dirStampKey : Props.dirChangedStamp Proplist.key = + Proplist.register "unchanged directory stamp" let checkNoUpdatePredicateChange thisRoot = let props = getArchiveProps thisRoot in @@ -1543,8 +1646,19 @@ newPreds; Format.eprintf "==> %b at ." (oldPreds = newPreds); *) - setArchivePropsLocal thisRoot (Proplist.add predKey newPreds props); - oldPreds = newPreds + let oldRsrc = + try Some (Proplist.find rsrcKey props) with Not_found -> None in + let newRsrc = Prefs.read Osx.rsrc in + try + if oldPreds <> newPreds || oldRsrc <> Some newRsrc then raise Not_found; + Proplist.find dirStampKey props + with Not_found -> + let stamp = Props.freshDirStamp () in + setArchivePropsLocal thisRoot + (Proplist.add dirStampKey stamp + (Proplist.add predKey newPreds + (Proplist.add rsrcKey newRsrc props))); + stamp (* for the given path, find the archive and compute the list of update items; as a side effect, update the local archive w.r.t. time-stamps for @@ -1560,7 +1674,10 @@ deleted. --BCP 2006 *) let (arcName,thisRoot) = archiveName fspath MainArch in let archive = getArchive thisRoot in - let _ = checkNoUpdatePredicateChange thisRoot in + let dirStamp = checkNoUpdatePredicateChange thisRoot in +(* +let t1 = Unix.gettimeofday () in +*) let (archive, updates) = Safelist.fold_right (fun path (arch, upd) -> @@ -1568,11 +1685,15 @@ (arch, NoUpdates :: upd) else let (arch', ui) = - buildUpdate arch fspath path Path.empty path + buildUpdate arch fspath path Path.empty path dirStamp in arch', ui :: upd) pathList (archive, []) in +(* +let t2 = Unix.gettimeofday () in +Format.eprintf "Update detection: %f at ." (t2 -. t1); +*) setArchiveLocal thisRoot archive; abortIfAnyMountpointsAreMissing fspath; updates @@ -1996,7 +2117,11 @@ state of the replica... *) let archive = updateArchiveRec ui archive in (* ...and check that this is a good description of what's out in the world *) - let (_, uiNew) = buildUpdateRec archive fspath localPath false in + let fastCheckInfos = + { fastCheck = false; dirFastCheck = false; + dirStamp = Props.changedDirStamp } + in + let (_, uiNew) = buildUpdateRec archive fspath localPath fastCheckInfos in markPossiblyUpdatedRec fspath pathInArchive uiNew; explainUpdate pathInArchive uiNew Modified: trunk/src/uutil.ml =================================================================== --- trunk/src/uutil.ml 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/uutil.ml 2009-07-16 19:33:15 UTC (rev 374) @@ -44,6 +44,7 @@ val dummy : t val add : t -> t -> t val sub : t -> t -> t + val ofFloat : float -> t val toFloat : t -> float val toString : t -> string val ofInt : int -> t @@ -57,10 +58,11 @@ module Filesize : FILESIZE = struct type t = int64 - let zero = Int64.zero - let dummy = Int64.minus_one + let zero = 0L + let dummy = -1L let add = Int64.add let sub = Int64.sub + let ofFloat = Int64.of_float let toFloat = Int64.to_float let toString = Int64.to_string let ofInt x = Int64.of_int x Modified: trunk/src/uutil.mli =================================================================== --- trunk/src/uutil.mli 2009-07-15 15:01:31 UTC (rev 373) +++ trunk/src/uutil.mli 2009-07-16 19:33:15 UTC (rev 374) @@ -20,6 +20,7 @@ val dummy : t val add : t -> t -> t val sub : t -> t -> t + val ofFloat : float -> t val toFloat : t -> float val toString : t -> string val ofInt : int -> t From bcpierce at cis.upenn.edu Thu Jul 16 15:37:49 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Thu, 16 Jul 2009 15:37:49 -0400 Subject: [Unison-hackers] [unison-svn] r374 - in trunk/src: . ubase In-Reply-To: <200907161933.n6GJXFYB000383@yaws.seas.upenn.edu> References: <200907161933.n6GJXFYB000383@yaws.seas.upenn.edu> Message-ID: > * Experimental update detection optimization: > do not read the contents of unchanged directories Nice idea! Just to make sure I understand... If a child of a directory is also a directory, then the fast check is disabled for the parent? - Benjamin > * MyMap.map and MyMap.mapi now iterate in increasing order > (rather than in an unspecified way) > > > Modified: trunk/src/RECENTNEWS > =================================================================== > --- trunk/src/RECENTNEWS 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/RECENTNEWS 2009-07-16 19:33:15 UTC (rev 374) > @@ -1,5 +1,13 @@ > CHANGES FROM VERSION 2.36.-27 > > +* Experimental update detection optimization: > + do not read the contents of unchanged directories > +* MyMap.map and MyMap.mapi now iterate in increasing order > + (rather than in an unspecified way) > + > +------------------------------- > +CHANGES FROM VERSION 2.36.-27 > + > * GTK UI: disabled scrolling to the first unfinished item during > transport. > It goes way too fast when lot of small files are synchronized, and > it > makes it impossible to browse the file list during transport. > > Modified: trunk/src/mkProjectInfo.ml > =================================================================== > --- trunk/src/mkProjectInfo.ml 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/mkProjectInfo.ml 2009-07-16 19:33:15 UTC (rev 374) > @@ -92,3 +92,4 @@ > > > > + > > Modified: trunk/src/props.ml > =================================================================== > --- trunk/src/props.ml 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/props.ml 2009-07-16 19:33:15 UTC (rev 374) > @@ -761,3 +761,28 @@ > let perms p = Perm.extract p.perm > > let syncModtimes = Time.sync > + > +(* > ------------------------------------------------------------------------- *) > +(* Directory change > stamps *) > +(* > ------------------------------------------------------------------------- *) > + > +(* We are reusing the directory length to store a flag indicating > that > + the directory is unchanged *) > + > +type dirChangedStamp = Uutil.Filesize.t > + > +let freshDirStamp () = > + let t = > + (Unix.gettimeofday () +. sqrt 2. *. float (Unix.getpid ())) *. > 1000. > + in > + Uutil.Filesize.ofFloat t > + > +let changedDirStamp = Uutil.Filesize.zero > + > +let setDirChangeFlag p stamp inode = > + let stamp = Uutil.Filesize.add stamp (Uutil.Filesize.ofInt inode) > in > + (setLength p stamp, length p <> stamp) > + > +let dirMarkedUnchanged p stamp inode = > + let stamp = Uutil.Filesize.add stamp (Uutil.Filesize.ofInt inode) > in > + stamp <> changedDirStamp && length p = stamp > > Modified: trunk/src/props.mli > =================================================================== > --- trunk/src/props.mli 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/props.mli 2009-07-16 19:33:15 UTC (rev 374) > @@ -29,3 +29,11 @@ > val dirDefault : t > > val syncModtimes : bool Prefs.t > + > +(* We are reusing the directory length to store a flag indicating > that > + the directory is unchanged *) > +type dirChangedStamp > +val freshDirStamp : unit -> dirChangedStamp > +val changedDirStamp : dirChangedStamp > +val setDirChangeFlag : t -> dirChangedStamp -> int -> t * bool > +val dirMarkedUnchanged : t -> dirChangedStamp -> int -> bool > > Modified: trunk/src/ubase/myMap.ml > =================================================================== > --- trunk/src/ubase/myMap.ml 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/ubase/myMap.ml 2009-07-16 19:33:15 UTC (rev 374) > @@ -164,11 +164,19 @@ > > let rec map f = function > Empty -> Empty > - | Node(l, v, d, r, h) -> Node(map f l, v, f d, map f r, h) > + | Node(l, v, d, r, h) -> > + let l' = map f l in > + let d' = f d in > + let r' = map f r in > + Node(l', v, d', r', h) > > let rec mapi f = function > Empty -> Empty > - | Node(l, v, d, r, h) -> Node(mapi f l, v, f v d, mapi f r, h) > + | Node(l, v, d, r, h) -> > + let l' = mapi f l in > + let d' = f v d in > + let r' = mapi f r in > + Node(l', v, d', r', h) > > let rec mapii f = function > Empty -> Empty > > Modified: trunk/src/update.ml > =================================================================== > --- trunk/src/update.ml 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/update.ml 2009-07-16 19:33:15 UTC (rev 374) > @@ -1019,6 +1019,11 @@ > let immutablenot = Pred.create "immutablenot" ~advanced:true > ("This preference overrides {\\tt immutable}.") > > +type fastCheckInfos = > + { fastCheck : bool; > + dirFastCheck : bool; > + dirStamp : Props.dirChangedStamp } > + > (** Status display **) > > let bigFileLength = 10 * 1024 > @@ -1092,6 +1097,60 @@ > | NoArchive -> > absentInfo > > +(* Check whether the directory immediate children may have changed *) > +let rec noChildChange childUpdates = > + match childUpdates with > + [] -> > + true > + | (_, Updates (File _, Previous (`FILE, _, _, _))) :: rem > + | (_, Updates (Dir _, Previous (`DIRECTORY, _, _, _))) :: rem > + | (_, Updates (Symlink _, Previous (`SYMLINK, _, _, _))) :: rem -> > + noChildChange rem > + | _ -> > + false > + > +(* Check whether the directory contents is different from what is in > + the archive *) > +let directoryCheckContentUnchanged > + currfspath path info archDesc childUpdates fastCheckInfos = > + if > + noChildChange childUpdates > + && > + let (info', dataUnchanged, ressUnchanged) = > + Fileinfo.unchanged currfspath path info in > + dataUnchanged > + then begin > + let (archDesc, updated) = > + let inode = > + match Fileinfo.stamp info with Fileinfo.InodeStamp i -> i | > _ -> 0 in > + Props.setDirChangeFlag archDesc fastCheckInfos.dirStamp inode > in > + let updated = > + updated || not (Props.same_time info.Fileinfo.desc archDesc) in > + if updated then > + debugverbose (fun()-> > + Util.msg "Contents of directory %s marked unchanged\n" > + (Fspath.toDebugString (Fspath.concat currfspath path))); > + (Props.setTime archDesc (Props.time info.Fileinfo.desc), updated) > + end else begin > + let (archDesc, updated) = > + Props.setDirChangeFlag archDesc Props.changedDirStamp 0 in > + if updated then > + debugverbose (fun()-> > + Util.msg "Contents of directory %s marked changed\n" > + (Fspath.toDebugString (Fspath.concat currfspath path))); > + (archDesc, updated) > + end > + > +(* Check whether the list of children of a directory is clearly > unchanged *) > +let dirContentsClearlyUnchanged info archDesc fastCheckInfos = > + fastCheckInfos.dirFastCheck > + && > + let inode = > + match Fileinfo.stamp info with Fileinfo.InodeStamp i -> i | _ -> > 0 in > + Props.dirMarkedUnchanged archDesc fastCheckInfos.dirStamp inode > + && > + Props.same_time info.Fileinfo.desc archDesc > + > (* Check whether a file's permissions have not changed *) > let isPropUnchanged info archiveDesc = > Props.similar info.Fileinfo.desc archiveDesc > @@ -1256,20 +1315,46 @@ > remain unchanged, the second a named list of updates; also returns > whether the directory is now empty *) > let rec buildUpdateChildren > - fspath path (archChi: archive NameMap.t) fastCheck > + fspath path (archChi: archive NameMap.t) unchangedChildren > fastCheckInfos > : archive NameMap.t option * (Name.t * Common.updateItem) list * > bool > = > showStatusDir path; > - let t = Trace.startTimerQuietly > - (Printf.sprintf "checking %s" (Path.toString path)) in > let skip = > Pred.test immutable (Path.toString path) && > not (Pred.test immutablenot (Path.toString path)) > in > -(* > -if skip then (None, [], false) else > -let curChildren = ref (NameMap.fold (fun nm _ rem -> (nm, `Ok) :: > rem) archChi []) in > -*) > + if unchangedChildren then begin > + if skip then begin > + if Prefs.read Xferhint.xferbycopying then > + NameMap.iter > + (fun nm archive -> > + match archive with > + ArchiveFile (archDesc, archDig, archStamp, archRess) > -> > + Xferhint.insertEntry (fspath, Path.child path nm) > archDig > + | _ -> > + ()) > + archChi; > + (None, [], false) > + end else begin > + let updates = ref [] in > + let archUpdated = ref false in > + let handleChild nm archive = > + let path' = Path.child path nm in > + showStatus path'; > + let (arch,uiChild) = > + buildUpdateRec archive fspath path' fastCheckInfos in > + if uiChild <> NoUpdates then > + updates := (nm, uiChild) :: !updates; > + match arch with > + None -> archive > + | Some arch -> archUpdated := true; arch > + in > + let newChi = NameMap.mapi handleChild archChi in > + (* The Recon module relies on the updates to be sorted *) > + ((if !archUpdated then Some newChi else None), > + Safelist.rev !updates, false) > + end > + end else > let curChildren = ref (getChildren fspath path) in > let emptied = not (NameMap.is_empty archChi) && !curChildren = [] in > let updates = ref [] in > @@ -1294,7 +1379,7 @@ > archive > end else begin > let (arch,uiChild) = > - buildUpdateRec archive fspath path' fastCheck in > + buildUpdateRec archive fspath path' fastCheckInfos in > if uiChild <> NoUpdates then > updates := (nm, uiChild) :: !updates; > match arch with > @@ -1353,12 +1438,11 @@ > let arch = handleChild nm NoArchive st in > assert (arch = NoArchive)) > !curChildren; > - Trace.showTimer t; > (* The Recon module relies on the updates to be sorted *) > ((if !archUpdated then Some newChi else None), > Safelist.rev !updates, emptied) > > -and buildUpdateRec archive currfspath path fastCheck = > +and buildUpdateRec archive currfspath path fastCheckInfos = > try > debug (fun() -> > Util.msg "buildUpdate: %s\n" > @@ -1375,7 +1459,7 @@ > | (`FILE, ArchiveFile (archDesc, archDig, archStamp, archRess)) -> > checkContentsChange > currfspath path info archive > - archDesc archDig archStamp archRess fastCheck > + archDesc archDig archStamp archRess > fastCheckInfos.fastCheck > | (`FILE, _) -> > debug (fun() -> Util.msg " buildUpdate -> Updated file\n"); > None, > @@ -1411,11 +1495,20 @@ > (PropsSame, archDesc) > else > (PropsUpdated, info.Fileinfo.desc) in > + let unchanged = > + dirContentsClearlyUnchanged info archDesc fastCheckInfos in > let (newChildren, childUpdates, emptied) = > - buildUpdateChildren currfspath path prevChildren > fastCheck in > + buildUpdateChildren > + currfspath path prevChildren unchanged fastCheckInfos in > + let (archDesc, updated) = > + directoryCheckContentUnchanged > + currfspath path info archDesc childUpdates > fastCheckInfos in > (begin match newChildren with > - Some ch -> Some (ArchiveDir (archDesc, ch)) > - | None -> None > + Some ch -> > + Some (ArchiveDir (archDesc, ch)) > + | None -> > + if updated then Some (ArchiveDir (archDesc, > prevChildren)) > + else None > end, > if childUpdates <> [] || permchange = PropsUpdated then > Updates (Dir (desc, childUpdates, permchange, emptied), > @@ -1425,7 +1518,8 @@ > | (`DIRECTORY, _) -> > debug (fun() -> Util.msg " buildUpdate -> New directory\n"); > let (newChildren, childUpdates, _) = > - buildUpdateChildren currfspath path NameMap.empty > fastCheck in > + buildUpdateChildren > + currfspath path NameMap.empty false fastCheckInfos in > (None, > Updates (Dir (info.Fileinfo.desc, childUpdates, > PropsUpdated, false), > oldInfoOf archive)) > @@ -1436,12 +1530,17 @@ > archive, which is the old archive with time stamps updated > appropriately (i.e., for those files whose contents remain > unchanged). *) > -let rec buildUpdate archive fspath fullpath here path = > +let rec buildUpdate archive fspath fullpath here path dirStamp = > match Path.deconstruct path with > None -> > showStatus here; > + let fastCheckInfos = > + { fastCheck = useFastChecking (); > + dirFastCheck = useFastChecking (); > + dirStamp = dirStamp } > + in > let (arch, ui) = > - buildUpdateRec archive fspath here (useFastChecking()) in > + buildUpdateRec archive fspath here fastCheckInfos in > (begin match arch with > None -> archive > | Some arch -> arch > @@ -1509,7 +1608,8 @@ > (Props.dummy, NoArchive, NameMap.empty) > in > let (arch, updates) = > - buildUpdate child fspath fullpath (Path.child here > name') path' > + buildUpdate > + child fspath fullpath (Path.child here name') path' > dirStamp > in > (* We need to put a directory in the archive here for path > translation. This is fine because we check that there > @@ -1529,6 +1629,9 @@ > > let predKey : (string * string list) list Proplist.key = > Proplist.register "update predicates" > +let rsrcKey : bool Proplist.key = Proplist.register "rsrc pref" > +let dirStampKey : Props.dirChangedStamp Proplist.key = > + Proplist.register "unchanged directory stamp" > > let checkNoUpdatePredicateChange thisRoot = > let props = getArchiveProps thisRoot in > @@ -1543,8 +1646,19 @@ > newPreds; > Format.eprintf "==> %b at ." (oldPreds = newPreds); > *) > - setArchivePropsLocal thisRoot (Proplist.add predKey newPreds > props); > - oldPreds = newPreds > + let oldRsrc = > + try Some (Proplist.find rsrcKey props) with Not_found -> None in > + let newRsrc = Prefs.read Osx.rsrc in > + try > + if oldPreds <> newPreds || oldRsrc <> Some newRsrc then raise > Not_found; > + Proplist.find dirStampKey props > + with Not_found -> > + let stamp = Props.freshDirStamp () in > + setArchivePropsLocal thisRoot > + (Proplist.add dirStampKey stamp > + (Proplist.add predKey newPreds > + (Proplist.add rsrcKey newRsrc props))); > + stamp > > (* for the given path, find the archive and compute the list of update > items; as a side effect, update the local archive w.r.t. time- > stamps for > @@ -1560,7 +1674,10 @@ > deleted. --BCP 2006 *) > let (arcName,thisRoot) = archiveName fspath MainArch in > let archive = getArchive thisRoot in > - let _ = checkNoUpdatePredicateChange thisRoot in > + let dirStamp = checkNoUpdatePredicateChange thisRoot in > +(* > +let t1 = Unix.gettimeofday () in > +*) > let (archive, updates) = > Safelist.fold_right > (fun path (arch, upd) -> > @@ -1568,11 +1685,15 @@ > (arch, NoUpdates :: upd) > else > let (arch', ui) = > - buildUpdate arch fspath path Path.empty path > + buildUpdate arch fspath path Path.empty path dirStamp > in > arch', ui :: upd) > pathList (archive, []) > in > +(* > +let t2 = Unix.gettimeofday () in > +Format.eprintf "Update detection: %f at ." (t2 -. t1); > +*) > setArchiveLocal thisRoot archive; > abortIfAnyMountpointsAreMissing fspath; > updates > @@ -1996,7 +2117,11 @@ > state of the replica... *) > let archive = updateArchiveRec ui archive in > (* ...and check that this is a good description of what's out in > the world *) > - let (_, uiNew) = buildUpdateRec archive fspath localPath false in > + let fastCheckInfos = > + { fastCheck = false; dirFastCheck = false; > + dirStamp = Props.changedDirStamp } > + in > + let (_, uiNew) = buildUpdateRec archive fspath localPath > fastCheckInfos in > markPossiblyUpdatedRec fspath pathInArchive uiNew; > explainUpdate pathInArchive uiNew > > > Modified: trunk/src/uutil.ml > =================================================================== > --- trunk/src/uutil.ml 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/uutil.ml 2009-07-16 19:33:15 UTC (rev 374) > @@ -44,6 +44,7 @@ > val dummy : t > val add : t -> t -> t > val sub : t -> t -> t > + val ofFloat : float -> t > val toFloat : t -> float > val toString : t -> string > val ofInt : int -> t > @@ -57,10 +58,11 @@ > > module Filesize : FILESIZE = struct > type t = int64 > - let zero = Int64.zero > - let dummy = Int64.minus_one > + let zero = 0L > + let dummy = -1L > let add = Int64.add > let sub = Int64.sub > + let ofFloat = Int64.of_float > let toFloat = Int64.to_float > let toString = Int64.to_string > let ofInt x = Int64.of_int x > > Modified: trunk/src/uutil.mli > =================================================================== > --- trunk/src/uutil.mli 2009-07-15 15:01:31 UTC (rev 373) > +++ trunk/src/uutil.mli 2009-07-16 19:33:15 UTC (rev 374) > @@ -20,6 +20,7 @@ > val dummy : t > val add : t -> t -> t > val sub : t -> t -> t > + val ofFloat : float -> t > val toFloat : t -> float > val toString : t -> string > val ofInt : int -> t > > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From Jerome.Vouillon at pps.jussieu.fr Thu Jul 16 16:28:34 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Thu, 16 Jul 2009 22:28:34 +0200 Subject: [Unison-hackers] Update detection optimization In-Reply-To: References: <200907161933.n6GJXFYB000383@yaws.seas.upenn.edu> Message-ID: <20090716202834.GA24608@pps.jussieu.fr> On Thu, Jul 16, 2009 at 03:37:49PM -0400, Benjamin Pierce wrote: > > * Experimental update detection optimization: > > do not read the contents of unchanged directories > > Nice idea! > > Just to make sure I understand... If a child of a directory is also a > directory, then the fast check is disabled for the parent? No, it is not disabled. Unison still has to scan recursively the children of a directory (files included) for correctness. But it gets the list of children from the archive. It does not read the directory contents, reorder it, check that there is not bad filenames or duplicated filenames and finally match the directory contents with the archive contents. So, one gets a significant speed-up even in this case. The speed-up is most dramatic with immutable directories, as the system does not have to read their contents from disk at all. For this to work, one has to make sure that the archive contents reflects the directory contents, so a directory is marked as unchanged only when it has no new or deleted childs. Also, the optimization has to be disabled whenever a preference (follow, ignore, ...) that may affect Unison view of the filesystem is changed. So, Unison keeps track of these preferences in the archive. I have the following (approximate) numbers for my home directory. "Cold cache" means when everything has to be read from the disk, while "hot cache" means that everything is already cached in memory and there is no disk access. These number are for fully synchronized replicas, when the optimization is most effective. Also, I have large maildir directories synchronized with the "immutable" preference. Finally, this is with xferbycopying disabled, otherwise Unison takes 70% of its time filling the hash tables :-(. Laptop with SSD drive With optimization Without optimization Speed-up Cold cache 2.8 5.8 x 2.0 Hot cache 0.42 2.12 x 5.0 Desktop computer with hard drive With optimization Without optimization Cold cache 11.4 19.3 x 1.7 Hot cache 0.28 1.32 x 4.7 -- Jerome From vouillon at seas.upenn.edu Thu Jul 16 18:13:45 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Thu, 16 Jul 2009 18:13:45 -0400 Subject: [Unison-hackers] [unison-svn] r375 - trunk/src Message-ID: <200907162213.n6GMDjkI004244@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-16 18:13:45 -0400 (Thu, 16 Jul 2009) New Revision: 375 Modified: trunk/src/RECENTNEWS trunk/src/mkProjectInfo.ml trunk/src/update.ml Log: * Fixed small bug in new update detection optimization: do not perform the optimization for directories with ignored children in the archive. Indeed, we cannot rely on the archive in this case instead of reading the directory contents from the filesystem (systematically pruning the ignored children from the archive is too costly). Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-16 19:33:15 UTC (rev 374) +++ trunk/src/RECENTNEWS 2009-07-16 22:13:45 UTC (rev 375) @@ -1,5 +1,15 @@ CHANGES FROM VERSION 2.36.-27 +* Fixed small bug in new update detection optimization: + do not perform the optimization for directories with ignored + children in the archive. Indeed, we cannot rely on the archive in + this case instead of reading the directory contents from the + filesystem (systematically pruning the ignored children from the + archive is too costly). + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * Experimental update detection optimization: do not read the contents of unchanged directories * MyMap.map and MyMap.mapi now iterate in increasing order Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-16 19:33:15 UTC (rev 374) +++ trunk/src/mkProjectInfo.ml 2009-07-16 22:13:45 UTC (rev 375) @@ -93,3 +93,4 @@ + Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-16 19:33:15 UTC (rev 374) +++ trunk/src/update.ml 2009-07-16 22:13:45 UTC (rev 375) @@ -1316,7 +1316,8 @@ whether the directory is now empty *) let rec buildUpdateChildren fspath path (archChi: archive NameMap.t) unchangedChildren fastCheckInfos - : archive NameMap.t option * (Name.t * Common.updateItem) list * bool + : archive NameMap.t option * (Name.t * Common.updateItem) list * + bool * bool = showStatusDir path; let skip = @@ -1334,7 +1335,7 @@ | _ -> ()) archChi; - (None, [], false) + (None, [], false, false) end else begin let updates = ref [] in let archUpdated = ref false in @@ -1352,16 +1353,18 @@ let newChi = NameMap.mapi handleChild archChi in (* The Recon module relies on the updates to be sorted *) ((if !archUpdated then Some newChi else None), - Safelist.rev !updates, false) + Safelist.rev !updates, false, false) end end else let curChildren = ref (getChildren fspath path) in let emptied = not (NameMap.is_empty archChi) && !curChildren = [] in + let hasIgnoredChildren = ref false in let updates = ref [] in let archUpdated = ref false in let handleChild nm archive status = let path' = Path.child path nm in if Globals.shouldIgnore path' then begin + hasIgnoredChildren := true; debugignore (fun()->Util.msg "buildUpdateChildren: ignoring path %s\n" (Path.toString path')); archive @@ -1440,7 +1443,7 @@ !curChildren; (* The Recon module relies on the updates to be sorted *) ((if !archUpdated then Some newChi else None), - Safelist.rev !updates, emptied) + Safelist.rev !updates, emptied, !hasIgnoredChildren) and buildUpdateRec archive currfspath path fastCheckInfos = try @@ -1497,10 +1500,20 @@ (PropsUpdated, info.Fileinfo.desc) in let unchanged = dirContentsClearlyUnchanged info archDesc fastCheckInfos in - let (newChildren, childUpdates, emptied) = + let (newChildren, childUpdates, emptied, hasIgnoredChildren) = buildUpdateChildren currfspath path prevChildren unchanged fastCheckInfos in let (archDesc, updated) = + (* If the archive contain ignored children, we cannot use it to + skip reading the directory contents from the filesystem. + Actually, we could check for ignored children in the archive, + but this has a significant cost. We could mark directories + with ignored children, and only perform the checks for them, + but that does not seem worthwhile, are directories with + ignored children are expected to be rare in the archive. + (These are files or directories which used not to be + ignored and are now ignored.) *) + if hasIgnoredChildren then (archDesc, true) else directoryCheckContentUnchanged currfspath path info archDesc childUpdates fastCheckInfos in (begin match newChildren with @@ -1517,7 +1530,7 @@ NoUpdates) | (`DIRECTORY, _) -> debug (fun() -> Util.msg " buildUpdate -> New directory\n"); - let (newChildren, childUpdates, _) = + let (newChildren, childUpdates, _, _) = buildUpdateChildren currfspath path NameMap.empty false fastCheckInfos in (None, From bcpierce at cis.upenn.edu Thu Jul 16 22:32:05 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Thu, 16 Jul 2009 22:32:05 -0400 Subject: [Unison-hackers] [unison-svn] r375 - trunk/src In-Reply-To: <200907162213.n6GMDjkI004244@yaws.seas.upenn.edu> References: <200907162213.n6GMDjkI004244@yaws.seas.upenn.edu> Message-ID: Hi Jerome, I've upgraded to this version, but it still appears to be scanning ignored subdirectories. Is it possible that my archives are messed up from running the previous version, or is there perhaps another bug to squash...? - B On Jul 16, 2009, at 6:13 PM, vouillon at seas.upenn.edu wrote: > Author: vouillon > Date: 2009-07-16 18:13:45 -0400 (Thu, 16 Jul 2009) > New Revision: 375 > > Modified: > trunk/src/RECENTNEWS > trunk/src/mkProjectInfo.ml > trunk/src/update.ml > Log: > * Fixed small bug in new update detection optimization: > do not perform the optimization for directories with ignored > children in the archive. Indeed, we cannot rely on the archive in > this case instead of reading the directory contents from the > filesystem (systematically pruning the ignored children from the > archive is too costly). > > > Modified: trunk/src/RECENTNEWS > =================================================================== > --- trunk/src/RECENTNEWS 2009-07-16 19:33:15 UTC (rev 374) > +++ trunk/src/RECENTNEWS 2009-07-16 22:13:45 UTC (rev 375) > @@ -1,5 +1,15 @@ > CHANGES FROM VERSION 2.36.-27 > > +* Fixed small bug in new update detection optimization: > + do not perform the optimization for directories with ignored > + children in the archive. Indeed, we cannot rely on the archive in > + this case instead of reading the directory contents from the > + filesystem (systematically pruning the ignored children from the > + archive is too costly). > + > +------------------------------- > +CHANGES FROM VERSION 2.36.-27 > + > * Experimental update detection optimization: > do not read the contents of unchanged directories > * MyMap.map and MyMap.mapi now iterate in increasing order > > Modified: trunk/src/mkProjectInfo.ml > =================================================================== > --- trunk/src/mkProjectInfo.ml 2009-07-16 19:33:15 UTC (rev 374) > +++ trunk/src/mkProjectInfo.ml 2009-07-16 22:13:45 UTC (rev 375) > @@ -93,3 +93,4 @@ > > > > + > > Modified: trunk/src/update.ml > =================================================================== > --- trunk/src/update.ml 2009-07-16 19:33:15 UTC (rev 374) > +++ trunk/src/update.ml 2009-07-16 22:13:45 UTC (rev 375) > @@ -1316,7 +1316,8 @@ > whether the directory is now empty *) > let rec buildUpdateChildren > fspath path (archChi: archive NameMap.t) unchangedChildren > fastCheckInfos > - : archive NameMap.t option * (Name.t * Common.updateItem) list > * bool > + : archive NameMap.t option * (Name.t * Common.updateItem) list * > + bool * bool > = > showStatusDir path; > let skip = > @@ -1334,7 +1335,7 @@ > | _ -> > ()) > archChi; > - (None, [], false) > + (None, [], false, false) > end else begin > let updates = ref [] in > let archUpdated = ref false in > @@ -1352,16 +1353,18 @@ > let newChi = NameMap.mapi handleChild archChi in > (* The Recon module relies on the updates to be sorted *) > ((if !archUpdated then Some newChi else None), > - Safelist.rev !updates, false) > + Safelist.rev !updates, false, false) > end > end else > let curChildren = ref (getChildren fspath path) in > let emptied = not (NameMap.is_empty archChi) && !curChildren = [] in > + let hasIgnoredChildren = ref false in > let updates = ref [] in > let archUpdated = ref false in > let handleChild nm archive status = > let path' = Path.child path nm in > if Globals.shouldIgnore path' then begin > + hasIgnoredChildren := true; > debugignore (fun()->Util.msg "buildUpdateChildren: ignoring > path %s\n" > (Path.toString path')); > archive > @@ -1440,7 +1443,7 @@ > !curChildren; > (* The Recon module relies on the updates to be sorted *) > ((if !archUpdated then Some newChi else None), > - Safelist.rev !updates, emptied) > + Safelist.rev !updates, emptied, !hasIgnoredChildren) > > and buildUpdateRec archive currfspath path fastCheckInfos = > try > @@ -1497,10 +1500,20 @@ > (PropsUpdated, info.Fileinfo.desc) in > let unchanged = > dirContentsClearlyUnchanged info archDesc fastCheckInfos in > - let (newChildren, childUpdates, emptied) = > + let (newChildren, childUpdates, emptied, > hasIgnoredChildren) = > buildUpdateChildren > currfspath path prevChildren unchanged fastCheckInfos in > let (archDesc, updated) = > + (* If the archive contain ignored children, we cannot use > it to > + skip reading the directory contents from the filesystem. > + Actually, we could check for ignored children in the > archive, > + but this has a significant cost. We could mark > directories > + with ignored children, and only perform the checks for > them, > + but that does not seem worthwhile, are directories with > + ignored children are expected to be rare in the archive. > + (These are files or directories which used not to be > + ignored and are now ignored.) *) > + if hasIgnoredChildren then (archDesc, true) else > directoryCheckContentUnchanged > currfspath path info archDesc childUpdates > fastCheckInfos in > (begin match newChildren with > @@ -1517,7 +1530,7 @@ > NoUpdates) > | (`DIRECTORY, _) -> > debug (fun() -> Util.msg " buildUpdate -> New directory\n"); > - let (newChildren, childUpdates, _) = > + let (newChildren, childUpdates, _, _) = > buildUpdateChildren > currfspath path NameMap.empty false fastCheckInfos in > (None, > > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From Jerome.Vouillon at pps.jussieu.fr Fri Jul 17 04:01:47 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Fri, 17 Jul 2009 10:01:47 +0200 Subject: [Unison-hackers] [unison-svn] r375 - trunk/src In-Reply-To: References: <200907162213.n6GMDjkI004244@yaws.seas.upenn.edu> Message-ID: <20090717080147.GA6775@pps.jussieu.fr> Hi Benjamin, On Thu, Jul 16, 2009 at 10:32:05PM -0400, Benjamin Pierce wrote: > I've upgraded to this version, but it still appears to be scanning > ignored subdirectories. Is it possible that my archives are messed up > from running the previous version, or is there perhaps another bug to > squash...? Yes, they are messed up. But just add a dummy ignore preference line in your profile and synchronize once. That should fix the problem, as it will reset the set of directories wrongly subject to the optimization. -- Jerome From vouillon at seas.upenn.edu Fri Jul 17 04:15:03 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Fri, 17 Jul 2009 04:15:03 -0400 Subject: [Unison-hackers] [unison-svn] r376 - trunk/src Message-ID: <200907170815.n6H8F3pC018601@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-17 04:15:02 -0400 (Fri, 17 Jul 2009) New Revision: 376 Modified: trunk/src/RECENTNEWS trunk/src/mkProjectInfo.ml trunk/src/update.ml Log: * Correction to previous fix: do not perform the optimization for directories with ignored children *in the archive*. (The previous fix was also rejecting directories with ignored children on disk, which is way too conservative.) Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-16 22:13:45 UTC (rev 375) +++ trunk/src/RECENTNEWS 2009-07-17 08:15:02 UTC (rev 376) @@ -1,5 +1,13 @@ CHANGES FROM VERSION 2.36.-27 +* Correction to previous fix: do not perform the optimization for + directories with ignored children *in the archive*. (The previous + fix was also rejecting directories with ignored children on disk, + which is way too conservative.) + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * Fixed small bug in new update detection optimization: do not perform the optimization for directories with ignored children in the archive. Indeed, we cannot rely on the archive in Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-16 22:13:45 UTC (rev 375) +++ trunk/src/mkProjectInfo.ml 2009-07-17 08:15:02 UTC (rev 376) @@ -94,3 +94,4 @@ + Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-16 22:13:45 UTC (rev 375) +++ trunk/src/update.ml 2009-07-17 08:15:02 UTC (rev 376) @@ -1364,7 +1364,7 @@ let handleChild nm archive status = let path' = Path.child path nm in if Globals.shouldIgnore path' then begin - hasIgnoredChildren := true; + hasIgnoredChildren := !hasIgnoredChildren || (archive <> NoArchive); debugignore (fun()->Util.msg "buildUpdateChildren: ignoring path %s\n" (Path.toString path')); archive From Jerome.Vouillon at pps.jussieu.fr Fri Jul 17 04:45:19 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Fri, 17 Jul 2009 10:45:19 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <4A5E0045.8070301@strank.info> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> Message-ID: <20090717084519.GA7733@pps.jussieu.fr> On Wed, Jul 15, 2009 at 06:13:57PM +0200, Stefan Rank wrote: > on 2009-07-15 17:39 Alan Schmitt said the following: > > I thought I fixed this a while ago (revision 358 where I > > incorporated the patch from Martin von Gagern). > > Indeed, the build just now worked out of the box, both text and gui, > after a make clean. > Sorry for the noise. > > Still I had errors when first compiling that looked very much like > 'wrong SDK'... > but I guess they must have been related to ocaml 3.11 then. I managed to > build a gui version with 3.11 by applying the above changes, but I had > to downgrade to version 3.10.2 anyway to avoid the 'child process' bug > in 3.11. It would be great if someone could try with ocaml 3.11.1 (which does not have the bug anymore) and report back. -- Jerome From bcpierce at cis.upenn.edu Fri Jul 17 10:49:30 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Fri, 17 Jul 2009 10:49:30 -0400 Subject: [Unison-hackers] [unison-svn] r375 - trunk/src In-Reply-To: <20090717080147.GA6775@pps.jussieu.fr> References: <200907162213.n6GMDjkI004244@yaws.seas.upenn.edu> <20090717080147.GA6775@pps.jussieu.fr> Message-ID: <3DDA4901-B99F-4389-892F-CCE037F59F55@cis.upenn.edu> Thanks -- that works. - B On Jul 17, 2009, at 4:01 AM, Jerome Vouillon wrote: > Hi Benjamin, > > On Thu, Jul 16, 2009 at 10:32:05PM -0400, Benjamin Pierce wrote: >> I've upgraded to this version, but it still appears to be scanning >> ignored subdirectories. Is it possible that my archives are messed >> up >> from running the previous version, or is there perhaps another bug to >> squash...? > > Yes, they are messed up. But just add a dummy ignore preference line > in your profile and synchronize once. That should fix the problem, as > it will reset the set of directories wrongly subject to the > optimization. > > -- Jerome > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From vouillon at seas.upenn.edu Fri Jul 17 17:41:59 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Fri, 17 Jul 2009 17:41:59 -0400 Subject: [Unison-hackers] [unison-svn] r377 - trunk/src Message-ID: <200907172141.n6HLfxP0003056@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-17 17:41:58 -0400 (Fri, 17 Jul 2009) New Revision: 377 Modified: trunk/src/.depend trunk/src/Makefile.OCaml trunk/src/RECENTNEWS trunk/src/copy.ml trunk/src/copy.mli trunk/src/files.ml trunk/src/fingerprint.ml trunk/src/fingerprint.mli trunk/src/mkProjectInfo.ml trunk/src/os.ml trunk/src/os.mli trunk/src/stasher.ml trunk/src/stasher.mli trunk/src/update.ml trunk/src/update.mli trunk/src/xferhint.ml trunk/src/xferhint.mli Log: * Performance improvement in Xferhint module. Update this cache more accurately during transport. Modified: trunk/src/.depend =================================================================== --- trunk/src/.depend 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/.depend 2009-07-17 21:41:58 UTC (rev 377) @@ -15,19 +15,19 @@ fingerprint.cmi: uutil.cmi path.cmi fspath.cmi fs.cmi: system/system_intf.cmo fspath.cmi fspath.cmi: system.cmi path.cmi name.cmi -globals.cmi: ubase/prefs.cmi path.cmi lwt/lwt.cmi common.cmi +globals.cmi: ubase/prefs.cmi pred.cmi path.cmi lwt/lwt.cmi common.cmi lock.cmi: system.cmi name.cmi: os.cmi: system.cmi props.cmi path.cmi name.cmi fspath.cmi fileinfo.cmi osx.cmi: uutil.cmi ubase/prefs.cmi path.cmi fspath.cmi fingerprint.cmi -path.cmi: name.cmi +path.cmi: pred.cmi name.cmi pred.cmi: props.cmi: uutil.cmi ubase/prefs.cmi path.cmi osx.cmi fspath.cmi recon.cmi: path.cmi common.cmi remote.cmi: ubase/prefs.cmi lwt/lwt.cmi fspath.cmi common.cmi clroot.cmi \ bytearray.cmi sortri.cmi: common.cmi -stasher.cmi: ubase/prefs.cmi path.cmi os.cmi fspath.cmi +stasher.cmi: update.cmi ubase/prefs.cmi path.cmi os.cmi fspath.cmi strings.cmi: system.cmi: system/system_intf.cmo terminal.cmi: @@ -44,7 +44,8 @@ update.cmi: uutil.cmi tree.cmi props.cmi path.cmi osx.cmi os.cmi name.cmi \ lwt/lwt.cmi fspath.cmi fileinfo.cmi common.cmi uutil.cmi: -xferhint.cmi: ubase/prefs.cmi path.cmi os.cmi fspath.cmi +xferhint.cmi: props.cmi ubase/prefs.cmi path.cmi osx.cmi os.cmi fspath.cmi \ + fileinfo.cmi abort.cmo: uutil.cmi ubase/util.cmi ubase/trace.cmi ubase/prefs.cmi abort.cmi abort.cmx: uutil.cmx ubase/util.cmx ubase/trace.cmx ubase/prefs.cmx abort.cmi bytearray.cmo: bytearray.cmi @@ -59,16 +60,16 @@ osx.cmi os.cmi name.cmi fspath.cmi fileinfo.cmi common.cmi common.cmx: uutil.cmx ubase/util.cmx ubase/safelist.cmx props.cmx path.cmx \ osx.cmx os.cmx name.cmx fspath.cmx fileinfo.cmx common.cmi -copy.cmo: xferhint.cmi uutil.cmi ubase/util.cmi transfer.cmi ubase/trace.cmi \ - ubase/safelist.cmi remote.cmi props.cmi ubase/prefs.cmi path.cmi osx.cmi \ - os.cmi lwt/lwt_util.cmi lwt/lwt.cmi globals.cmi fspath.cmi fs.cmi \ - fileinfo.cmi external.cmi common.cmi clroot.cmi bytearray.cmi abort.cmi \ - copy.cmi -copy.cmx: xferhint.cmx uutil.cmx ubase/util.cmx transfer.cmx ubase/trace.cmx \ - ubase/safelist.cmx remote.cmx props.cmx ubase/prefs.cmx path.cmx osx.cmx \ - os.cmx lwt/lwt_util.cmx lwt/lwt.cmx globals.cmx fspath.cmx fs.cmx \ - fileinfo.cmx external.cmx common.cmx clroot.cmx bytearray.cmx abort.cmx \ - copy.cmi +copy.cmo: xferhint.cmi uutil.cmi ubase/util.cmi update.cmi transfer.cmi \ + ubase/trace.cmi ubase/safelist.cmi remote.cmi props.cmi ubase/prefs.cmi \ + path.cmi osx.cmi os.cmi lwt/lwt_util.cmi lwt/lwt.cmi globals.cmi \ + fspath.cmi fs.cmi fileinfo.cmi external.cmi common.cmi clroot.cmi \ + bytearray.cmi abort.cmi copy.cmi +copy.cmx: xferhint.cmx uutil.cmx ubase/util.cmx update.cmx transfer.cmx \ + ubase/trace.cmx ubase/safelist.cmx remote.cmx props.cmx ubase/prefs.cmx \ + path.cmx osx.cmx os.cmx lwt/lwt_util.cmx lwt/lwt.cmx globals.cmx \ + fspath.cmx fs.cmx fileinfo.cmx external.cmx common.cmx clroot.cmx \ + bytearray.cmx abort.cmx copy.cmi external.cmo: ubase/util.cmi system.cmi ubase/safelist.cmi lwt/lwt_util.cmi \ lwt/lwt_unix.cmi lwt/lwt.cmi external.cmi external.cmx: ubase/util.cmx system.cmx ubase/safelist.cmx lwt/lwt_util.cmx \ @@ -77,18 +78,18 @@ osx.cmi fspath.cmi fs.cmi fileinfo.cmi fileinfo.cmx: ubase/util.cmx system.cmx props.cmx ubase/prefs.cmx path.cmx \ osx.cmx fspath.cmx fs.cmx fileinfo.cmi -files.cmo: uutil.cmi ubase/util.cmi update.cmi ubase/trace.cmi system.cmi \ - stasher.cmi ubase/safelist.cmi ubase/rx.cmi remote.cmi props.cmi \ - ubase/prefs.cmi path.cmi osx.cmi os.cmi name.cmi lwt/lwt_util.cmi \ - lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi fs.cmi \ - fingerprint.cmi fileinfo.cmi external.cmi copy.cmi common.cmi abort.cmi \ - files.cmi -files.cmx: uutil.cmx ubase/util.cmx update.cmx ubase/trace.cmx system.cmx \ - stasher.cmx ubase/safelist.cmx ubase/rx.cmx remote.cmx props.cmx \ - ubase/prefs.cmx path.cmx osx.cmx os.cmx name.cmx lwt/lwt_util.cmx \ - lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx fs.cmx \ - fingerprint.cmx fileinfo.cmx external.cmx copy.cmx common.cmx abort.cmx \ - files.cmi +files.cmo: xferhint.cmi uutil.cmi ubase/util.cmi update.cmi ubase/trace.cmi \ + system.cmi stasher.cmi ubase/safelist.cmi ubase/rx.cmi remote.cmi \ + props.cmi ubase/prefs.cmi path.cmi osx.cmi os.cmi name.cmi \ + lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi \ + fs.cmi fingerprint.cmi fileinfo.cmi external.cmi copy.cmi common.cmi \ + abort.cmi files.cmi +files.cmx: xferhint.cmx uutil.cmx ubase/util.cmx update.cmx ubase/trace.cmx \ + system.cmx stasher.cmx ubase/safelist.cmx ubase/rx.cmx remote.cmx \ + props.cmx ubase/prefs.cmx path.cmx osx.cmx os.cmx name.cmx \ + lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx \ + fs.cmx fingerprint.cmx fileinfo.cmx external.cmx copy.cmx common.cmx \ + abort.cmx files.cmi fileutil.cmo: fileutil.cmi fileutil.cmx: fileutil.cmi fingerprint.cmo: uutil.cmi ubase/util.cmi fspath.cmi fs.cmi fingerprint.cmi @@ -165,14 +166,14 @@ path.cmi common.cmi sortri.cmi sortri.cmx: ubase/util.cmx ubase/safelist.cmx ubase/prefs.cmx pred.cmx \ path.cmx common.cmx sortri.cmi -stasher.cmo: ubase/util.cmi system.cmi ubase/safelist.cmi remote.cmi \ - props.cmi ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi \ - lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi fingerprint.cmi \ - fileutil.cmi fileinfo.cmi copy.cmi common.cmi stasher.cmi -stasher.cmx: ubase/util.cmx system.cmx ubase/safelist.cmx remote.cmx \ - props.cmx ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx \ - lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx fingerprint.cmx \ - fileutil.cmx fileinfo.cmx copy.cmx common.cmx stasher.cmi +stasher.cmo: xferhint.cmi ubase/util.cmi update.cmi system.cmi \ + ubase/safelist.cmi remote.cmi props.cmi ubase/prefs.cmi pred.cmi path.cmi \ + osx.cmi os.cmi lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi \ + fingerprint.cmi fileutil.cmi fileinfo.cmi copy.cmi common.cmi stasher.cmi +stasher.cmx: xferhint.cmx ubase/util.cmx update.cmx system.cmx \ + ubase/safelist.cmx remote.cmx props.cmx ubase/prefs.cmx pred.cmx path.cmx \ + osx.cmx os.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx \ + fingerprint.cmx fileutil.cmx fileinfo.cmx copy.cmx common.cmx stasher.cmi strings.cmo: strings.cmi strings.cmx: strings.cmi system.cmo: system.cmi @@ -268,17 +269,15 @@ unicode_tables.cmo: unicode_tables.cmx: update.cmo: xferhint.cmi uutil.cmi ubase/util.cmi tree.cmi ubase/trace.cmi \ - system.cmi stasher.cmi ubase/safelist.cmi remote.cmi props.cmi \ - ubase/proplist.cmi ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi \ - name.cmi ubase/myMap.cmi lwt/lwt_unix.cmi lwt/lwt.cmi lock.cmi \ - globals.cmi fspath.cmi fs.cmi fingerprint.cmi fileinfo.cmi copy.cmi \ - common.cmi case.cmi update.cmi + system.cmi ubase/safelist.cmi remote.cmi props.cmi ubase/proplist.cmi \ + ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi name.cmi ubase/myMap.cmi \ + lwt/lwt_unix.cmi lwt/lwt.cmi lock.cmi globals.cmi fspath.cmi fs.cmi \ + fingerprint.cmi fileinfo.cmi common.cmi case.cmi update.cmi update.cmx: xferhint.cmx uutil.cmx ubase/util.cmx tree.cmx ubase/trace.cmx \ - system.cmx stasher.cmx ubase/safelist.cmx remote.cmx props.cmx \ - ubase/proplist.cmx ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx \ - name.cmx ubase/myMap.cmx lwt/lwt_unix.cmx lwt/lwt.cmx lock.cmx \ - globals.cmx fspath.cmx fs.cmx fingerprint.cmx fileinfo.cmx copy.cmx \ - common.cmx case.cmx update.cmi + system.cmx ubase/safelist.cmx remote.cmx props.cmx ubase/proplist.cmx \ + ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx name.cmx ubase/myMap.cmx \ + lwt/lwt_unix.cmx lwt/lwt.cmx lock.cmx globals.cmx fspath.cmx fs.cmx \ + fingerprint.cmx fileinfo.cmx common.cmx case.cmx update.cmi uutil.cmo: ubase/util.cmi ubase/trace.cmi ubase/projectInfo.cmo uutil.cmi uutil.cmx: ubase/util.cmx ubase/trace.cmx ubase/projectInfo.cmx uutil.cmi xferhint.cmo: ubase/util.cmi ubase/trace.cmi ubase/prefs.cmi path.cmi os.cmi \ Modified: trunk/src/Makefile.OCaml =================================================================== --- trunk/src/Makefile.OCaml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/Makefile.OCaml 2009-07-17 21:41:58 UTC (rev 377) @@ -207,8 +207,8 @@ abort.cmo osx.cmo external.cmo \ props.cmo fileinfo.cmo os.cmo lock.cmo clroot.cmo common.cmo \ tree.cmo checksum.cmo terminal.cmo \ - transfer.cmo xferhint.cmo remote.cmo globals.cmo copy.cmo \ - stasher.cmo update.cmo \ + transfer.cmo xferhint.cmo remote.cmo globals.cmo \ + update.cmo copy.cmo stasher.cmo \ files.cmo sortri.cmo recon.cmo transport.cmo \ strings.cmo uicommon.cmo uitext.cmo test.cmo Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/RECENTNEWS 2009-07-17 21:41:58 UTC (rev 377) @@ -1,5 +1,11 @@ CHANGES FROM VERSION 2.36.-27 +* Performance improvement in Xferhint module. + Update this cache more accurately during transport. + +------------------------------- +CHANGES FROM VERSION 2.36.-27 + * Correction to previous fix: do not perform the optimization for directories with ignored children *in the archive*. (The previous fix was also rejecting directories with ignored children on disk, Modified: trunk/src/copy.ml =================================================================== --- trunk/src/copy.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/copy.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -42,11 +42,6 @@ (****) -(* From update.ml *) -(* (there is a dependency loop between copy.ml and update.ml...) *) -let excelFile = ref (fun _ -> false) -let markPossiblyUpdated = ref (fun _ _ -> ()) - (* Check whether the source file has been modified during synchronization *) let checkContentsChangeLocal fspathFrom pathFrom archDesc archDig archStamp archRess paranoid = @@ -60,7 +55,7 @@ let dataClearlyUnchanged = not clearlyModified && Props.same_time info.Fileinfo.desc archDesc - && not (!excelFile pathFrom) + && not (Update.excelFile pathFrom) && match archStamp with Some (Fileinfo.InodeStamp inode) -> info.Fileinfo.inode = inode | Some (Fileinfo.CtimeStamp ctime) -> true @@ -75,7 +70,7 @@ if paranoid then begin let newDig = Os.fingerprint fspathFrom pathFrom info in if archDig <> newDig then begin - !markPossiblyUpdated fspathFrom pathFrom; + Update.markPossiblyUpdated fspathFrom pathFrom; raise (Util.Transient (Printf.sprintf "The source file %s\n\ has been modified but the fast update detection mechanism\n\ @@ -248,14 +243,22 @@ match Xferhint.lookup fp with None -> None - | Some (candidateFspath, candidatePath) -> + | Some (candidateFspath, candidatePath, hintHandle) -> debug (fun () -> Util.msg "tryCopyMovedFile: found match at %s,%s. Try local copying\n" (Fspath.toDebugString candidateFspath) (Path.toString candidatePath)); try - if Os.exists candidateFspath candidatePath then begin + (* If candidateFspath is the replica root, the argument + [true] is correct. Otherwise, we don't expect to point + to a symlink, and therefore we still get the correct + result. *) + let info = Fileinfo.get true candidateFspath candidatePath in + if + info.Fileinfo.typ <> `ABSENT && + Props.length info.Fileinfo.desc = Props.length desc + then begin localFile candidateFspath candidatePath fspathTo pathTo realPathTo update desc (Osx.ressLength ress) (Some id); @@ -263,7 +266,6 @@ fileIsTransferred fspathTo pathTo desc fp ress in if isTransferred then begin debug (fun () -> Util.msg "tryCopyMoveFile: success.\n"); - Xferhint.insertEntry (fspathTo, pathTo) fp; let msg = Printf.sprintf "Shortcut: copied %s/%s from local file %s/%s\n" @@ -277,15 +279,14 @@ debug (fun () -> Util.msg "tryCopyMoveFile: candidate file %s modified!\n" (Path.toString candidatePath)); - Xferhint.deleteEntry (candidateFspath, candidatePath); - Os.delete fspathTo pathTo; + Xferhint.deleteEntry hintHandle; None end end else begin debug (fun () -> Util.msg "tryCopyMoveFile: candidate file %s disappeared!\n" (Path.toString candidatePath)); - Xferhint.deleteEntry (candidateFspath, candidatePath); + Xferhint.deleteEntry hintHandle; None end with @@ -294,8 +295,7 @@ Util.msg "tryCopyMovedFile: local copy from %s didn't work [%s]" (Path.toString candidatePath) s); - Xferhint.deleteEntry (candidateFspath, candidatePath); - Os.delete fspathTo pathTo; + Xferhint.deleteEntry hintHandle; None) (****) @@ -627,8 +627,11 @@ (Path.toString pathTo))); transferRessourceForkAndSetFileinfo connFrom fspathFrom pathFrom fspathTo pathTo realPathTo - update desc fp ress id + update desc fp ress id >>= fun res -> + Xferhint.insertEntry fspathTo pathTo fp; + Lwt.return res + let finishExternalTransferOnRoot = Remote.registerRootCmdWithConnection "finishExternalTransfer" finishExternalTransferLocal @@ -689,6 +692,7 @@ let len = Uutil.Filesize.add (Props.length desc) (Osx.ressLength ress) in Uutil.showProgress id len "alr"; setFileinfo fspathTo pathTo realPathTo update desc; + Xferhint.insertEntry fspathTo pathTo fp; Lwt.return (`DONE (Success info, Some msg)) end else match @@ -696,6 +700,7 @@ with Some (info, msg) -> (* Transfer was performed by copying *) + Xferhint.insertEntry fspathTo pathTo fp; Lwt.return (`DONE (Success info, Some msg)) | None -> if shouldUseExternalCopyprog update desc then @@ -704,6 +709,7 @@ reallyTransferFile connFrom fspathFrom pathFrom fspathTo pathTo realPathTo update desc fp ress id >>= fun status -> + Xferhint.insertEntry fspathTo pathTo fp; Lwt.return (`DONE (status, None)) end Modified: trunk/src/copy.mli =================================================================== --- trunk/src/copy.mli 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/copy.mli 2009-07-17 21:41:58 UTC (rev 377) @@ -27,8 +27,3 @@ -> Uutil.Filesize.t (* fork length *) -> Uutil.File.t option (* file's index in UI (for progress bars), as appropriate *) -> unit - -(* From update.ml *) -(* (there is a dependency loop between copy.ml and update.ml...) *) -val excelFile : (Path.local -> bool) ref -val markPossiblyUpdated : (Fspath.t -> Path.local -> unit) ref Modified: trunk/src/files.ml =================================================================== --- trunk/src/files.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/files.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -79,8 +79,8 @@ let localPathTo = Update.translatePathLocal fspathTo pathTo in (* Make sure the target is unchanged first *) (* (There is an unavoidable race condition here.) *) - Update.checkNoUpdates fspathTo localPathTo ui; - Stasher.backup fspathTo localPathTo `AndRemove; + let prevArch = Update.checkNoUpdates fspathTo localPathTo ui in + Stasher.backup fspathTo localPathTo `AndRemove prevArch; (* Archive update must be done last *) Update.replaceArchiveLocal fspathTo localPathTo Update.NoArchive; Lwt.return () @@ -177,7 +177,7 @@ (* ------------------------------------------------------------ *) -let performRename fspathTo localPathTo workingDir pathFrom pathTo = +let performRename fspathTo localPathTo workingDir pathFrom pathTo prevArch = debug (fun () -> Util.msg "Renaming %s to %s in %s; root is %s\n" (Path.toString pathFrom) (Path.toString pathTo) @@ -221,7 +221,7 @@ debug (fun() -> Util.msg "moving %s to %s\n" (Fspath.toDebugString target) temp'); - Stasher.backup fspathTo localPathTo `ByCopying; + Stasher.backup fspathTo localPathTo `ByCopying prevArch; writeCommitLog source target temp'; Util.finalize (fun() -> (* If the first rename fails, the log can be removed: the @@ -245,7 +245,7 @@ Os.delete temp Path.empty end else begin debug (fun() -> Util.msg "rename: moveFirst=false\n"); - Stasher.backup fspathTo localPathTo `ByCopying; + Stasher.backup fspathTo localPathTo `ByCopying prevArch; Os.rename "renameLocal(3)" source Path.empty target Path.empty; debug (fun() -> if filetypeFrom = `FILE then @@ -271,11 +271,13 @@ (fspathTo, (localPathTo, workingDir, pathFrom, pathTo, ui, archOpt)) = (* Make sure the target is unchanged, then do the rename. (Note that there is an unavoidable race condition here...) *) - Update.checkNoUpdates fspathTo localPathTo ui; - performRename fspathTo localPathTo workingDir pathFrom pathTo; - (* Archive update must be done last *) + let prevArch = Update.checkNoUpdates fspathTo localPathTo ui in + performRename fspathTo localPathTo workingDir pathFrom pathTo prevArch; begin match archOpt with Some archTo -> Stasher.stashCurrentVersion fspathTo localPathTo None; + Update.iterFiles fspathTo localPathTo archTo + Xferhint.insertEntry; + (* Archive update must be done last *) Update.replaceArchiveLocal fspathTo localPathTo archTo | None -> () end; @@ -283,7 +285,7 @@ let renameOnHost = Remote.registerRootCmd "rename" renameLocal -let rename root pathInArchive localPath workingDir pathOld pathNew ui archOpt = +let rename root localPath workingDir pathOld pathNew ui archOpt = debug (fun() -> Util.msg "rename(root=%s, pathOld=%s, pathNew=%s)\n" (root2string root) @@ -518,7 +520,7 @@ else begin (* Rename the files to their final location and then update the archive on the destination replica *) - rename rootTo pathTo localPathTo workingDir tempPathTo realPathTo uiTo + rename rootTo localPathTo workingDir tempPathTo realPathTo uiTo (Some archTo) >>= fun () -> (* Update the archive on the source replica FIX: we could reuse localArch if rootFrom is the same as rootLocal *) @@ -701,7 +703,7 @@ Copy.file (Local, fspathFrom) pathFrom rootTo workingDirForCopy tempPathTo realPathTo `Copy newprops fp None stamp id >>= fun info -> - rename rootTo pathTo localPathTo workingDirForCopy tempPathTo realPathTo + rename rootTo localPathTo workingDirForCopy tempPathTo realPathTo uiTo None) let keeptempfilesaftermerge = Modified: trunk/src/fingerprint.ml =================================================================== --- trunk/src/fingerprint.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/fingerprint.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -79,3 +79,14 @@ let string = Digest.string let dummy = "" + +let hash d = + if d == dummy then + 1234577 + else begin + Char.code (String.unsafe_get d 0) + + (Char.code (String.unsafe_get d 1) lsl 8) + + (Char.code (String.unsafe_get d 2) lsl 16) + end + +let equal (d : string) d' = d = d' Modified: trunk/src/fingerprint.mli =================================================================== --- trunk/src/fingerprint.mli 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/fingerprint.mli 2009-07-17 21:41:58 UTC (rev 377) @@ -14,3 +14,6 @@ (* This dummy fingerprint is guaranteed small and distinct from all other fingerprints *) val dummy : t + +val hash : t -> int +val equal : t -> t -> bool Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/mkProjectInfo.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -95,3 +95,4 @@ + Modified: trunk/src/os.ml =================================================================== --- trunk/src/os.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/os.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -36,13 +36,6 @@ if s = "" then tempFileSuffixFixed else "." ^ s ^ tempFileSuffixFixed -let xferDelete = ref (fun (fp,p) -> ()) -let xferRename = ref (fun (fp,p) (ftp,tp) -> ()) - -let initializeXferFunctions del ren = - xferDelete := del; - xferRename := ren - (*****************************************************************************) (* QUERYING THE FILESYSTEM *) (*****************************************************************************) @@ -158,7 +151,6 @@ Safelist.iter (fun child -> delete fspath (Path.child path child)) (allChildrenOf fspath path); - (!xferDelete) (fspath, path); Fs.rmdir absolutePath | `FILE -> if Util.osType <> `Unix then begin @@ -166,7 +158,6 @@ Fs.chmod absolutePath 0o600; with Unix.Unix_error _ -> () end; - (!xferDelete) (fspath, path); Fs.unlink absolutePath; if Prefs.read Osx.rsrc then begin let pathDouble = Fspath.appleDouble absolutePath in @@ -189,7 +180,6 @@ Util.convertUnixErrorsToTransient ("renaming " ^ source' ^ " to " ^ target') (fun () -> debug (fun() -> Util.msg "rename %s to %s\n" source' target'); - (!xferRename) (sourcefspath, sourcepath) (targetfspath, targetpath); Fs.rename source target; if Prefs.read Osx.rsrc then begin let sourceDouble = Fspath.appleDouble source in @@ -278,6 +268,12 @@ let fullfingerprint_dummy = (Fingerprint.dummy,Fingerprint.dummy) +let fullfingerprintHash (fp, rfp) = + Fingerprint.hash fp + 31 * Fingerprint.hash rfp + +let fullfingerprintEqual (fp, rfp) (fp', rfp') = + Fingerprint.equal fp fp' && Fingerprint.equal rfp rfp' + (*****************************************************************************) (* UNISON DIRECTORY *) (*****************************************************************************) Modified: trunk/src/os.mli =================================================================== --- trunk/src/os.mli 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/os.mli 2009-07-17 21:41:58 UTC (rev 377) @@ -31,6 +31,8 @@ val fullfingerprint_to_string : fullfingerprint -> string val reasonForFingerprintMismatch : fullfingerprint -> fullfingerprint -> string val fullfingerprint_dummy : fullfingerprint +val fullfingerprintHash : fullfingerprint -> int +val fullfingerprintEqual : fullfingerprint -> fullfingerprint -> bool (* Use this function if the file may change during fingerprinting *) val safeFingerprint : @@ -47,10 +49,3 @@ (* Versions of system calls that will restart when interrupted by signal handling *) val accept : Unix.file_descr -> (Unix.file_descr * Unix.sockaddr) - -(* Called during program initialization to resolve a circular dependency - between this module and Xferhints *) -val initializeXferFunctions : - (Fspath.t * Path.local -> unit) -> - ((Fspath.t * Path.local) -> (Fspath.t * Path.local) -> unit) -> - unit Modified: trunk/src/stasher.ml =================================================================== --- trunk/src/stasher.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/stasher.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -360,7 +360,7 @@ (*------------------------------------------------------------------------------------*) -let backup fspath path (finalDisposition : [`AndRemove | `ByCopying]) = +let backup fspath path (finalDisposition : [`AndRemove | `ByCopying]) arch = debug (fun () -> Util.msg "backup: %s / %s\n" (Fspath.toDebugString fspath) @@ -409,14 +409,17 @@ debug (fun () -> Util.msg " Finished copying; deleting %s / %s\n" (Fspath.toDebugString fspath) (Path.toString path)); disposeIfNeeded() in - if finalDisposition = `AndRemove then + begin if finalDisposition = `AndRemove then try + (*FIX: this does the wrong thing with followed symbolic links!*) Os.rename "backup" workingDir realPath backRoot backPath with Util.Transient _ -> debug (fun () -> Util.msg "Rename failed -- copying instead\n"); byCopying() else byCopying() + end; + Update.iterFiles backRoot backPath arch Xferhint.insertEntry end else begin debug (fun () -> Util.msg "Path %s / %s does not need to be backed up\n" (Fspath.toDebugString fspath) @@ -462,7 +465,10 @@ (Osx.ressLength stat.Fileinfo.osX.Osx.ressInfo) None end) - + +let _ = +Update.setStasherFun (fun fspath path -> stashCurrentVersion fspath path None) + (*------------------------------------------------------------------------------------*) (* This function tries to find a backup of a recent version of the file at location Modified: trunk/src/stasher.mli =================================================================== --- trunk/src/stasher.mli 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/stasher.mli 2009-07-17 21:41:58 UTC (rev 377) @@ -5,9 +5,12 @@ (* This module maintains backups for general purpose and *) (* as archives for mergeable files. *) -(* Make a backup copy of a file, if needed; if the third parameter is `AndRemove, - then the file is either backed up by renaming or deleted if no backup is needed. *) -val backup: Fspath.t -> Path.local -> [`AndRemove | `ByCopying] -> unit +(* Make a backup copy of a file, if needed; if the third parameter is + `AndRemove, then the file is either backed up by renaming or + deleted if no backup is needed. *) +val backup: + Fspath.t -> Path.local -> + [`AndRemove | `ByCopying] -> Update.archive -> unit (* Stashes of current versions (so that we have archives when needed for merging) *) val stashCurrentVersion: Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/update.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -1223,7 +1223,7 @@ Osx.ressUnchanged archRess info.Fileinfo.osX.Osx.ressInfo None dataClearlyUnchanged in if dataClearlyUnchanged && ressClearlyUnchanged then begin - Xferhint.insertEntry (currfspath, path) archDig; + Xferhint.insertEntry currfspath path archDig; None, checkPropChange info archive archDesc end else begin debugverbose (fun() -> Util.msg " Double-check possibly updated file\n"); @@ -1231,7 +1231,7 @@ let (info, newDigest) = Os.safeFingerprint currfspath path info (if dataClearlyUnchanged then Some archDig else None) in - Xferhint.insertEntry (currfspath, path) newDigest; + Xferhint.insertEntry currfspath path newDigest; debug (fun() -> Util.msg " archive digest = %s current digest = %s\n" (Os.fullfingerprint_to_string archDig) (Os.fullfingerprint_to_string newDigest)); @@ -1239,7 +1239,6 @@ let newprops = Props.setTime archDesc (Props.time info.Fileinfo.desc) in let newarch = ArchiveFile - (newprops, archDig, Fileinfo.stamp info, Fileinfo.ressStamp info) in debugverbose (fun() -> Util.msg " Contents match: update archive with new time...%f\n" @@ -1330,8 +1329,8 @@ NameMap.iter (fun nm archive -> match archive with - ArchiveFile (archDesc, archDig, archStamp, archRess) -> - Xferhint.insertEntry (fspath, Path.child path nm) archDig + ArchiveFile (_, archDig, _, _) -> + Xferhint.insertEntry fspath (Path.child path nm) archDig | _ -> ()) archChi; @@ -1374,8 +1373,8 @@ `Ok | `Abs -> if skip && archive <> NoArchive && status <> `Abs then begin begin match archive with - ArchiveFile (archDesc, archDig, archStamp, archRess) -> - Xferhint.insertEntry (fspath, path') archDig + ArchiveFile (_, archDig, _, _) -> + Xferhint.insertEntry fspath path' archDig | _ -> () end; @@ -1469,7 +1468,7 @@ begin showStatusAddLength info; let (info, dig) = Os.safeFingerprint currfspath path info None in - Xferhint.insertEntry (currfspath, path) dig; + Xferhint.insertEntry currfspath path dig; Updates (File (info.Fileinfo.desc, ContentsUpdated (dig, Fileinfo.stamp info, Fileinfo.ressStamp info)), @@ -1909,6 +1908,10 @@ let (_, subArch) = getPathInArchive archive Path.empty path in updateArchiveRec ui (stripArchive path subArch) +(* (For breaking the dependency loop between update.ml and stasher.ml...) *) +let stashCurrentVersion = ref (fun _ _ -> ()) +let setStasherFun f = stashCurrentVersion := f + (* This function is called for files changed only in identical ways. It only updates the archives and perhaps makes backups. *) let markEqualLocal fspath paths = @@ -1922,7 +1925,7 @@ let arch = updatePathInArchive !archive fspath Path.empty path (fun archive localPath -> - Stasher.stashCurrentVersion fspath localPath None; + !stashCurrentVersion fspath localPath; updateArchiveRec (Updates (uc, New)) archive) in archive := arch); @@ -2136,7 +2139,8 @@ in let (_, uiNew) = buildUpdateRec archive fspath localPath fastCheckInfos in markPossiblyUpdatedRec fspath pathInArchive uiNew; - explainUpdate pathInArchive uiNew + explainUpdate pathInArchive uiNew; + archive (*****************************************************************************) (* UPDATE SIZE *) @@ -2213,9 +2217,16 @@ let (_, subArch) = getPathInArchive archive Path.empty path in updateSizeRec subArch ui -(*****) +(*****************************************************************************) +(* MISC *) +(*****************************************************************************) -(* There is a dependency loop between copy.ml and update.ml... *) -let _ = -Copy.excelFile := excelFile; -Copy.markPossiblyUpdated := markPossiblyUpdated +let rec iterFiles fspath path arch f = + match arch with + ArchiveDir (_, children) -> + NameMap.iter + (fun nm arch -> iterFiles fspath (Path.child path nm) arch f) children + | ArchiveFile (desc, fp, stamp, ress) -> + f fspath path fp + | _ -> + () Modified: trunk/src/update.mli =================================================================== --- trunk/src/update.mli 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/update.mli 2009-07-17 21:41:58 UTC (rev 377) @@ -36,7 +36,9 @@ Fspath.t -> 'a Path.path -> Props.t option -> Common.updateItem -> unit (* Check that no updates has taken place in a given place of the filesystem *) -val checkNoUpdates : Fspath.t -> Path.local -> Common.updateItem -> unit +(* Returns an archive mirroring the filesystem contents *) +val checkNoUpdates : + Fspath.t -> Path.local -> Common.updateItem -> archive (* Turn off fastcheck for the given file on the next sync. *) val markPossiblyUpdated : Fspath.t -> Path.local -> unit @@ -61,8 +63,19 @@ (* Are we checking fast, or carefully? *) val useFastChecking : unit -> bool +(* Is that a file for which fast checking is disabled? *) +val excelFile : Path.local -> bool + (* Print the archive to the current formatter (see Format) *) val showArchive: archive -> unit (* Compute the size of an update *) val updateSize : Path.t -> Common.updateItem -> int * Uutil.Filesize.t + +(* Iterate on all files in an archive *) +val iterFiles : + Fspath.t -> Path.local -> archive -> + (Fspath.t -> Path.local -> Os.fullfingerprint -> unit) -> unit + +(* (For breaking the dependency loop between update.ml and stasher.ml...) *) +val setStasherFun : (Fspath.t -> Path.local -> unit) -> unit Modified: trunk/src/xferhint.ml =================================================================== --- trunk/src/xferhint.ml 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/xferhint.ml 2009-07-17 21:41:58 UTC (rev 377) @@ -27,89 +27,39 @@ ^ "allows file moves to be propagated very quickly. The default value is" ^ "\\texttt{true}. ") -module PathMap = - Hashtbl.Make - (struct - type t = Fspath.t * Path.local - let hash (fspath, path) = - (Fspath.hash fspath + 13217 * Path.hash path) - land - 0x3FFFFFFF - let equal = (=) - end) module FPMap = Hashtbl.Make (struct type t = Os.fullfingerprint - let hash = Hashtbl.hash - let equal = (=) + let hash = Os.fullfingerprintHash + let equal = Os.fullfingerprintEqual end) -(* map(path, fingerprint) *) -let path2fingerprintMap = PathMap.create 101 +type handle = Os.fullfingerprint + (* map(fingerprint, path) *) -let fingerprint2pathMap = FPMap.create 101 +let fingerprint2pathMap = FPMap.create 10000 -(* Now we don't clear it out anymore -let initLocal () = - debug (fun () -> Util.msg "initLocal\n"); - path2fingerprintMap := PathMap.empty; - fingerprint2pathMap := FPMap.empty -*) +let deleteEntry fp = + debug (fun () -> + Util.msg "deleteEntry: fp=%s\n" (Os.fullfingerprint_to_string fp)); + FPMap.remove fingerprint2pathMap fp let lookup fp = assert (Prefs.read xferbycopying); debug (fun () -> Util.msg "lookup: fp = %s\n" (Os.fullfingerprint_to_string fp)); try - Some (FPMap.find fingerprint2pathMap fp) + let (fspath, path) = FPMap.find fingerprint2pathMap fp in + Some (fspath, path, fp) with Not_found -> None -let insertEntry p fp = +let insertEntry fspath path fp = if Prefs.read xferbycopying then begin debug (fun () -> - let (fspath, path) = p in Util.msg "insertEntry: fspath=%s, path=%s, fp=%s\n" (Fspath.toDebugString fspath) (Path.toString path) (Os.fullfingerprint_to_string fp)); - (* Neither of these should be able to raise Not_found *) - PathMap.replace path2fingerprintMap p fp; - FPMap.replace fingerprint2pathMap fp p + FPMap.replace fingerprint2pathMap fp (fspath, path) end - -let deleteEntry p = - if Prefs.read xferbycopying then begin - debug (fun () -> - let (fspath, path) = p in - Util.msg "deleteEntry: fspath=%s, path=%s\n" - (Fspath.toDebugString fspath) (Path.toString path)); - try - let fp = PathMap.find path2fingerprintMap p in - PathMap.remove path2fingerprintMap p; - let p' = FPMap.find fingerprint2pathMap fp in - (* Maybe we should do this unconditionally *) - if p' = p then FPMap.remove fingerprint2pathMap fp - with Not_found -> - () - end - -let renameEntry pOrig pNew = - if Prefs.read xferbycopying then begin - debug (fun () -> - let (fspathOrig, pathOrig) = pOrig in - let (fspathNew, pathNew) = pNew in - Util.msg "renameEntry: fsOrig=%s, pOrig=%s, fsNew=%s, pNew=%s\n" - (Fspath.toDebugString fspathOrig) (Path.toString pathOrig) - (Fspath.toDebugString fspathNew) (Path.toString pathNew)); - try - let fp = PathMap.find path2fingerprintMap pOrig in - PathMap.remove path2fingerprintMap pOrig; - PathMap.replace path2fingerprintMap pNew fp; - FPMap.replace fingerprint2pathMap fp pNew - with Not_found -> - () - end - -let _ = - Os.initializeXferFunctions deleteEntry renameEntry Modified: trunk/src/xferhint.mli =================================================================== --- trunk/src/xferhint.mli 2009-07-17 08:15:02 UTC (rev 376) +++ trunk/src/xferhint.mli 2009-07-17 21:41:58 UTC (rev 377) @@ -9,10 +9,13 @@ val xferbycopying: bool Prefs.t +type handle + (* Suggest a file that's likely to have a given fingerprint *) -val lookup: Os.fullfingerprint -> (Fspath.t * Path.local) option +val lookup: Os.fullfingerprint -> (Fspath.t * Path.local * handle) option -(* Add, delete, and rename entries *) -val insertEntry: Fspath.t * Path.local -> Os.fullfingerprint -> unit -val deleteEntry: Fspath.t * Path.local -> unit -val renameEntry: Fspath.t * Path.local -> Fspath.t * Path.local -> unit +(* Add a file *) +val insertEntry: Fspath.t -> Path.local -> Os.fullfingerprint -> unit + +(* Delete an entry *) +val deleteEntry: handle -> unit From vouillon at seas.upenn.edu Sun Jul 19 16:07:54 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Sun, 19 Jul 2009 16:07:54 -0400 Subject: [Unison-hackers] [unison-svn] r378 - in trunk/src: . ubase Message-ID: <200907192007.n6JK7sSE015879@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-19 16:07:54 -0400 (Sun, 19 Jul 2009) New Revision: 378 Modified: trunk/src/RECENTNEWS trunk/src/common.ml trunk/src/common.mli trunk/src/copy.ml trunk/src/fileinfo.ml trunk/src/fileinfo.mli trunk/src/files.ml trunk/src/files.mli trunk/src/globals.ml trunk/src/mkProjectInfo.ml trunk/src/path.ml trunk/src/path.mli trunk/src/props.ml trunk/src/recon.ml trunk/src/recon.mli trunk/src/remote.ml trunk/src/remote.mli trunk/src/transfer.ml trunk/src/transfer.mli trunk/src/transport.ml trunk/src/ubase/prefs.ml trunk/src/ubase/prefs.mli trunk/src/uicommon.ml trunk/src/uigtk2.ml trunk/src/uimacbridge.ml trunk/src/uitext.ml trunk/src/update.ml trunk/src/update.mli Log: * Bumped version number: incompatible protocol changes * Create parent directories (with correct permissions) during transport for paths which point to non-existent locations in the destination replica. * Keep track of which file contents are being transferred, and delay the transfer of a file when another file with the same contents is currently being transferred. This way, the second transfer can be skipped and replaced by a local copy. * Changes to the implementation of the rsync algorithm: - use longer blocks for large files (the size of a block is the square root of the size of the file for large files); - transmit less checksum information per block (we still have less than one chance in a hundred million of transferring a file incorrectly, and Unison will catch any transfer error when fingerprinting the whole file) - avoid transfer overhead (which was 4 bytes per block) For a 1G file, the first optimization saves a factor 50 on the amount of data transferred from the target to the source (blocks are 32768 bytes rather than just 700 bytes). The two other optimizations save another factor of 2 (from 24 bytes per block down to 10). * New "links" preference. When set to false, Unison will report an error on symlinks during update detection. (This is the default when one host is running Windows but not Cygwin.) This is better than failing during propagation. * Added a preference "halfduplex" to force half-duplex communication with the server. This may be useful on unreliable links (as a more efficient alternative to "maxthreads = 1"). * Renamed preference "pretendwin" to "ignoreinodenumbers" (an alias is kept for backwards compatibility). * GTK UI: display estimated remaining time and transfer rate on the progress bar * GTK UI: some polishing; in particular: - stop statistics window updates when idle (save power on laptops) - some ok and cancel buttons were in the wrong order * Added some support for making it easier to extend Unison without breaking backwards compatibility. - Possibility to mark a preference as local. Such a preference is propagated if possible but will not result in an error if it is not found server-side. This make it possible to add new functionalities client-side without breaking compatibility. - Added a function [Remove.commandAvailable] which tests whether a command is available on a given root. * Removed hack in findUpdates that would update the archive in a visible way for the sake of path translation: it is no longer needed. Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/RECENTNEWS 2009-07-19 20:07:54 UTC (rev 378) @@ -1,3 +1,56 @@ +CHANGES FROM VERSION 2.37.1 + +* Bumped version number: incompatible protocol changes + +* Create parent directories (with correct permissions) during + transport for paths which point to non-existent locations in the + destination replica. +* Keep track of which file contents are being transferred, and delay + the transfer of a file when another file with the same contents is + currently being transferred. This way, the second transfer can be + skipped and replaced by a local copy. +* Changes to the implementation of the rsync algorithm: + - use longer blocks for large files (the size of a block is the + square root of the size of the file for large files); + - transmit less checksum information per block (we still have less + than one chance in a hundred million of transferring a file + incorrectly, and Unison will catch any transfer error when + fingerprinting the whole file) + - avoid transfer overhead (which was 4 bytes per block) + For a 1G file, the first optimization saves a factor 50 on the + amount of data transferred from the target to the source (blocks + are 32768 bytes rather than just 700 bytes). The two other + optimizations save another factor of 2 (from 24 bytes per block + down to 10). + +* New "links" preference. When set to false, Unison will report an + error on symlinks during update detection. (This is the default + when one host is running Windows but not Cygwin.) This is better + than failing during propagation. +* Added a preference "halfduplex" to force half-duplex communication + with the server. This may be useful on unreliable links (as a more + efficient alternative to "maxthreads = 1"). +* Renamed preference "pretendwin" to "ignoreinodenumbers" (an alias is + kept for backwards compatibility). +* GTK UI: display estimated remaining time and transfer rate on the + progress bar +* GTK UI: some polishing; in particular: + - stop statistics window updates when idle (save power on laptops) + - some ok and cancel buttons were in the wrong order + +* Added some support for making it easier to extend Unison without + breaking backwards compatibility. + - Possibility to mark a preference as local. Such a preference is + propagated if possible but will not result in an error if it is + not found server-side. This make it possible to add new + functionalities client-side without breaking compatibility. + - Added a function [Remove.commandAvailable] which tests whether a + command is available on a given root. +* Removed hack in findUpdates that would update the archive in a + visible way for the sake of path translation: it is no longer + needed. + +------------------------------- CHANGES FROM VERSION 2.36.-27 * Performance improvement in Xferhint module. Modified: trunk/src/common.ml =================================================================== --- trunk/src/common.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/common.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -112,9 +112,10 @@ type replicaContent = { typ : Fileinfo.typ; status : status; - desc : Props.t; + desc : Props.t; (* Properties (for the UI) *) ui : updateItem; - size : int * Uutil.Filesize.t } + size : int * Uutil.Filesize.t; (* Number of items and size *) + props : Props.t list } (* Parent properties *) type direction = Conflict Modified: trunk/src/common.mli =================================================================== --- trunk/src/common.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/common.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -90,9 +90,10 @@ type replicaContent = { typ : Fileinfo.typ; status : status; - desc : Props.t; + desc : Props.t; (* Properties (for the UI) *) ui : updateItem; - size : int * Uutil.Filesize.t } + size : int * Uutil.Filesize.t; (* Number of items and size *) + props : Props.t list } (* Parent properties *) type direction = Conflict Modified: trunk/src/copy.ml =================================================================== --- trunk/src/copy.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/copy.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -409,9 +409,9 @@ fd let rsyncReg = Lwt_util.make_region (40 * 1024) -let rsyncThrottle useRsync sz f = +let rsyncThrottle useRsync srcFileSize destFileSize f = if not useRsync then f () else - let l = Transfer.Rsync.memoryFootprint sz in + let l = Transfer.Rsync.memoryFootprint srcFileSize destFileSize in Lwt_util.run_in_region rsyncReg l f let transferFileContents @@ -440,15 +440,17 @@ && Transfer.Rsync.aboveRsyncThreshold srcFileSize in - rsyncThrottle useRsync destFileSize (fun () -> + rsyncThrottle useRsync srcFileSize destFileSize (fun () -> let (bi, decompr) = if useRsync then Util.convertUnixErrorsToTransient "preprocessing file" (fun () -> let ifd = openFileIn fspathTo realPathTo fileKind in - let bi = - protect (fun () -> Transfer.Rsync.rsyncPreprocess ifd) + let (bi, blockSize) = + protect + (fun () -> Transfer.Rsync.rsyncPreprocess + ifd srcFileSize destFileSize) (fun () -> close_in_noerr ifd) in infd := Some ifd; @@ -459,7 +461,7 @@ destinationFd fspathTo pathTo fileKind srcFileSize outfd id in let eof = - Transfer.Rsync.rsyncDecompress ifd fd showProgress ti + Transfer.Rsync.rsyncDecompress blockSize ifd fd showProgress ti in if eof then begin close_out fd; outfd := None end)) else @@ -523,6 +525,48 @@ (****) +let filesBeingTransferred = Hashtbl.create 17 + +let wakeupNextTransfer fp = + match + try + Some (Queue.take (Hashtbl.find filesBeingTransferred fp)) + with Queue.Empty -> + None + with + None -> + Hashtbl.remove filesBeingTransferred fp + | Some next -> + Lwt.wakeup next () + +let executeTransfer fp f = + Lwt.try_bind f + (fun res -> wakeupNextTransfer fp; Lwt.return res) + (fun e -> wakeupNextTransfer fp; Lwt.fail e) + +(* Keep track of which file contents are being transferred, and delay + the transfer of a file with the same contents as another file being + currently transferred. This way, the second transfer can be + skipped and replaced by a local copy. *) +let rec registerFileTransfer pathTo fp f = + if not (Prefs.read Xferhint.xferbycopying) then f () else + match + try Some (Hashtbl.find filesBeingTransferred fp) with Not_found -> None + with + None -> + let q = Queue.create () in + Hashtbl.add filesBeingTransferred fp q; + executeTransfer fp f + | Some q -> + debug (fun () -> Util.msg "delaying tranfer of file %s\n" + (Path.toString pathTo)); + let res = Lwt.wait () in + Queue.push res q; + res >>= fun () -> + executeTransfer fp f + +(****) + let copyprog = Prefs.createString "copyprog" "rsync --inplace --compress" "!external program for copying large files" @@ -631,7 +675,6 @@ Xferhint.insertEntry fspathTo pathTo fp; Lwt.return res - let finishExternalTransferOnRoot = Remote.registerRootCmdWithConnection "finishExternalTransfer" finishExternalTransferLocal @@ -676,6 +719,8 @@ (snd rootFrom, pathFrom, fspathTo, pathTo, realPathTo, update, desc, fp, ress, id) +(****) + let transferFileLocal connFrom (fspathFrom, pathFrom, fspathTo, pathTo, realPathTo, update, desc, fp, ress, id) = @@ -695,23 +740,25 @@ Xferhint.insertEntry fspathTo pathTo fp; Lwt.return (`DONE (Success info, Some msg)) end else - match - tryCopyMovedFile fspathTo pathTo realPathTo update desc fp ress id - with - Some (info, msg) -> - (* Transfer was performed by copying *) - Xferhint.insertEntry fspathTo pathTo fp; - Lwt.return (`DONE (Success info, Some msg)) - | None -> - if shouldUseExternalCopyprog update desc then - Lwt.return (`EXTERNAL (prepareExternalTransfer fspathTo pathTo)) - else begin - reallyTransferFile - connFrom fspathFrom pathFrom fspathTo pathTo realPathTo - update desc fp ress id >>= fun status -> - Xferhint.insertEntry fspathTo pathTo fp; - Lwt.return (`DONE (status, None)) - end + registerFileTransfer pathTo fp + (fun () -> + match + tryCopyMovedFile fspathTo pathTo realPathTo update desc fp ress id + with + Some (info, msg) -> + (* Transfer was performed by copying *) + Xferhint.insertEntry fspathTo pathTo fp; + Lwt.return (`DONE (Success info, Some msg)) + | None -> + if shouldUseExternalCopyprog update desc then + Lwt.return (`EXTERNAL (prepareExternalTransfer fspathTo pathTo)) + else begin + reallyTransferFile + connFrom fspathFrom pathFrom fspathTo pathTo realPathTo + update desc fp ress id >>= fun status -> + Xferhint.insertEntry fspathTo pathTo fp; + Lwt.return (`DONE (status, None)) + end) let transferFileOnRoot = Remote.registerRootCmdWithConnection "transferFile" transferFileLocal Modified: trunk/src/fileinfo.ml =================================================================== --- trunk/src/fileinfo.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/fileinfo.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -18,6 +18,28 @@ let debugV = Util.debug "fileinfo+" +let allowSymlinks = + Prefs.createString "links" "default" + "allow the synchronization of symbolic links (true/false/default)" + ("When set to {\\tt true}, this flag causes Unison to synchronize \ + symbolic links. When the flag is set to {\\tt false}, symbolic \ + links will result in an error during update detection. \ + Ordinarily, when the flag is set to {\\tt default}, symbolic \ + links are synchronized except when one of the hosts is running \ + Windows. In rare circumstances it is useful to set the flag \ + manually (e.g. when running Unison on a Unix system with a FAT \ + [Windows] volume mounted).") + +let symlinksAllowed = + Prefs.createBool "links-aux" true + "*Pseudo-preference for internal use only" "" + +let init b = + Prefs.set symlinksAllowed + (Prefs.read allowSymlinks = "yes" || + Prefs.read allowSymlinks = "true" || + (Prefs.read allowSymlinks = "default" && not b)) + type typ = [ `ABSENT | `FILE | `DIRECTORY | `SYMLINK ] let type2string = function @@ -58,7 +80,14 @@ match stats.Unix.LargeFile.st_kind with Unix.S_REG -> `FILE | Unix.S_DIR -> `DIRECTORY - | Unix.S_LNK -> `SYMLINK + | Unix.S_LNK -> + if not fromRoot || Prefs.read symlinksAllowed then + `SYMLINK + else + raise + (Util.Transient + (Format.sprintf "path %s is a symbolic link" + (Fspath.toPrintString (Fspath.concat fspath path)))) | _ -> raise (Util.Transient ("path " ^ @@ -121,15 +150,16 @@ probably not use any stamp under Windows. *) let pretendLocalOSIsWin32 = - Prefs.createBool "pretendwin" false + Prefs.createBool "ignoreinodenumbers" false "!Use creation times for detecting updates" - ("When set to true, this preference makes Unison use Windows-style " - ^ "fast update detection (using file creation times as " - ^ "``pseudo-inode-numbers''), even when running on a Unix system. This " - ^ "switch should be used with care, as it is less safe than the standard " - ^ "update detection method, but it can be useful for synchronizing VFAT " - ^ "filesystems (which do not support inode numbers) mounted on Unix " - ^ "systems. The {\\tt fastcheck} option should also be set to true.") + ("When set to true, this preference makes Unison not take advantage \ + of inode numbers during fast update detection even when running \ + on a Unix system. This switch should be used with care, as it \ + is less safe than the standard update detection method, but it \ + can be useful for synchronizing VFAT filesystems (which do not \ + support inode numbers) mounted on Unix systems. \ + The {\\tt fastcheck} option should also be set to true.") +let _ = Prefs.alias pretendLocalOSIsWin32 "pretendwin" let stamp info = (* Was "CtimeStamp info.ctime", but this is bogus: Windows Modified: trunk/src/fileinfo.mli =================================================================== --- trunk/src/fileinfo.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/fileinfo.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -23,3 +23,7 @@ (* Check whether a file is unchanged *) val unchanged : Fspath.t -> Path.local -> t -> (t * bool * bool) + +(****) + +val init : bool -> unit Modified: trunk/src/files.ml =================================================================== --- trunk/src/files.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/files.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -319,6 +319,36 @@ let setupTargetPaths = Remote.registerRootCmd "setupTargetPaths" setupTargetPathsLocal +let rec createDirectories fspath localPath props = + match props with + [] -> + () + | desc :: rem -> + match Path.deconstructRev localPath with + None -> + assert false + | Some (_, parentPath) -> + createDirectories fspath parentPath rem; + try + let absolutePath = Fspath.concat fspath parentPath in + Fs.mkdir absolutePath (Props.perms desc) + (* The directory may have already been created + if there are several paths with the same prefix *) + with Unix.Unix_error (Unix.EEXIST, _, _) -> () + +let setupTargetPathsAndCreateParentDirectoryLocal (fspath, (path, props)) = + let localPath = Update.translatePathLocal fspath path in + Util.convertUnixErrorsToTransient + "creating parent directories" + (fun () -> createDirectories fspath localPath props); + let (workingDir,realPath) = Fspath.findWorkingDir fspath localPath in + let tempPath = Os.tempPath ~fresh:false workingDir realPath in + Lwt.return (workingDir, realPath, tempPath, localPath) + +let setupTargetPathsAndCreateParentDirectory = + Remote.registerRootCmd "setupTargetPathsAndCreateParentDirectory" + setupTargetPathsAndCreateParentDirectoryLocal + (* ------------------------------------------------------------ *) let updateSourceArchiveLocal (fspathFrom, (localPathFrom, uiFrom, errPaths)) = @@ -376,6 +406,15 @@ let deleteSpuriousChildren = Remote.registerRootCmd "deleteSpuriousChildren" deleteSpuriousChildrenLocal +let rec normalizePropsRec propsFrom propsTo = + match propsFrom, propsTo with + d :: r, d' :: r' -> normalizePropsRec r r' + | _, [] -> propsFrom + | [], _ :: _ -> assert false + +let normalizeProps propsFrom propsTo = + normalizePropsRec (Safelist.rev propsFrom) (Safelist.rev propsTo) + (* ------------------------------------------------------------ *) let copyReg = Lwt_util.make_region 50 @@ -385,10 +424,13 @@ rootFrom pathFrom (* copy from here... *) uiFrom (* (and then check that this updateItem still describes the current state of the src replica) *) + propsFrom (* the properties of the parent directories, in + case we need to propagate them *) rootTo pathTo (* ...to here *) uiTo (* (but, before committing the copy, check that this updateItem still describes the current state of the target replica) *) + propsTo (* the properties of the parent directories *) id = (* for progress display *) debug (fun() -> Util.msg @@ -396,7 +438,8 @@ (root2string rootFrom) (Path.toString pathFrom) (root2string rootTo) (Path.toString pathTo)); (* Calculate target paths *) - setupTargetPaths rootTo pathTo + setupTargetPathsAndCreateParentDirectory rootTo + (pathTo, normalizeProps propsFrom propsTo) >>= fun (workingDir, realPathTo, tempPathTo, localPathTo) -> (* When in Unicode case-insensitive mode, we want to create files with NFC normal-form filenames. *) Modified: trunk/src/files.mli =================================================================== --- trunk/src/files.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/files.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -26,9 +26,11 @@ -> Common.root (* from what root *) -> Path.t (* from what path *) -> Common.updateItem (* source updates *) + -> Props.t list (* properties of parent directories *) -> Common.root (* to what root *) -> Path.t (* to what path *) -> Common.updateItem (* dest. updates *) + -> Props.t list (* properties of parent directories *) -> Uutil.File.t (* id for showing progress of transfer *) -> unit Lwt.t Modified: trunk/src/globals.ml =================================================================== --- trunk/src/globals.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/globals.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -162,7 +162,7 @@ (* FIX: this does weird things in case-insensitive mode... *) let globPath lr p = - let p = Path.magic p in + let p = Path.forceLocal p in debug (fun() -> Util.msg "Checking path '%s' for expansions\n" (Path.toDebugString p) ); @@ -175,10 +175,10 @@ (Path.toString p) "but first root (after canonizing) is non-local")) | Some lrfspath -> - Safelist.map (fun c -> Path.magic' (Path.child parent c)) + Safelist.map (fun c -> Path.makeGlobal (Path.child parent c)) (Os.childrenOf lrfspath parent) end - | _ -> [Path.magic' p] + | _ -> [Path.makeGlobal p] let expandWildcardPaths() = let lr = Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/mkProjectInfo.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -5,8 +5,8 @@ let projectName = "unison" let majorVersion = 2 -let minorVersion = 36 -let pointVersionOrigin = 359 (* Revision that corresponds to point version 0 *) +let minorVersion = 37 +let pointVersionOrigin = 377 (* Revision that corresponds to point version 0 *) (* Documentation: This is a program to construct a version of the form Major.Minor.Point, @@ -65,7 +65,7 @@ Str.matched_group 1 str;; let extract_int re str = int_of_string (extract_str re str);; -let revisionString = "$Rev: 332$";; +let revisionString = "$Rev: 378$";; let pointVersion = if String.length revisionString > 5 then Scanf.sscanf revisionString "$Rev: %d " (fun x -> x) - pointVersionOrigin else (* Determining the pointVersionOrigin in bzr is kind of tricky: @@ -96,3 +96,4 @@ + Modified: trunk/src/path.ml =================================================================== --- trunk/src/path.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/path.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -207,5 +207,5 @@ (Util.osType = `Unix || Util.isCygwin) && Pred.test followPred (toString path) -let magic p = p -let magic' p = p +let forceLocal p = p +let makeGlobal p = p Modified: trunk/src/path.mli =================================================================== --- trunk/src/path.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/path.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -36,5 +36,5 @@ val followLink : local -> bool val followPred : Pred.t -val magic : t -> local -val magic' : local -> t +val forceLocal : t -> local +val makeGlobal : local -> t Modified: trunk/src/props.ml =================================================================== --- trunk/src/props.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/props.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -146,7 +146,9 @@ else off in - bit 0o1000 "" "" "t" ^ + bit 0o4000 "" "-" "S" ^ + bit 0o2000 "" "-" "s" ^ + bit 0o1000 "?" "" "t" ^ bit 0o0400 "?" "-" "r" ^ bit 0o0200 "?" "-" "w" ^ bit 0o0100 "?" "-" "x" ^ @@ -169,7 +171,9 @@ else off in - bit 0o1000 "" "" "t" ^ + bit 0o4000 "" "-" "S" ^ + bit 0o2000 "" "-" "s" ^ + bit 0o1000 "?" "" "t" ^ bit 0o0400 "?" "-" "r" ^ bit 0o0200 "?" "-" "w" ^ bit 0o0100 "?" "-" "x" ^ Modified: trunk/src/recon.ml =================================================================== --- trunk/src/recon.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/recon.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -247,44 +247,44 @@ type singleUpdate = Rep1Updated | Rep2Updated -let update2replicaContent path (conflict: bool) ui ucNew oldType: +let update2replicaContent path (conflict: bool) ui props ucNew oldType: Common.replicaContent = let size = Update.updateSize path ui in match ucNew with Absent -> {typ = `ABSENT; status = `Deleted; desc = Props.dummy; - ui = ui; size = size} + ui = ui; size = size; props = props} | File (desc, ContentsSame) -> {typ = `FILE; status = `PropsChanged; desc = desc; - ui = ui; size = size} + ui = ui; size = size; props = props} | File (desc, _) when oldType <> `FILE -> {typ = `FILE; status = `Created; desc = desc; - ui = ui; size = size} + ui = ui; size = size; props = props} | File (desc, ContentsUpdated _) -> {typ = `FILE; status = `Modified; desc = desc; - ui = ui; size = size} + ui = ui; size = size; props = props} | Symlink l when oldType <> `SYMLINK -> {typ = `SYMLINK; status = `Created; desc = Props.dummy; - ui = ui; size = size} + ui = ui; size = size; props = props} | Symlink l -> {typ = `SYMLINK; status = `Modified; desc = Props.dummy; - ui = ui; size = size} + ui = ui; size = size; props = props} | Dir (desc, _, _, _) when oldType <> `DIRECTORY -> {typ = `DIRECTORY; status = `Created; desc = desc; - ui = ui; size = size} + ui = ui; size = size; props = props} | Dir (desc, _, PropsUpdated, _) -> {typ = `DIRECTORY; status = `PropsChanged; desc = desc; - ui = ui; size = size} + ui = ui; size = size; props = props} | Dir (desc, _, PropsSame, _) when conflict -> (* Special case: the directory contents has been modified and the *) (* directory is in conflict. (We don't want to display a conflict *) (* between an unchanged directory and a file, for instance: this would *) (* be rather puzzling to the user) *) {typ = `DIRECTORY; status = `Modified; desc = desc; - ui = ui; size = size} + ui = ui; size = size; props = props} | Dir (desc, _, PropsSame, _) -> {typ = `DIRECTORY; status = `Unchanged; desc =desc; - ui = ui; size = size} + ui = ui; size = size; props = props} let oldType (prev: Common.prevState): Fileinfo.typ = match prev with @@ -297,25 +297,26 @@ | New -> Props.dummy (* [describeUpdate ui] returns the replica contents for both the case of *) -(* updating and the case of non-updatingd *) -let describeUpdate path ui +(* updating and the case of non-updating *) +let describeUpdate path props' ui props : Common.replicaContent * Common.replicaContent = match ui with Updates (ucNewStatus, prev) -> let typ = oldType prev in - (update2replicaContent path false ui ucNewStatus typ, + (update2replicaContent path false ui props ucNewStatus typ, {typ = typ; status = `Unchanged; desc = oldDesc prev; - ui = NoUpdates; size = Update.updateSize path NoUpdates}) + ui = NoUpdates; size = Update.updateSize path NoUpdates; + props = props'}) | _ -> assert false (* Computes the reconItems when only one side has been updated. (We split *) (* this out into a separate function to avoid duplicating all the symmetric *) (* cases.) *) -let rec reconcileNoConflict allowPartial path ui whatIsUpdated +let rec reconcileNoConflict allowPartial path props' ui props whatIsUpdated (result: (Name.t * Name.t, Common.replicas) Tree.u) : (Name.t * Name.t, Common.replicas) Tree.u = let different() = - let rcUpdated, rcNotUpdated = describeUpdate path ui in + let rcUpdated, rcNotUpdated = describeUpdate path props' ui props in match whatIsUpdated with Rep2Updated -> Different {rc1 = rcNotUpdated; rc2 = rcUpdated; @@ -340,7 +341,8 @@ (fun result (theName, uiChild) -> Tree.leave (reconcileNoConflict allowPartial (Path.child path theName) - uiChild whatIsUpdated (Tree.enter result (theName, theName)))) + [] uiChild [] whatIsUpdated + (Tree.enter result (theName, theName)))) r children | Updates _ -> Tree.add result (propagateErrors allowPartial (different ())) @@ -393,21 +395,26 @@ (* Tree.u *) (* unequals: (Name.t * Name.t, Common.replicas) Tree.u *) (* -- *) -let rec reconcile allowPartial path ui1 ui2 counter (equals:(_*_,_)Tree.u) unequals = +let rec reconcile + allowPartial path ui1 props1 ui2 props2 counter equals unequals = let different uc1 uc2 oldType equals unequals = (equals, Tree.add unequals (propagateErrors allowPartial - (Different {rc1 = update2replicaContent path true ui1 uc1 oldType; - rc2 = update2replicaContent path true ui2 uc2 oldType; + (Different {rc1 = update2replicaContent + path true ui1 props1 uc1 oldType; + rc2 = update2replicaContent + path true ui2 props2 uc2 oldType; direction = Conflict; default_direction = Conflict; errors1 = []; errors2 = []}))) in let toBeMerged uc1 uc2 oldType equals unequals = (equals, Tree.add unequals (propagateErrors allowPartial - (Different {rc1 = update2replicaContent path true ui1 uc1 oldType; - rc2 = update2replicaContent path true ui2 uc2 oldType; + (Different {rc1 = update2replicaContent + path true ui1 props1 uc1 oldType; + rc2 = update2replicaContent + path true ui2 props2 uc2 oldType; direction = Merge; default_direction = Merge; errors1 = []; errors2 = []}))) in match (ui1, ui2) with @@ -416,9 +423,13 @@ | (_, Error s) -> (equals, Tree.add unequals (Problem s)) | (NoUpdates, _) -> - (equals, reconcileNoConflict allowPartial path ui2 Rep2Updated unequals) + (equals, + reconcileNoConflict + allowPartial path props1 ui2 props2 Rep2Updated unequals) | (_, NoUpdates) -> - (equals, reconcileNoConflict allowPartial path ui1 Rep1Updated unequals) + (equals, + reconcileNoConflict + allowPartial path props2 ui1 props1 Rep1Updated unequals) | (Updates (Absent, _), Updates (Absent, _)) -> (add_equal counter equals (Absent, Absent), unequals) | (Updates (Dir (desc1, children1, propsChanged1, _) as uc1, prevState1), @@ -439,8 +450,8 @@ (equals, Tree.add unequals (Different - {rc1 = update2replicaContent path false ui1 uc1 `DIRECTORY; - rc2 = update2replicaContent path false ui2 uc2 `DIRECTORY; + {rc1 = update2replicaContent path false ui1 [] uc1 `DIRECTORY; + rc2 = update2replicaContent path false ui2 [] uc2 `DIRECTORY; direction = action; default_direction = action; errors1 = []; errors2 = []})) in @@ -448,7 +459,8 @@ Safelist.fold_left (fun (equals, unequals) (name1,ui1,name2,ui2) -> let (eq, uneq) = - reconcile allowPartial (Path.child path name1) ui1 ui2 counter + reconcile + allowPartial (Path.child path name1) ui1 [] ui2 [] counter (Tree.enter equals (name1, name2)) (Tree.enter unequals (name1, name2)) in @@ -521,16 +533,22 @@ (* file that is updated in the same way on both roots *) let reconcileList allowPartial (pathUpdatesList: - (Path.t * Common.updateItem * Path.t * Common.updateItem) list) + ((Path.local * Common.updateItem * Props.t list) * + (Path.local * Common.updateItem * Props.t list)) list) : Common.reconItem list * bool * Path.t list = let counter = ref 0 in let archiveUpdated = ref false in let (equals, unequals, dangerous) = Safelist.fold_left - (fun (equals, unequals, dangerous) (path1,ui1,path2,ui2) -> + (fun (equals, unequals, dangerous) + ((path1,ui1,props1),(path2,ui2,props2)) -> + (* We make the paths global as we may concatenate them with + names from the other replica *) + let path1 = Path.makeGlobal path1 in + let path2 = Path.makeGlobal path2 in let (equals, unequals) = reconcile allowPartial - path1 ui1 ui2 (counter, archiveUpdated) + path1 ui1 props1 ui2 props2 (counter, archiveUpdated) (enterPath path1 path2 equals) (enterPath path1 path2 unequals) in Modified: trunk/src/recon.mli =================================================================== --- trunk/src/recon.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/recon.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -4,7 +4,8 @@ val reconcileAll : ?allowPartial:bool (* whether we allow partial synchronization of directories (default to false) *) - -> (Path.t * Common.updateItem * Path.t * Common.updateItem) list + -> ((Path.local * Common.updateItem * Props.t list) * + (Path.local * Common.updateItem * Props.t list)) list (* one updateItem per replica, per path *) -> Common.reconItem list (* List of updates that need propagated *) * bool (* Any file updated equally on all roots*) Modified: trunk/src/remote.ml =================================================================== --- trunk/src/remote.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/remote.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -270,7 +270,6 @@ to the requests to be processed *) Lwt.ignore_result (Lwt_unix.yield () >>= fun () -> popOutputQueues q) - let disableFlowControl q = q.flowControl <- false; if not q.canWrite then allowWrites q @@ -315,6 +314,7 @@ flushBuffer buf end else flushBuffer buf) >>= fun () -> + assert (not (q.flowControl && q.canWrite)); (* Restart the reader thread if needed *) match !receiver with None -> Lwt.return () @@ -894,6 +894,10 @@ (fun e -> ping conn id >>= fun () -> Lwt.fail e) end +let commandAvailable = + registerRootCmd "commandAvailable" + (fun (_, cmdName) -> Lwt.return (Util.StringMap.mem cmdName !serverCmds)) + (**************************************************************************** BUILDING CONNECTIONS TO THE SERVER ****************************************************************************) @@ -933,6 +937,16 @@ Both hosts must use non-blocking I/O (otherwise a dead-lock is possible with ssh). *) +let halfduplex = + Prefs.createBool "halfduplex" false + "!force half-duplex communication with the server" + "When this flag is set to {\\tt true}, Unison network communication \ + is forced to be half duplex (the client and the server never \ + simultaneously emit data). If you experience unstabilities with \ + your network link, this may help. The communication is always \ + half-duplex when synchronizing with a Windows machine due to a \ + limitation of Unison current implementation that could result \ + in a deadlock." let negociateFlowControlLocal conn () = if not needFlowControl then disableFlowControl conn.outputQueue; @@ -942,14 +956,14 @@ registerServerCmd "negociateFlowControl" negociateFlowControlLocal let negociateFlowControl conn = - if not needFlowControl then - negociateFlowControlRemote conn () >>= (fun needed -> - if not needed then - negociateFlowControlLocal conn () >>= (fun _ -> Lwt.return ()) - else - Lwt.return ()) - else - Lwt.return () + (* Flow control negociation can be done asynchronously. *) + if not (needFlowControl || Prefs.read halfduplex) then + Lwt.ignore_result + (negociateFlowControlRemote conn () >>= fun needed -> + if not needed then + negociateFlowControlLocal conn () + else + Lwt.return true) (****) @@ -960,8 +974,7 @@ checkHeader conn (Bytearray.create 1) 0 (String.length connectionHeader) >>= (fun () -> Lwt.ignore_result (receive conn); - (* Flow control negociation can be done asynchronously. *) - Lwt.ignore_result (negociateFlowControl conn); + negociateFlowControl conn; Lwt.return conn) let inetAddr host = Modified: trunk/src/remote.mli =================================================================== --- trunk/src/remote.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/remote.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -32,6 +32,12 @@ -> 'a (* additional arguments *) -> 'b Lwt.t) (* -> (suspended) result *) +(* Test whether a command exits on some root *) +val commandAvailable : + Common.root -> (* root *) + string -> (* command name *) + bool Lwt.t + (* Enter "server mode", reading and processing commands from a remote client process until killed *) val beAServer : unit -> unit Modified: trunk/src/transfer.ml =================================================================== --- trunk/src/transfer.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/transfer.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -94,8 +94,7 @@ | EOF (* Size of a block *) -let blockSize = 700 -let blockSize64 = Int64.of_int blockSize +let minBlockSize = 700 let maxQueueSize = 65500 let maxQueueSizeFS = Uutil.Filesize.ofInt maxQueueSize @@ -105,16 +104,9 @@ (* some informations about the previous token *) mutable pos : int; (* head of the queue *) - mutable prog : int } (* the size of the data they represent *) + mutable prog : int; (* the size of the data they represent *) + mutable bSize : int } (* block size *) -(* Size of the data a token represents for the destination host, - to keep track of the propagation progress *) -let tokenProg t = - match t with - STRING (s, pos, len) -> String.length s - | BLOCK n -> blockSize - | EOF -> 0 - let encodeInt3 s pos i = assert (i >= 0 && i < 256 * 256 * 256); s.{pos + 0} <- Char.chr ((i lsr 0) land 0xff); @@ -199,7 +191,7 @@ encodeInt3 q.data (q.pos + 1) pos; encodeInt1 q.data (q.pos + 4) 1; q.pos <- q.pos + 5; - q.prog <- q.prog + blockSize; + q.prog <- q.prog + q.bSize; q.previous <- `Block (pos + 1); return ()) @@ -209,7 +201,7 @@ assert (decodeInt3 q.data (q.pos - 4) + count = pos); assert (count < 255); encodeInt1 q.data (q.pos - 1) (count + 1); - q.prog <- q.prog + blockSize; + q.prog <- q.prog + q.bSize; q.previous <- if count = 254 then `None else `Block (pos + 1); return () @@ -229,7 +221,7 @@ | BLOCK pos, _ -> pushBlock q id transmit pos -let makeQueue length = +let makeQueue length blockSize = { data = (* We need to make sure here that the size of the queue is not larger than 65538 @@ -237,7 +229,8 @@ Bytearray.create (if length > maxQueueSizeFS then maxQueueSize else Uutil.Filesize.toInt length + 10); - pos = 0; previous = `None; prog = 0 } + pos = 0; previous = `None; prog = 0; + bSize = blockSize } (*************************************************************************) (* GENERIC TRANSMISSION *) @@ -252,7 +245,7 @@ let bufSz = 8192 in let bufSzFS = Uutil.Filesize.ofInt 8192 in let buf = String.create bufSz in - let q = makeQueue length in + let q = makeQueue length 0 in let rec sendSlice length = let count = reallyRead infd buf 0 @@ -303,75 +296,116 @@ (* It is impossible to use rsync when the file size is smaller than the size of a block *) - let blockSizeFs = Uutil.Filesize.ofInt blockSize - let aboveRsyncThreshold sz = sz >= blockSizeFs + let minBlockSizeFs = Uutil.Filesize.ofInt minBlockSize + let aboveRsyncThreshold sz = sz > minBlockSizeFs (* The type of the info that will be sent to the source host *) - type rsync_block_info = (Checksum.t * Digest.t) list + type rsync_block_info = + { blockSize : int; + blockCount : int; + checksumSize : int; + weakChecksum : + (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t; + strongChecksum : Bytearray.t } - (*** PREPROCESS ***) - (* Preprocess buffer size *) - let preproBufSize = 8192 + (* Worst case probability of a failure *) + let logProba = -27. (* One time in 100 millions *) + (* Strength of the weak checksum + (how many bit of the weak checksum we can rely on) *) + let weakLen = 27. + (* This is what rsync uses: + let logProba = -10. + let weakLen = 31. + This would save almost 3 bytes per block, but one need to be able + to recover from an rsync error. + *) + (* Block size *) + let computeBlockSize l = truncate (max 700. (min (sqrt l) 131072.)) + (* Size of each strong checksum *) + let checksumSize bs sl dl = + let bits = + -. logProba -. weakLen +. log (sl *. dl /. float bs) /. log 2. in + max 2 (min 16 (truncate ((bits +. 7.99) /. 8.))) + let sizes srcLength dstLength = + let blockSize = computeBlockSize (Uutil.Filesize.toFloat dstLength) in + let blockCount = + let count = + Int64.div (Uutil.Filesize.toInt64 dstLength) (Int64.of_int blockSize) + in + Int64.to_int (min 16777216L count) + in + let csSize = + checksumSize blockSize + (Uutil.Filesize.toFloat srcLength)(Uutil.Filesize.toFloat dstLength) + in + (blockSize, blockCount, csSize) + (* Incrementally build arg by executing f on successive blocks (of size 'blockSize') of the input stream (pointed by 'infd'). The procedure uses a buffer of size 'bufferSize' to load the input, and eventually handles the buffer update. *) - let blockIter infd f arg maxCount = + let blockIter infd f blockSize maxCount = let bufferSize = 8192 + blockSize in let buffer = String.create bufferSize in - let rec iter count arg offset length = - if count = maxCount then arg else begin + let rec iter count offset length = + if count = maxCount then + count + else begin let newOffset = offset + blockSize in - if newOffset <= length then - iter (count + 1) (f buffer offset arg) newOffset length - else if offset > 0 then begin + if newOffset <= length then begin + f count buffer offset; + iter (count + 1) newOffset length + end else if offset > 0 then begin let chunkSize = length - offset in String.blit buffer offset buffer 0 chunkSize; - iter count arg 0 chunkSize + iter count 0 chunkSize end else begin let l = input infd buffer length (bufferSize - length) in if l = 0 then - arg + count else - iter count arg 0 (length + l) + iter count 0 (length + l) end end in - iter 0 arg 0 0 + iter 0 0 0 (* Given a block size, get blocks from the old file and compute a checksum and a fingerprint for each one. *) - let rsyncPreprocess infd = + let rsyncPreprocess infd srcLength dstLength = debug (fun() -> Util.msg "preprocessing\n"); - debugLog (fun() -> Util.msg "block size = %d bytes\n" blockSize); + let (blockSize, blockCount, csSize) = sizes srcLength dstLength in + debugLog (fun() -> + Util.msg "block size = %d bytes; block count = %d; \ + strong checksum size = %d\n" blockSize blockCount csSize); let timer = Trace.startTimer "Preprocessing old file" in - let addBlock buf offset rev_bi = - let cs = Checksum.substring buf offset blockSize in - let fp = Digest.substring buf offset blockSize in - (cs, fp) :: rev_bi + let weakCs = + Bigarray.Array1.create Bigarray.int32 Bigarray.c_layout blockCount in + let strongCs = Bytearray.create (blockCount * csSize) in + let addBlock i buf offset = + weakCs.{i} <- Int32.of_int (Checksum.substring buf offset blockSize); + Bytearray.blit_from_string + (Digest.substring buf offset blockSize) 0 strongCs (i * csSize) csSize in (* Make sure we are at the beginning of the file (important for AppleDouble files *) LargeFile.seek_in infd 0L; (* Limit the number of block so that there is no overflow in encodeInt3 *) - let rev_bi = blockIter infd addBlock [] (256*256*256) in - let bi = Safelist.rev rev_bi in - debugLog (fun() -> Util.msg "%d blocks\n" (Safelist.length bi)); + let count = blockIter infd addBlock blockSize (256*256*256) in + debugLog (fun() -> Util.msg "%d blocks\n" count); Trace.showTimer timer; - bi + ({ blockSize = blockSize; blockCount = count; checksumSize = csSize; + weakChecksum = weakCs; strongChecksum = strongCs }, + blockSize) (* Expected size of the [rsync_block_info] datastructure (in KiB). *) - (* The calculation here are for a 64 bit architecture. *) - (* When serialized, the datastructure takes currently 24 bytes per block. *) - (* In theory, 12 byte per block should be enough! *) - let memoryFootprint sz = - Int64.to_int - (min (Int64.div (Uutil.Filesize.toInt64 sz) 716800L) 16384L) - * 72 + let memoryFootprint srcLength dstLength = + let (blockSize, blockCount, csSize) = sizes srcLength dstLength in + blockCount * (csSize + 4) (*** DECOMPRESSION ***) @@ -380,7 +414,7 @@ (* For each transfer instruction, either output a string or copy one or several blocks from the old file. *) - let rsyncDecompress infd outfd showProgress (data, pos, len) = + let rsyncDecompress blockSize infd outfd showProgress (data, pos, len) = let decomprBuf = String.create decomprBufSize in let progress = ref 0 in let rec copy length = @@ -393,7 +427,7 @@ reallyWrite outfd decomprBuf 0 length in let copyBlocks n k = - LargeFile.seek_in infd (Int64.mul n blockSize64); + LargeFile.seek_in infd (Int64.mul n (Int64.of_int blockSize)); let length = k * blockSize in copy length; progress := !progress + length @@ -435,42 +469,33 @@ (* Maximum number of entries in the hash table. MUST be a power of 2 ! Typical values are around an average 2 * fileSize / blockSize. *) - let hashTableMaxLength = 64 * 1024 + let hashTableMaxLength = 2048 * 1024 + let rec upperPowerOfTwo n n2 = + if (n2 >= n) || (n2 = hashTableMaxLength) then + n2 + else + upperPowerOfTwo n (2 * n2) + let hash checksum = checksum (* Compute the hash table length as a function of the number of blocks *) let hashTableLength signatures = - let rec upperPowerOfTwo n n2 = - if (n2 >= n) || (n2 = hashTableMaxLength) then - n2 - else - upperPowerOfTwo n (2 * n2) - in - 2 * (upperPowerOfTwo (Safelist.length signatures) 32) + 2 * (upperPowerOfTwo signatures.blockCount 32) (* Hash the block signatures into the hash table *) let hashSig hashTableLength signatures = let hashTable = Array.make hashTableLength [] in - let rec addList k l = - match l with - [] -> - () - | (cs, fp) :: r -> - (* Negative 31-bits integers are sign-extended when - unmarshalled on a 64-bit architecture, so we - truncate them back to 31 bits. *) - let cs = cs land 0x7fffffff in - let h = (hash cs) land (hashTableLength - 1) in - hashTable.(h) <- (k, cs, fp)::(hashTable.(h)); - addList (k + 1) r - in - addList 0 signatures; + for k = 0 to signatures.blockCount - 1 do + let cs = Int32.to_int signatures.weakChecksum.{k} land 0x7fffffff in + let h = (hash cs) land (hashTableLength - 1) in + hashTable.(h) <- (k, cs) :: hashTable.(h) + done; hashTable (* Given a key, retrieve the corresponding entry in the table *) let findEntry hashTable hashTableLength checksum : - (int * Checksum.t * Digest.t) list = + (int * Checksum.t) list = hashTable.((hash checksum) land (hashTableLength - 1)) (* Log the values of the parameters associated with the hash table *) @@ -527,12 +552,14 @@ (* Compression buffer size *) (* MUST be >= 2 * blockSize *) - let comprBufSize = 8192 - let comprBufSizeFS = Uutil.Filesize.ofInt 8192 + let minComprBufSize = 8192 (* Compress the file using the algorithm described in the header *) let rsyncCompress sigs infd srcLength showProgress transmit = debug (fun() -> Util.msg "compressing\n"); + let blockSize = sigs.blockSize in + let comprBufSize = (2 * blockSize + 8191) land (-8192) in + let comprBufSizeFS = Uutil.Filesize.ofInt comprBufSize in debugLog (fun() -> Util.msg "compression buffer size = %d bytes\n" comprBufSize); debugLog (fun() -> Util.msg "block size = %d bytes\n" blockSize); @@ -564,7 +591,7 @@ *) (* Enable token buffering *) - let tokenQueue = makeQueue srcLength in + let tokenQueue = makeQueue srcLength blockSize in let flushTokenQueue () = flushQueue tokenQueue showProgress transmit true in let transmit token = queueToken tokenQueue showProgress transmit token in @@ -574,6 +601,17 @@ let blockTable = hashSig !hashTableLength sigs in logHash blockTable !hashTableLength; + let rec fingerprintMatchRec checksums pos fp i = + let i = i - 1 in + i < 0 || + (String.unsafe_get fp i = checksums.{pos + i} && + fingerprintMatchRec checksums pos fp i) + in + let fingerprintMatch k fp = + fingerprintMatchRec sigs.strongChecksum (k * sigs.checksumSize) + fp sigs.checksumSize + in + (* Create the compression buffer *) let comprBuf = String.create comprBufSize in @@ -661,12 +699,12 @@ match entry, fingerprint with | [], _ -> -1 - | (k, cs, fp) :: tl, None + | (k, cs) :: tl, None when cs = checksum -> let fingerprint = Digest.substring comprBuf offset blockSize in findBlock offset checksum entry (Some fingerprint) - | (k, cs, fp) :: tl, Some fingerprint - when (cs = checksum) && (fp = fingerprint) -> + | (k, cs) :: tl, Some fingerprint + when cs = checksum && fingerprintMatch k fingerprint -> k | _ :: tl, _ -> findBlock offset checksum tl fingerprint Modified: trunk/src/transfer.mli =================================================================== --- trunk/src/transfer.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/transfer.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -78,16 +78,19 @@ type rsync_block_info (* Expected size of the [rsync_block_info] datastructure (in KiB). *) - val memoryFootprint : Uutil.Filesize.t -> int + val memoryFootprint : Uutil.Filesize.t -> Uutil.Filesize.t -> int (* Compute block informations from the old file *) val rsyncPreprocess : in_channel (* old file descriptor *) - -> rsync_block_info + -> Uutil.Filesize.t (* source file length *) + -> Uutil.Filesize.t (* destination file length *) + -> rsync_block_info * int (* Interpret a transfer instruction *) val rsyncDecompress : - in_channel (* old file descriptor *) + int (* block size *) + -> in_channel (* old file descriptor *) -> out_channel (* output file descriptor *) -> (int -> unit) (* progress report *) -> transfer_instruction (* transfer instruction received *) Modified: trunk/src/transport.ml =================================================================== --- trunk/src/transport.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/transport.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -120,8 +120,8 @@ ("Updating file " ^ Path.toString toPath) (fun () -> Files.copy (`Update (fileSize uiFrom uiTo)) - fromRoot fromPath uiFrom toRoot toPath uiTo id) - | {ui = uiFrom}, {ui = uiTo} -> + fromRoot fromPath uiFrom [] toRoot toPath uiTo [] id) + | {ui = uiFrom; props = propsFrom}, {ui = uiTo; props = propsTo} -> logLwtNumbered ("Copying " ^ Path.toString toPath ^ "\n from " ^ root2string fromRoot ^ "\n to " ^ @@ -129,7 +129,8 @@ ("Copying " ^ Path.toString toPath) (fun () -> Files.copy `Copy - fromRoot fromPath uiFrom toRoot toPath uiTo id)) + fromRoot fromPath uiFrom propsFrom + toRoot toPath uiTo propsTo id)) (fun e -> Trace.log (Printf.sprintf "Failed: %s\n" (Util.printException e)); Modified: trunk/src/ubase/prefs.ml =================================================================== --- trunk/src/ubase/prefs.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/ubase/prefs.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -56,30 +56,33 @@ (* created, a dumper (marshaler) and a loader (parser) are added to the list *) (* kept here... *) -type dumpedPrefs = (string * string) list +type dumpedPrefs = (string * bool * string) list -let dumpers = ref ([] : (string * (unit->string)) list) +let dumpers = ref ([] : (string * bool * (unit->string)) list) let loaders = ref (Util.StringMap.empty : (string->unit) Util.StringMap.t) -let adddumper name f = - dumpers := (name,f) :: !dumpers +let adddumper name optional f = + dumpers := (name,optional,f) :: !dumpers let addloader name f = loaders := Util.StringMap.add name f !loaders -let dump () = Safelist.map (fun (name,f) -> (name, f())) !dumpers - +let dump () = Safelist.map (fun (name, opt, f) -> (name, opt, f())) !dumpers + let load d = - begin - Safelist.iter - (fun (name, dumpedval) -> - let loaderfn = - try Util.StringMap.find name !loaders - with Not_found -> raise (Util.Fatal - ("Preference "^name^" not found: inconsistent Unison versions??")) - in loaderfn dumpedval) - d - end + Safelist.iter + (fun (name, opt, dumpedval) -> + match + try Some (Util.StringMap.find name !loaders) with Not_found -> None + with + Some loaderfn -> + loaderfn dumpedval + | None -> + if not opt then + raise (Util.Fatal + ("Preference "^name^" not found: \ + inconsistent Unison versions??"))) + d (* For debugging *) let dumpPrefsToStderr() = @@ -117,42 +120,42 @@ raise (Util.Fatal ("Preference " ^ name ^ " registered twice")); prefs := Util.StringMap.add name (doc, pspec, fulldoc) !prefs -let createPrefInternal name default doc fulldoc printer parsefn = +let createPrefInternal name local default doc fulldoc printer parsefn = let newCell = rawPref (default, [name]) in registerPref name (parsefn newCell) doc fulldoc; - adddumper name (fun () -> Marshal.to_string !newCell []); + adddumper name local (fun () -> Marshal.to_string !newCell []); addprinter name (fun () -> printer (fst !newCell)); addresetter (fun () -> newCell := (default, [name])); addloader name (fun s -> newCell := Marshal.from_string s 0); newCell -let create name default doc fulldoc intern printer = - createPrefInternal name default doc fulldoc printer +let create name ?(local=false) default doc fulldoc intern printer = + createPrefInternal name local default doc fulldoc printer (fun cell -> Uarg.String (fun s -> set cell (intern (fst !cell) s))) -let createBool name default doc fulldoc = +let createBool name ?(local=false) default doc fulldoc = let doc = if default then doc ^ " (default true)" else doc in - createPrefInternal name default doc fulldoc + createPrefInternal name local default doc fulldoc (fun v -> [if v then "true" else "false"]) (fun cell -> Uarg.Bool (fun b -> set cell b)) -let createInt name default doc fulldoc = - createPrefInternal name default doc fulldoc - (fun v -> [string_of_int v]) +let createInt name ?(local=false) default doc fulldoc = + createPrefInternal name local default doc fulldoc + (fun v -> [string_of_int v]) (fun cell -> Uarg.Int (fun i -> set cell i)) -let createString name default doc fulldoc = - createPrefInternal name default doc fulldoc +let createString name ?(local=false) default doc fulldoc = + createPrefInternal name local default doc fulldoc (fun v -> [v]) (fun cell -> Uarg.String (fun s -> set cell s)) -let createFspath name default doc fulldoc = - createPrefInternal name default doc fulldoc +let createFspath name ?(local=false) default doc fulldoc = + createPrefInternal name local default doc fulldoc (fun v -> [System.fspathToString v]) (fun cell -> Uarg.String (fun s -> set cell (System.fspathFromString s))) -let createStringList name doc fulldoc = - createPrefInternal name [] doc fulldoc +let createStringList name ?(local=false) doc fulldoc = + createPrefInternal name local [] doc fulldoc (fun v -> v) (fun cell -> Uarg.String (fun s -> set cell (s::(fst !cell)))) Modified: trunk/src/ubase/prefs.mli =================================================================== --- trunk/src/ubase/prefs.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/ubase/prefs.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -13,6 +13,7 @@ (* accumulates a list of values. *) val createBool : string (* preference name *) + -> ?local:bool (* whether it is local to the client *) -> bool (* initial value *) -> string (* documentation string *) -> string (* full (tex) documentation string *) @@ -20,6 +21,7 @@ val createInt : string (* preference name *) + -> ?local:bool (* whether it is local to the client *) -> int (* initial value *) -> string (* documentation string *) -> string (* full (tex) documentation string *) @@ -27,6 +29,7 @@ val createString : string (* preference name *) + -> ?local:bool (* whether it is local to the client *) -> string (* initial value *) -> string (* documentation string *) -> string (* full (tex) documentation string *) @@ -34,6 +37,7 @@ val createFspath : string (* preference name *) + -> ?local:bool (* whether it is local to the client *) -> System.fspath (* initial value *) -> string (* documentation string *) -> string (* full (tex) documentation string *) @@ -41,6 +45,7 @@ val createStringList : string (* preference name *) + -> ?local:bool (* whether it is local to the client *) -> string (* documentation string *) -> string (* full (tex) documentation string *) -> string list t (* -> new preference value *) @@ -51,6 +56,7 @@ (* IllegalValue if it is passed a string it cannot deal with. *) val create : string (* preference name *) + -> ?local:bool (* whether it is local to the client *) -> 'a (* initial value *) -> string (* documentation string *) -> string (* full (tex) documentation string *) Modified: trunk/src/uicommon.ml =================================================================== --- trunk/src/uicommon.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/uicommon.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -441,7 +441,7 @@ let architecture = Remote.registerRootCmd "architecture" - (fun (_,()) -> return (Util.osType = `Win32, Osx.isMacOSX)) + (fun (_,()) -> return (Util.osType = `Win32, Osx.isMacOSX, Util.isCygwin)) (* During startup the client determines the case sensitivity of each root. If any root is case insensitive, all roots must know this -- it's @@ -452,16 +452,19 @@ let checkCaseSensitivity () = Globals.allRootsMap (fun r -> architecture r ()) >>= (fun archs -> let someHostIsRunningWindows = - Safelist.exists (fun (isWin, _) -> isWin) archs in + Safelist.exists (fun (isWin, _, _) -> isWin) archs in let allHostsAreRunningWindows = - Safelist.for_all (fun (isWin, _) -> isWin) archs in + Safelist.for_all (fun (isWin, _, _) -> isWin) archs in + let someHostIsRunningBareWindows = + Safelist.exists (fun (isWin, _, isCyg) -> isWin && not isCyg) archs in let someHostRunningOsX = - Safelist.exists (fun (_, isOSX) -> isOSX) archs in + Safelist.exists (fun (_, isOSX, _) -> isOSX) archs in let someHostIsCaseInsensitive = someHostIsRunningWindows || someHostRunningOsX in Case.init someHostIsCaseInsensitive; Props.init someHostIsRunningWindows; Osx.init someHostRunningOsX; + Fileinfo.init someHostIsRunningBareWindows; Prefs.set Globals.someHostIsRunningWindows someHostIsRunningWindows; Prefs.set Globals.allHostsAreRunningWindows allHostsAreRunningWindows; return ()) Modified: trunk/src/uigtk2.ml =================================================================== --- trunk/src/uigtk2.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/uigtk2.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -259,7 +259,7 @@ GBin.scrolled_window ?packing ~show:false ~hpolicy:`NEVER ~vpolicy:`AUTOMATIC () in - let text = GText.view ?editable ?wrap_mode:(Some `WORD) ~packing:sw#add () in + let text = GText.view ?editable ~wrap_mode:`WORD ~packing:sw#add () in object inherit GObj.widget_full sw#as_widget method text = text @@ -382,8 +382,20 @@ val values = Array.make width 0. val mutable active = false - method activate a = active <- a + method redraw () = + scale := min_scale; + while !maxim > !scale do + scale := !scale *. 1.5 + done; + pixmap#set_foreground `WHITE; + pixmap#rectangle ~filled:true ~x:0 ~y:0 ~width ~height (); + pixmap#set_foreground `BLACK; + for i = 0 to width - 1 do + self#rect i values.(max 0 (i - 1)) values.(i) + done + method activate a = active <- a; if a then self#redraw () + method scale h = truncate ((float height) *. h /. !scale) method private rect i v' v = @@ -416,18 +428,9 @@ if active then begin let need_resize = !maxim > !scale || (!maxim > min_scale && !maxim < !scale /. 1.5) in - if need_resize then begin - scale := min_scale; - while !maxim > !scale do - scale := !scale *. 1.5 - done; - pixmap#set_foreground `WHITE; - pixmap#rectangle ~filled:true ~x:0 ~y:0 ~width ~height (); - pixmap#set_foreground `BLACK; - for i = 0 to width - 1 do - self#rect i values.(max 0 (i - 1)) values.(i) - done - end else begin + if need_resize then + self#redraw () + else begin pixmap#put_pixmap ~x:0 ~y:0 ~xsrc:1 (pixmap#pixmap); pixmap#set_foreground `WHITE; pixmap#rectangle @@ -440,7 +443,26 @@ let clientWritten = ref 0. let serverWritten = ref 0. +let emitRate2 = ref 0. +let receiveRate2 = ref 0. +let rate2str v = + if v > 9.9e3 then begin + if v > 9.9e6 then + Format.sprintf "%1.0f MiB/s" (v /. 1e6) + else if v > 999e3 then + Format.sprintf "%1.1f MiB/s" (v /. 1e6) + else + Format.sprintf "%1.0f KiB/s" (v /. 1e3) + end else begin + if v > 990. then + Format.sprintf "%1.1f KiB/s" (v /. 1e3) + else if v > 99. then + Format.sprintf "%1.2f KiB/s" (v /. 1e3) + else + " " + end + let statistics () = let title = "Statistics" in let t = GWindow.dialog ~title () in @@ -487,10 +509,26 @@ let emittedBytes = ref 0. in let emitRate = ref 0. in - let emitRate2 = ref 0. in let receivedBytes = ref 0. in let receiveRate = ref 0. in - let receiveRate2 = ref 0. in + + let stopCounter = ref 0 in + + let updateTable () = + let kib2str v = Format.sprintf "%.0f B" v in + lst#set_cell ~text:(rate2str !receiveRate2) 0 1; + lst#set_cell ~text:(rate2str !emitRate2) 0 2; + lst#set_cell ~text: + (rate2str (!receiveRate2 +. !emitRate2)) 0 3; + lst#set_cell ~text:(kib2str !receivedBytes) 1 1; + lst#set_cell ~text:(kib2str !emittedBytes) 1 2; + lst#set_cell ~text: + (kib2str (!receivedBytes +. !emittedBytes)) 1 3; + lst#set_cell ~text:(kib2str !clientWritten) 2 1; + lst#set_cell ~text:(kib2str !serverWritten) 2 2; + lst#set_cell ~text: + (kib2str (!clientWritten +. !serverWritten)) 2 3 + in let timeout _ = emitRate := a *. !emitRate +. @@ -508,42 +546,26 @@ reception#push !receiveRate; emittedBytes := !Remote.emittedBytes; receivedBytes := !Remote.receivedBytes; - let kib2str v = Format.sprintf "%.0f B" v in - let rate2str v = - if v > 9.9e3 then begin - if v > 9.9e6 then - Format.sprintf "%4.0f MiB/s" (v /. 1e6) - else if v > 999e3 then - Format.sprintf "%4.1f MiB/s" (v /. 1e6) - else - Format.sprintf "%4.0f KiB/s" (v /. 1e3) - end else begin - if v > 990. then - Format.sprintf "%4.1f KiB/s" (v /. 1e3) - else if v > 99. then - Format.sprintf "%4.2f KiB/s" (v /. 1e3) - else - " " - end - in - lst#set_cell ~text:(rate2str !receiveRate2) 0 1; - lst#set_cell ~text:(rate2str !emitRate2) 0 2; - lst#set_cell ~text: - (rate2str (!receiveRate2 +. !emitRate2)) 0 3; - lst#set_cell ~text:(kib2str !receivedBytes) 1 1; - lst#set_cell ~text:(kib2str !emittedBytes) 1 2; - lst#set_cell ~text: - (kib2str (!receivedBytes +. !emittedBytes)) 1 3; - lst#set_cell ~text:(kib2str !clientWritten) 2 1; - lst#set_cell ~text:(kib2str !serverWritten) 2 2; - lst#set_cell ~text: - (kib2str (!clientWritten +. !serverWritten)) 2 3; - true + if !stopCounter > 0 then decr stopCounter; + if !stopCounter = 0 then begin + emitRate2 := 0.; receiveRate2 := 0.; + end; + updateTable (); + !stopCounter <> 0 in - ignore (GMain.Timeout.add ~ms:(truncate (delay *. 1000.)) ~callback:timeout); + let startStats () = + if !stopCounter = 0 then begin + emittedBytes := !Remote.emittedBytes; + receivedBytes := !Remote.receivedBytes; + stopCounter := -1; + ignore (GMain.Timeout.add ~ms:(truncate (delay *. 1000.)) + ~callback:timeout) + end else + stopCounter := -1 + in + let stopStats () = stopCounter := 10 in + (t, startStats, stopStats) - t - (****) (* Standard file dialog *) @@ -617,13 +639,13 @@ let contCommand() = result := Some(fileE#text); t#destroy () in + let quitButton = GButton.button ~stock:`QUIT ~packing:f3#add () in + ignore (quitButton#connect#clicked + ~callback:(fun () -> result := None; t#destroy())); let contButton = GButton.button ~stock:`OK ~packing:f3#add () in ignore (contButton#connect#clicked ~callback:contCommand); ignore (fileE#connect#activate ~callback:contCommand); contButton#grab_default (); - let quitButton = GButton.button ~stock:`QUIT ~packing:f3#add () in - ignore (quitButton#connect#clicked - ~callback:(fun () -> result := None; t#destroy())); t#show (); ignore (t#connect#destroy ~callback:GMain.Main.quit); GMain.Main.main (); @@ -746,14 +768,14 @@ okBox ~title:"Error" ~typ:`ERROR ~message:"Something's wrong with the values you entered, try again" in let f3 = t#action_area in + let quitButton = + GButton.button ~stock:`QUIT ~packing:f3#add () in + ignore (quitButton#connect#clicked ~callback:safeExit); let contButton = GButton.button ~stock:`OK ~packing:f3#add () in ignore (contButton#connect#clicked ~callback:contCommand); contButton#grab_default (); ignore (fileE#connect#activate ~callback:contCommand); - let quitButton = - GButton.button ~stock:`QUIT ~packing:f3#add () in - ignore (quitButton#connect#clicked ~callback:safeExit); t#show (); ignore (t#connect#destroy ~callback:GMain.Main.quit); @@ -827,7 +849,7 @@ ("Error scanning profile "^ System.fspathToPrintString filename ^":\n" ^ "Value of 'key' preference must be a single digit (0-9), " ^ "not " ^ k)) - with int_of_string -> raise (Util.Fatal + with Failure "int_of_string" -> raise (Util.Fatal ("Error scanning profile "^ System.fspathToPrintString filename ^":\n" ^ "Value of 'key' preference must be a single digit (0-9), " ^ "not " ^ k)) @@ -969,12 +991,12 @@ close_out ch; fillLst profile; exit () in + let cancelButton = + GButton.button ~stock:`CANCEL ~packing:f3#add () in + ignore (cancelButton#connect#clicked ~callback:exit); let okButton = GButton.button ~stock:`OK ~packing:f3#add () in ignore (okButton#connect#clicked ~callback:okCommand); okButton#grab_default (); - let cancelButton = - GButton.button ~stock:`CANCEL ~packing:f3#add () in - ignore (cancelButton#connect#clicked ~callback:exit); t#show (); grabFocus t; @@ -1189,7 +1211,7 @@ Statistic window *******************************************************************) - let stat_win = statistics () in + let (statWin, startStats, stopStats) = statistics () in (******************************************************************* Groups of things that are sensitive to interaction at the same time @@ -1375,11 +1397,12 @@ | Some (title, details) -> messageBox ~title (transcode details) in + let detailsWindowSW = + GBin.scrolled_window ~packing:(toplevelVBox#pack ~expand:false) + ~shadow_type:`IN ~hpolicy:`NEVER ~vpolicy:`AUTOMATIC () + in let detailsWindow = - let sw = - GBin.scrolled_window ~packing:(toplevelVBox#pack ~expand:false) - ~shadow_type:`IN ~hpolicy:`AUTOMATIC ~vpolicy:`AUTOMATIC () in - GText.view ~editable:false ~wrap_mode:`NONE ~packing:sw#add () + GText.view ~editable:false ~wrap_mode:`NONE ~packing:detailsWindowSW#add () in detailsWindow#misc#modify_font (Lazy.force fontMonospaceMediumPango); detailsWindow#misc#set_size_chars ~height:3 ~width:112 (); @@ -1447,18 +1470,20 @@ detailsWindow#buffer#set_text "" | Some row -> makeRowVisible row; - let details = + let (formated, details) = match !theState.(row).whatHappened with - None -> Uicommon.details2string !theState.(row).ri " " - | Some(Util.Succeeded, _) -> Uicommon.details2string !theState.(row).ri " " - | Some(Util.Failed(s), None) -> s - | Some(Util.Failed(s), Some resultLog) -> s in + None | Some(Util.Succeeded, _) -> + (true, Uicommon.details2string !theState.(row).ri " ") + | Some(Util.Failed(s), _) -> + (false, s) + in let path = Path.toString !theState.(row).ri.path1 in let txt = transcodeFilename path ^ "\n" ^ transcode details in let len = String.length txt in let txt = if txt.[len - 1] = '\n' then String.sub txt 0 (len - 1) else txt in - detailsWindow#buffer#set_text txt + detailsWindow#buffer#set_text txt; + detailsWindow#set_wrap_mode (if formated then `NONE else `WORD) end; (* Display text *) updateButtons () in @@ -1471,6 +1496,8 @@ let progressBar = GRange.progress_bar ~packing:(statusHBox#pack ~expand:false) () in + + progressBar#misc#set_size_chars ~height:1 ~width:25 (); progressBar#set_pulse_step 0.02; let progressBarPulse = ref false in @@ -1655,25 +1682,41 @@ let t0 = ref 0. in let t1 = ref 0. in let lastFrac = ref 0. in + let oldWritten = ref 0. in + let writeRate = ref 0. in let displayGlobalProgress v = if v = 0. || abs_float (v -. !lastFrac) > 1. then begin lastFrac := v; progressBar#set_fraction (max 0. (min 1. (v /. 100.))) end; -(* - let t = Unix.gettimeofday () in - if t -. !t1 >= 1. then begin - t1 := t; - let remTime = - if v <= 0. then "" - else if v >= 100. then "00:00 ETA" - else + if v < 0.001 then + progressBar#set_text " " + else begin + let t = Unix.gettimeofday () in + let delta = t -. !t1 in + if delta >= 0.5 then begin + t1 := t; + let remTime = + if v >= 100. then "00:00 remaining" else let t = truncate ((!t1 -. !t0) *. (100. -. v) /. v +. 0.5) in - Format.sprintf "%02d:%02d ETA" (t / 60) (t mod 60) - in - progressBar#set_text remTime + Format.sprintf "%02d:%02d remaining" (t / 60) (t mod 60) + in + let written = !clientWritten +. !serverWritten in + let b = 0.64 ** delta in + writeRate := + b *. !writeRate +. + (1. -. b) *. (written -. !oldWritten) /. delta; + oldWritten := written; + let rate = !writeRate (*!emitRate2 +. !receiveRate2*) in + let txt = + if rate > 99. then + Format.sprintf "%s (%s)" remTime (rate2str rate) + else + remTime + in + progressBar#set_text txt + end end -*) in let showGlobalProgress b = @@ -1690,6 +1733,7 @@ totalBytesToTransfer := b; totalBytesTransferred := Uutil.Filesize.zero; t0 := Unix.gettimeofday (); t1 := !t0; + writeRate := 0.; oldWritten := !clientWritten +. !serverWritten; displayGlobalProgress 0. in @@ -1784,6 +1828,7 @@ let detectUpdatesAndReconcile () = grDisactivateAll (); + startStats (); mainWindow#clear(); detailsWindow#buffer#set_text ""; @@ -1824,6 +1869,7 @@ current := None; displayMain(); progressBarPulse := false; sync_action := None; displayGlobalProgress 0.; + stopStats (); grSet grGo (Array.length !theState > 0); grSet grRescan true; if Prefs.read Globals.confirmBigDeletes then begin @@ -1995,6 +2041,7 @@ end else actions in + startStats (); Lwt_unix.run (let actions = loop 0 [] (fun ri -> not (Common.isDeletion ri)) in Lwt_util.join actions); @@ -2004,6 +2051,7 @@ Transport.logFinish (); Trace.showTimer t; commitUpdates (); + stopStats (); let failures = let count = @@ -2088,7 +2136,7 @@ let reloadProfile () = match !Prefs.profileName with None -> () - | Some(n) -> loadProfile n in + | Some(n) -> grDisactivateAll (); loadProfile n in let detectCmdName = "Rescan" in let detectCmd () = @@ -2177,10 +2225,12 @@ item.bytesTransferred <- Uutil.Filesize.zero; item.bytesToTransfer <- len; initGlobalProgress len; + startStats (); Uicommon.showDiffs item.ri (fun title text -> messageBox ~title:(transcode title) (transcode text)) Trace.status (Uutil.File.ofLine i); + stopStats (); displayGlobalProgress 0.; fastRedisplay i) | None -> @@ -2453,7 +2503,7 @@ ignore (fileMenu#add_separator ()); ignore (fileMenu#add_item - ~callback:(fun _ -> stat_win#show ()) "Statistics"); + ~callback:(fun _ -> statWin#show ()) "Statistics"); ignore (fileMenu#add_separator ()); ignore (fileMenu#add_image_item @@ -2539,9 +2589,11 @@ createToplevelWindow(); (* Display the ui *) +(*JV: not useful, as Unison does not handle any signal ignore (GMain.Timeout.add 500 (fun _ -> true)); (* Hack: this allows signals such as SIGINT to be handled even when Gtk is waiting for events *) +*) GMain.Main.main () with Util.Transient(s) | Util.Fatal(s) -> fatalError s Modified: trunk/src/uimacbridge.ml =================================================================== --- trunk/src/uimacbridge.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/uimacbridge.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -261,11 +261,11 @@ let unisonRiToDetails ri = match ri.whatHappened with - Some (Util.Failed s) -> (Path.toString ri.ri.path) ^ "\n" ^ s - | _ -> (Path.toString ri.ri.path) ^ "\n" ^ (Uicommon.details2string ri.ri " ");; + Some (Util.Failed s) -> (Path.toString ri.ri.path1) ^ "\n" ^ s + | _ -> (Path.toString ri.ri.path1) ^ "\n" ^ (Uicommon.details2string ri.ri " ");; Callback.register "unisonRiToDetails" unisonRiToDetails;; -let unisonRiToPath ri = Path.toString ri.ri.path;; +let unisonRiToPath ri = Path.toString ri.ri.path1;; Callback.register "unisonRiToPath" unisonRiToPath;; let rcToString rc = @@ -410,11 +410,11 @@ Callback.register "unisonSynchronize" unisonSynchronize;; let unisonIgnorePath si = - Uicommon.addIgnorePattern (Uicommon.ignorePath si.ri.path);; + Uicommon.addIgnorePattern (Uicommon.ignorePath si.ri.path1);; let unisonIgnoreExt si = - Uicommon.addIgnorePattern (Uicommon.ignoreExt si.ri.path);; + Uicommon.addIgnorePattern (Uicommon.ignoreExt si.ri.path1);; let unisonIgnoreName si = - Uicommon.addIgnorePattern (Uicommon.ignoreName si.ri.path);; + Uicommon.addIgnorePattern (Uicommon.ignoreName si.ri.path1);; Callback.register "unisonIgnorePath" unisonIgnorePath;; Callback.register "unisonIgnoreExt" unisonIgnoreExt;; Callback.register "unisonIgnoreName" unisonIgnoreName;; @@ -428,7 +428,7 @@ let num = ref(-1) in let newI = ref None in (* FIX: we should actually test whether any prefix is now ignored *) - let keep s = not (Globals.shouldIgnore s.ri.path) in + let keep s = not (Globals.shouldIgnore s.ri.path1) in for j = 0 to (Array.length !theState - 1) do let s = !theState.(j) in if keep s then begin Modified: trunk/src/uitext.ml =================================================================== --- trunk/src/uitext.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/uitext.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -798,14 +798,17 @@ synchronizeUntilDone () end -let start _ = +let start interface = + if interface <> Uicommon.Text then + Util.msg "This Unison binary only provides the text GUI...\n"; begin try (* Just to make sure something is there... *) setWarnPrinterForInitialization(); Uicommon.uiInit (fun s -> Util.msg "%s\n%s\n" Uicommon.shortUsageMsg s; exit 1) (fun s -> Util.msg "%s" Uicommon.shortUsageMsg; exit 1) - (fun () -> if not (Prefs.read silent) + (fun () -> if Prefs.read silent then Prefs.set Trace.terse true; + if not (Prefs.read silent) then Util.msg "%s\n" (Uicommon.contactingServerMsg())) (fun () -> Some "default") (fun () -> Util.msg "%s" Uicommon.shortUsageMsg; exit 1) Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/update.ml 2009-07-19 20:07:54 UTC (rev 378) @@ -1400,15 +1400,15 @@ archive | `BadEnc -> let uiChild = - Error ("The file name is not encoded in Unicode (" - ^ Path.toString path' ^ ")") + Error ("The file name is not encoded in Unicode. (File '" + ^ Path.toString path' ^ "')") in updates := (nm, uiChild) :: !updates; archive | `BadName -> let uiChild = - Error ("The name of this Unix file is not allowed in Windows (" - ^ Path.toString path' ^ ")") + Error ("The name of this Unix file is not allowed under Windows. \ + (File '" ^ Path.toString path' ^ "')") in updates := (nm, uiChild) :: !updates; archive @@ -1541,7 +1541,10 @@ (* Compute the updates for [path] against archive. Also returns an archive, which is the old archive with time stamps updated appropriately (i.e., for those files whose contents remain - unchanged). *) + unchanged). The filenames are also updated to match the filesystem + contents. The directory permissions along the path are also + collected, in case we need to build the directory hierarchy + on one side. *) let rec buildUpdate archive fspath fullpath here path dirStamp = match Path.deconstruct path with None -> @@ -1557,9 +1560,10 @@ None -> archive | Some arch -> arch end, - ui) + ui, here, []) | Some(name, path') -> - if not (isDir fspath here) then + let info = Fileinfo.get true fspath here in + if info.Fileinfo.typ <> `DIRECTORY && info.Fileinfo.typ <> `ABSENT then let error = if Path.isEmpty here then Printf.sprintf @@ -1572,65 +1576,66 @@ the replicas" (Path.toString fullpath) (Path.toString here) in - (* FIX: We have to fail here (and in other error cases below) - rather than report an error for this path, which would be - more user friendly. Indeed, the archive is otherwise - modified in inconsistent way when the failure occurs only - on one replica (see at the end of this function). - A better solution should be not to put the archives in a - different state, but this is a lot more work. *) - raise (Util.Transient error) -(* (archive, Error error) *) + (archive, Error error, translatePathLocal fspath fullpath, []) else - let children = getChildren fspath here in let (name', status) = - try - Safelist.find (fun (name', _) -> Name.eq name name') children - with Not_found -> + if info.Fileinfo.typ = `ABSENT then (name, checkFilename name) + else + let children = getChildren fspath here in + try + Safelist.find (fun (name', _) -> Name.eq name name') children + with Not_found -> + (name, checkFilename name) in match status with - | `BadEnc -> + | `BadEnc -> raise (Util.Transient - ("The path " ^ Path.toString fullpath ^ - " is not encoded in Unicode")) - | `BadName -> + (Format.sprintf + "The filename %s in path %s is not encoded in Unicode" + (Name.toString name) (Path.toString fullpath))) + | `BadName -> raise (Util.Transient - ("The path " ^ Path.toString fullpath ^ - " is not allowed in Windows")) + (Format.sprintf + "The filename %s in path %s is not allowed under Windows" + (Name.toString name) (Path.toString fullpath))) | `Dup -> raise (Util.Transient - ("The path " ^ Path.toString fullpath ^ - " is ambiguous (i.e., the name of this path or one of its " - ^ "ancestors is the same, modulo capitalization, as another " - ^ "path in a case-sensitive filesystem, and you are " - ^ "synchronizing this filesystem with a case-insensitive " - ^ "filesystem. ")) + (Format.sprintf + "The path %s is ambiguous at filename %s (i.e., the name \ + of this path is the same, modulo capitalization, as \ + another path in a case-sensitive filesystem, and you are \ + synchronizing this filesystem with a case-insensitive \ + filesystem." + (Path.toString fullpath) (Name.toString name))) | `Ok -> - let (desc, child, otherChildren) = - match archive with - ArchiveDir (desc, children) -> - begin try - let child = NameMap.find name children in - (desc, child, NameMap.remove name children) - with Not_found -> - (desc, NoArchive, children) - end - | _ -> - (Props.dummy, NoArchive, NameMap.empty) - in - let (arch, updates) = - buildUpdate - child fspath fullpath (Path.child here name') path' dirStamp - in - (* We need to put a directory in the archive here for path - translation. This is fine because we check that there - really is a directory on both replica. - Note that we may also put NoArchive deep inside an - archive... - *) - (ArchiveDir (desc, NameMap.add name' arch otherChildren), - updates) + match archive with + ArchiveDir (desc, children) -> + let archChild = + try NameMap.find name children with Not_found -> NoArchive in + let otherChildren = NameMap.remove name children in + let (arch, updates, localPath, props) = + buildUpdate + archChild fspath fullpath (Path.child here name') path' + dirStamp + in + let children = + if arch = NoArchive then otherChildren else + NameMap.add name' arch otherChildren + in + (ArchiveDir (desc, children), updates, localPath, + if info.Fileinfo.typ = `ABSENT then [] else + info.Fileinfo.desc :: props) + | _ -> + let (arch, updates, localPath, props) = + buildUpdate + NoArchive fspath fullpath (Path.child here name') path' + dirStamp + in + assert (arch = NoArchive); + (archive, updates, localPath, + if info.Fileinfo.typ = `ABSENT then [] else + info.Fileinfo.desc :: props) (* All the predicates that may change the set of files scanned during update detection *) @@ -1675,7 +1680,8 @@ (* for the given path, find the archive and compute the list of update items; as a side effect, update the local archive w.r.t. time-stamps for unchanged files *) -let findLocal fspath pathList: Common.updateItem list = +let findLocal fspath pathList: + (Path.local * Common.updateItem * Props.t list) list = debug (fun() -> Util.msg "findLocal %s\n" (Fspath.toDebugString fspath)); addHashToTempNames fspath; (* Maybe we should remember the device number where the root lives at @@ -1694,12 +1700,12 @@ Safelist.fold_right (fun path (arch, upd) -> if Globals.shouldIgnore path then - (arch, NoUpdates :: upd) + (arch, (translatePathLocal fspath path, NoUpdates, []) :: upd) else - let (arch', ui) = + let (arch', ui, localPath, props) = buildUpdate arch fspath path Path.empty path dirStamp in - arch', ui :: upd) + arch', (localPath, ui, props) :: upd) pathList (archive, []) in (* @@ -1732,8 +1738,7 @@ let t = Trace.startTimer "Collecting changes" in Globals.allRootsMapWithWaitingAction (fun r -> debug (fun() -> Util.msg "findOnRoot %s\n" (root2string r)); - findOnRoot r pathList >>= fun updates -> - Lwt.return (List.combine pathList updates)) + findOnRoot r pathList) (fun (host, _) -> begin match host with Remote _ -> Uutil.showUpdateStatus ""; @@ -1746,8 +1751,8 @@ Safelist.map (fun r -> match r with - [(p1, u1); (p2, u2)] -> (p1,u1,p2,u2) - | _ -> assert false) + [i1; i2] -> (i1, i2) + | _ -> assert false) (Safelist.transpose updates) in Trace.status ""; @@ -2230,3 +2235,9 @@ f fspath path fp | _ -> () + +(* Hook for filesystem auto-detection (not implemented yet) *) +let inspectFilesystem = + Remote.registerRootCmd + "inspectFilesystem" + (fun _ -> Lwt.return Proplist.empty) Modified: trunk/src/update.mli =================================================================== --- trunk/src/update.mli 2009-07-17 21:41:58 UTC (rev 377) +++ trunk/src/update.mli 2009-07-19 20:07:54 UTC (rev 378) @@ -20,7 +20,8 @@ (* Structures describing dirty files/dirs (1 per path given in the -path preference) *) val findUpdates : - unit -> (Path.t * Common.updateItem * Path.t * Common.updateItem) list + unit -> ((Path.local * Common.updateItem * Props.t list) * + (Path.local * Common.updateItem * Props.t list)) list (* Take a tree of equal update contents and update the archive accordingly. *) val markEqual : From Jerome.Vouillon at pps.jussieu.fr Mon Jul 20 06:44:35 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 20 Jul 2009 12:44:35 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <4A5E0045.8070301@strank.info> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> Message-ID: <20090720104435.GA17390@pps.jussieu.fr> On Wed, Jul 15, 2009 at 06:13:57PM +0200, Stefan Rank wrote: > on 2009-07-15 17:39 Alan Schmitt said the following: > > I thought I fixed this a while ago (revision 358 where I > > incorporated the patch from Martin von Gagern). > > Indeed, the build just now worked out of the box, both text and gui, > after a make clean. > Sorry for the noise. > > Still I had errors when first compiling that looked very much like > 'wrong SDK'... > but I guess they must have been related to ocaml 3.11 then. I managed to > build a gui version with 3.11 by applying the above changes, but I had > to downgrade to version 3.10.2 anyway to avoid the 'child process' bug > in 3.11. It would be great if someone could try with Ocaml 3.11.1 (where this bug is fixed) and report back. -- Jerome From bcpierce at cis.upenn.edu Mon Jul 20 10:06:20 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 20 Jul 2009 10:06:20 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090720104435.GA17390@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> Message-ID: <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> > It would be great if someone could try with Ocaml 3.11.1 (where this > bug is fixed) and report back. I tried again to get 3.11.1 working on my laptop, but I'm not quite there yet. Any idea what's wrong? (This is with a newly compiled OCaml.) - B ~/current/unison/trunk/src> make ocamlc -o mkProjectInfo unix.cma str.cma mkProjectInfo.ml ./mkProjectInfo > Makefile.ProjectInfo UISTYLE = macnew Building for Unix NATIVE = true THREADS = true STATIC = false OSTYPE = OSARCH = osx ocamlopt: ubase/rx.mli ---> ubase/rx.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/rx.mli ocamlopt: ubase/rx.ml ---> ubase/rx.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/rx.ml ocamlopt: unicode_tables.ml ---> unicode_tables.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ unicode_tables.ml ocamlopt: unicode.mli ---> unicode.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ unicode.mli ocamlopt: unicode.ml ---> unicode.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ unicode.ml ocamlopt: bytearray.mli ---> bytearray.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ bytearray.mli ocamlopt: bytearray.ml ---> bytearray.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ bytearray.ml ocamlopt: system/system_generic.ml ---> system/system_generic.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ system/system_generic.ml ocamlopt: system/generic/system_impl.ml ---> system/generic/ system_impl.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ system/generic/system_impl.ml ocamlc: system/system_intf.ml ---> system/system_intf.cmo ocamlc -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ system/system_intf.ml ocamlopt: system.mli ---> system.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ system.mli ocamlopt: system.ml ---> system.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ system.ml echo 'let myName = "'unison'";;' > ubase/projectInfo.ml echo 'let myVersion = "'2.37.1'";;' >> ubase/projectInfo.ml echo 'let myMajorVersion = "'2.37'";;' >> ubase/projectInfo.ml ocamlopt: ubase/projectInfo.ml ---> ubase/projectInfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/projectInfo.ml ocamlopt: ubase/myMap.mli ---> ubase/myMap.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/myMap.mli ocamlopt: ubase/myMap.ml ---> ubase/myMap.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/myMap.ml ocamlopt: ubase/safelist.mli ---> ubase/safelist.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/safelist.mli ocamlopt: ubase/safelist.ml ---> ubase/safelist.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/safelist.ml ocamlopt: ubase/uprintf.mli ---> ubase/uprintf.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uprintf.mli ocamlopt: ubase/uprintf.ml ---> ubase/uprintf.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uprintf.ml ocamlopt: ubase/util.mli ---> ubase/util.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/util.mli ocamlopt: ubase/util.ml ---> ubase/util.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/util.ml ocamlopt: ubase/uarg.mli ---> ubase/uarg.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uarg.mli ocamlopt: ubase/uarg.ml ---> ubase/uarg.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uarg.ml ocamlopt: ubase/prefs.mli ---> ubase/prefs.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/prefs.mli ocamlopt: ubase/prefs.ml ---> ubase/prefs.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/prefs.ml ocamlopt: ubase/trace.mli ---> ubase/trace.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/trace.mli ocamlopt: ubase/trace.ml ---> ubase/trace.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/trace.ml ocamlopt: ubase/proplist.mli ---> ubase/proplist.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/proplist.mli ocamlopt: ubase/proplist.ml ---> ubase/proplist.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/proplist.ml ocamlopt: lwt/pqueue.mli ---> lwt/pqueue.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/pqueue.mli ocamlopt: lwt/pqueue.ml ---> lwt/pqueue.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/pqueue.ml ocamlopt: lwt/lwt.mli ---> lwt/lwt.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt.mli ocamlopt: lwt/lwt.ml ---> lwt/lwt.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt.ml ocamlopt: lwt/lwt_util.mli ---> lwt/lwt_util.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_util.mli ocamlopt: lwt/lwt_util.ml ---> lwt/lwt_util.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_util.ml ocamlopt: lwt/lwt_unix.mli ---> lwt/lwt_unix.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_unix.mli ocamlopt: lwt/lwt_unix.ml ---> lwt/lwt_unix.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_unix.ml ocamlopt: case.mli ---> case.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ case.mli ocamlopt: case.ml ---> case.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ case.ml ocamlopt: pred.mli ---> pred.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ pred.mli ocamlopt: pred.ml ---> pred.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ pred.ml ocamlopt: uutil.mli ---> uutil.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uutil.mli ocamlopt: uutil.ml ---> uutil.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uutil.ml ocamlopt: fileutil.mli ---> fileutil.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fileutil.mli ocamlopt: fileutil.ml ---> fileutil.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fileutil.ml ocamlopt: name.mli ---> name.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ name.mli ocamlopt: name.ml ---> name.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ name.ml ocamlopt: path.mli ---> path.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ path.mli ocamlopt: path.ml ---> path.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ path.ml ocamlopt: fspath.mli ---> fspath.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fspath.mli ocamlopt: fspath.ml ---> fspath.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fspath.ml ocamlopt: fs.mli ---> fs.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fs.mli ocamlopt: fs.ml ---> fs.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fs.ml ocamlopt: fingerprint.mli ---> fingerprint.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fingerprint.mli ocamlopt: fingerprint.ml ---> fingerprint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fingerprint.ml ocamlopt: abort.mli ---> abort.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ abort.mli ocamlopt: abort.ml ---> abort.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ abort.ml ocamlopt: osx.mli ---> osx.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ osx.mli ocamlopt: osx.ml ---> osx.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ osx.ml ocamlopt: external.mli ---> external.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ external.mli ocamlopt: external.ml ---> external.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ external.ml ocamlopt: props.mli ---> props.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ props.mli ocamlopt: props.ml ---> props.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ props.ml ocamlopt: fileinfo.mli ---> fileinfo.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fileinfo.mli ocamlopt: fileinfo.ml ---> fileinfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fileinfo.ml ocamlopt: os.mli ---> os.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ os.mli ocamlopt: os.ml ---> os.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ os.ml ocamlopt: lock.mli ---> lock.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lock.mli ocamlopt: lock.ml ---> lock.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ lock.ml ocamlopt: clroot.mli ---> clroot.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ clroot.mli ocamlopt: clroot.ml ---> clroot.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ clroot.ml ocamlopt: common.mli ---> common.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ common.mli ocamlopt: common.ml ---> common.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ common.ml ocamlopt: tree.mli ---> tree.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ tree.mli ocamlopt: tree.ml ---> tree.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ tree.ml ocamlopt: checksum.mli ---> checksum.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ checksum.mli ocamlopt: checksum.ml ---> checksum.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ checksum.ml ocamlopt: terminal.mli ---> terminal.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ terminal.mli ocamlopt: terminal.ml ---> terminal.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ terminal.ml ocamlopt: transfer.mli ---> transfer.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ transfer.mli ocamlopt: transfer.ml ---> transfer.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ transfer.ml ocamlopt: xferhint.mli ---> xferhint.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ xferhint.mli ocamlopt: xferhint.ml ---> xferhint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ xferhint.ml ocamlopt: remote.mli ---> remote.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ remote.mli ocamlopt: remote.ml ---> remote.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ remote.ml ocamlopt: globals.mli ---> globals.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ globals.mli ocamlopt: globals.ml ---> globals.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ globals.ml ocamlopt: update.mli ---> update.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ update.mli ocamlopt: update.ml ---> update.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ update.ml ocamlopt: copy.mli ---> copy.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ copy.mli ocamlopt: copy.ml ---> copy.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ copy.ml ocamlopt: stasher.mli ---> stasher.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ stasher.mli ocamlopt: stasher.ml ---> stasher.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ stasher.ml ocamlopt: files.mli ---> files.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ files.mli ocamlopt: files.ml ---> files.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ files.ml ocamlopt: sortri.mli ---> sortri.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ sortri.mli ocamlopt: sortri.ml ---> sortri.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ sortri.ml ocamlopt: recon.mli ---> recon.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ recon.mli ocamlopt: recon.ml ---> recon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ recon.ml ocamlopt: transport.mli ---> transport.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ transport.mli ocamlopt: transport.ml ---> transport.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ transport.ml ocamlopt: strings.mli ---> strings.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ strings.mli ocamlopt: strings.ml ---> strings.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ strings.ml ocamlopt: uicommon.mli ---> uicommon.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uicommon.mli ocamlopt: uicommon.ml ---> uicommon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uicommon.ml ocamlopt: uitext.mli ---> uitext.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uitext.mli ocamlopt: uitext.ml ---> uitext.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uitext.ml ocamlopt: test.mli ---> test.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ test.mli ocamlopt: test.ml ---> test.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ test.ml ocamlopt: main.ml ---> main.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ main.ml ocamlopt: uimacbridgenew.ml ---> uimacbridgenew.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uimacbridgenew.ml ocamlopt: osxsupport.c ---> osxsupport.o ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -ccopt -o -ccopt /Users/bcpierce/current/ unison/trunk/src/osxsupport.o -c /Users/bcpierce/current/unison/trunk/ src/osxsupport.c ocamlopt: pty.c ---> pty.o ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -ccopt -o -ccopt /Users/bcpierce/current/ unison/trunk/src/pty.o -c /Users/bcpierce/current/unison/trunk/src/pty.c ocamlopt: bytearray_stubs.c ---> bytearray_stubs.o ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -ccopt -o -ccopt /Users/bcpierce/current/ unison/trunk/src/bytearray_stubs.o -c /Users/bcpierce/current/unison/ trunk/src/bytearray_stubs.c Linking unison-blob.o ocamlopt -output-obj -verbose -I lwt -I ubase -I system -thread -I system/generic -ccopt -mmacosx-version-min=10.4 -o u-b.o unix.cmxa str.cmxa bigarray.cmxa threads.cmxa ubase/rx.cmx unicode_tables.cmx unicode.cmx bytearray.cmx system/system_generic.cmx system/generic/ system_impl.cmx system.cmx ubase/projectInfo.cmx ubase/myMap.cmx ubase/ safelist.cmx ubase/uprintf.cmx ubase/util.cmx ubase/uarg.cmx ubase/ prefs.cmx ubase/trace.cmx ubase/proplist.cmx lwt/pqueue.cmx lwt/ lwt.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx case.cmx pred.cmx uutil.cmx fileutil.cmx name.cmx path.cmx fspath.cmx fs.cmx fingerprint.cmx abort.cmx osx.cmx external.cmx props.cmx fileinfo.cmx os.cmx lock.cmx clroot.cmx common.cmx tree.cmx checksum.cmx terminal.cmx transfer.cmx xferhint.cmx remote.cmx globals.cmx update.cmx copy.cmx stasher.cmx files.cmx sortri.cmx recon.cmx transport.cmx strings.cmx uicommon.cmx uitext.cmx test.cmx main.cmx uimacbridgenew.cmx + as -o '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartup372e93.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Tmp-/camlstartup4f86bf.s' + ld -r -o 'u-b.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartup372e93.o' 'uimacbridgenew.o' 'main.o' 'test.o' 'uitext.o' 'uicommon.o' 'strings.o' 'transport.o' 'recon.o' 'sortri.o' 'files.o' 'stasher.o' 'copy.o' 'update.o' 'globals.o' 'remote.o' 'xferhint.o' 'transfer.o' 'terminal.o' 'checksum.o' 'tree.o' 'common.o' 'clroot.o' 'lock.o' 'os.o' 'fileinfo.o' 'props.o' 'external.o' 'osx.o' 'abort.o' 'fingerprint.o' 'fs.o' 'fspath.o' 'path.o' 'name.o' 'fileutil.o' 'uutil.o' 'pred.o' 'case.o' 'lwt/lwt_unix.o' 'lwt/lwt_util.o' 'lwt/ lwt.o' 'lwt/pqueue.o' 'ubase/proplist.o' 'ubase/trace.o' 'ubase/ prefs.o' 'ubase/uarg.o' 'ubase/util.o' 'ubase/uprintf.o' 'ubase/ safelist.o' 'ubase/myMap.o' 'ubase/projectInfo.o' 'system.o' 'system/ generic/system_impl.o' 'system/system_generic.o' 'bytearray.o' 'unicode.o' 'unicode_tables.o' 'ubase/rx.o' '/usr/local/lib/ocaml/ threads/threads.a' '/usr/local/lib/ocaml/bigarray.a' '/usr/local/lib/ ocaml/str.a' '/usr/local/lib/ocaml/unix.a' '/usr/local/lib/ocaml/ stdlib.a' ld -r -o unison-blob.o u-b.o osxsupport.o pty.o bytearray_stubs.o rm -f u-b.o (cd uimacnew; xcodebuild OCAMLLIBDIR="/usr/local/lib/ocaml" SYMROOT=build) === BUILDING AGGREGATE TARGET Create ExternalSettings WITH THE DEFAULT CONFIGURATION (Default) === Checking Dependencies... The file ???ExternalSettings.xcconfig??? does not exist. (/Users/ bcpierce/current/unison/trunk/src/uimacnew/ExternalSettings.xcconfig) PhaseScriptExecution "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ Script-2A124E7E0DE1C4BE00524237.sh" cd /Users/bcpierce/current/unison/trunk/src/uimacnew setenv ACTION build setenv ALWAYS_SEARCH_USER_PATHS YES setenv APPLE_INTERNAL_DEVELOPER_DIR /AppleInternal/Developer setenv APPLE_INTERNAL_DIR /AppleInternal setenv APPLE_INTERNAL_DOCUMENTATION_DIR /AppleInternal/ Documentation setenv APPLE_INTERNAL_LIBRARY_DIR /AppleInternal/Library setenv APPLE_INTERNAL_TOOLS /AppleInternal/Developer/Tools setenv ARCHS i386 setenv BUILD_COMPONENTS "headers build" setenv BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_STYLE Default setenv BUILD_VARIANTS normal setenv BUILT_PRODUCTS_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default setenv CACHE_ROOT /Library/Caches/com.apple.Xcode.501 setenv CCHROOT /Library/Caches/com.apple.Xcode.501 setenv CHMOD /bin/chmod setenv CHOWN /usr/sbin/chown setenv CLASS_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ JavaClasses" setenv CLEAN_PRECOMPS YES setenv COMMAND_MODE legacy setenv COMPOSITE_SDK_DIRS /Library/Caches/com.apple.Xcode.501/ CompositeSDKs setenv CONFIGURATION Default setenv CONFIGURATION_BUILD_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv CONFIGURATION_TEMP_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default setenv COPY_PHASE_STRIP YES setenv COPY_RESOURCES_FROM_STATIC_FRAMEWORKS YES setenv CP /bin/cp setenv CURRENT_ARCH i386 setenv CURRENT_VARIANT normal setenv DEBUGGING_SYMBOLS YES setenv DEBUG_INFORMATION_FORMAT dwarf setenv DEPLOYMENT_LOCATION NO setenv DERIVED_FILES_DIR "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/DerivedSources" setenv DERIVED_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ DerivedSources" setenv DERIVED_SOURCES_DIR "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/DerivedSources" setenv DEVELOPER_APPLICATIONS_DIR /Developer/Applications setenv DEVELOPER_BIN_DIR /Developer/usr/bin setenv DEVELOPER_DIR /Developer setenv DEVELOPER_FRAMEWORKS_DIR /Developer/Library/Frameworks setenv DEVELOPER_FRAMEWORKS_DIR_QUOTED "\"/Developer/Library/ Frameworks\"" setenv DEVELOPER_LIBRARY_DIR /Developer/Library setenv DEVELOPER_SDK_DIR /Developer/SDKs setenv DEVELOPER_TOOLS_DIR /Developer/Tools setenv DEVELOPER_USR_DIR /Developer/usr setenv DEVELOPMENT_LANGUAGE English setenv DSTROOT /tmp/uimacnew.dst setenv DWARF_DSYM_FILE_NAME .dSYM setenv DWARF_DSYM_FOLDER_PATH /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv ENABLE_HEADER_DEPENDENCIES YES setenv EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES "*.nib *.lproj *.framework *.gch (*) CVS .svn *.xcodeproj *.xcode *.pbproj *.pbxproj" setenv FIXED_FILES_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ FixedFiles" setenv FRAMEWORK_VERSION A setenv GCC_PFE_FILE_C_DIALECTS "c objective-c c++ objective-c++" setenv GCC_TREAT_WARNINGS_AS_ERRORS NO setenv GCC_VERSION 4.0 setenv GENERATE_PKGINFO_FILE NO setenv GENERATE_PROFILING_CODE NO setenv GID 501 setenv GROUP bcpierce setenv HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT YES setenv HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES YES setenv HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS YES setenv HEADERMAP_INCLUDES_PROJECT_HEADERS YES setenv INFOPLIST_EXPAND_BUILD_SETTINGS YES setenv INSTALL_DIR /tmp/uimacnew.dst setenv INSTALL_GROUP bcpierce setenv INSTALL_MODE_FLAG a-w,a+rX setenv INSTALL_OWNER bcpierce setenv INSTALL_ROOT /tmp/uimacnew.dst setenv JAVAC_DEFAULT_FLAGS "-J-Xms64m -J-XX:NewSize=4M -J- Dfile.encoding=UTF8" setenv JAVA_APP_STUB /System/Library/Frameworks/JavaVM.framework/ Resources/MacOS/JavaApplicationStub setenv JAVA_ARCHIVE_CLASSES YES setenv JAVA_ARCHIVE_TYPE JAR setenv JAVA_COMPILER /usr/bin/javac setenv JAVA_FRAMEWORK_RESOURCES_DIRS Resources setenv JAVA_JAR_FLAGS cv setenv JAVA_SOURCE_SUBDIR . setenv JAVA_USE_DEPENDENCIES YES setenv JAVA_ZIP_FLAGS -urg setenv JIKES_DEFAULT_FLAGS "+E +OLDCSO" setenv LEX /Developer/usr/bin/lex setenv LINK_FILE_LIST_normal_i386 setenv LOCAL_ADMIN_APPS_DIR /Applications/Utilities setenv LOCAL_APPS_DIR /Applications setenv LOCAL_DEVELOPER_DIR /Library/Developer setenv LOCAL_LIBRARY_DIR /Library setenv MAC_OS_X_VERSION_ACTUAL 1057 setenv MAC_OS_X_VERSION_MAJOR 1050 setenv MAC_OS_X_VERSION_MINOR 0507 setenv NATIVE_ARCH i386 setenv NATIVE_ARCH_32_BIT i386 setenv NATIVE_ARCH_64_BIT x86_64 setenv NATIVE_ARCH_ACTUAL i386 setenv NO_COMMON YES setenv OBJECT_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ Objects" setenv OBJECT_FILE_DIR_normal "/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/Objects-normal" setenv OBJROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv OCAMLLIBDIR /usr/local/lib/ocaml setenv OPTIMIZATION_LEVEL 0 setenv OS MACOS setenv OSAC /usr/bin/osacompile setenv PASCAL_STRINGS YES setenv PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES "/usr/ include /usr/local/include /System/Library/Frameworks /System/Library/ PrivateFrameworks /Developer/Headers" setenv PKGINFO_FILE_PATH "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/PkgInfo" setenv PREBINDING YES setenv PRECOMP_DESTINATION_DIR "/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/PrefixHeaders" setenv PRODUCT_NAME "Create ExternalSettings" setenv PRODUCT_SETTINGS_PATH setenv PROJECT uimacnew setenv PROJECT_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/DerivedSources setenv PROJECT_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv PROJECT_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/uimacnew.xcodeproj setenv PROJECT_NAME uimacnew setenv PROJECT_TEMP_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build setenv RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS YES setenv REMOVE_CVS_FROM_RESOURCES YES setenv REMOVE_SVN_FROM_RESOURCES YES setenv REZ_COLLECTOR_DIR "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ResourceManagerResources" setenv REZ_OBJECTS_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ ResourceManagerResources/Objects" setenv SCRIPT_INPUT_FILE_COUNT 0 setenv SCRIPT_OUTPUT_FILE_COUNT 0 setenv SDKROOT /Developer/SDKs/MacOSX10.4u.sdk setenv SED /usr/bin/sed setenv SET_DIR_MODE_OWNER_GROUP YES setenv SET_FILE_MODE_OWNER_GROUP NO setenv SHARED_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/DerivedSources setenv SHARED_PRECOMPS_DIR /Library/Caches/com.apple.Xcode.501/ SharedPrecompiledHeaders setenv SKIP_INSTALL YES setenv SOURCE_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv SRCROOT /Users/bcpierce/current/unison/trunk/src/uimacnew setenv STRIP_INSTALLED_PRODUCT YES setenv SYMBOL_REPOSITORY_DIR "/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/SymbolRepositories" setenv SYMROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv SYSTEM_ADMIN_APPS_DIR /Applications/Utilities setenv SYSTEM_APPS_DIR /Applications setenv SYSTEM_CORE_SERVICES_DIR /System/Library/CoreServices setenv SYSTEM_DEMOS_DIR /Applications/Extras setenv SYSTEM_DEVELOPER_APPS_DIR /Developer/Applications setenv SYSTEM_DEVELOPER_BIN_DIR /Developer/usr/bin setenv SYSTEM_DEVELOPER_DEMOS_DIR "/Developer/Applications/ Utilities/Built Examples" setenv SYSTEM_DEVELOPER_DIR /Developer setenv SYSTEM_DEVELOPER_DOC_DIR "/Developer/ADC Reference Library" setenv SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR "/Developer/ Applications/Graphics Tools" setenv SYSTEM_DEVELOPER_JAVA_TOOLS_DIR "/Developer/Applications/ Java Tools" setenv SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR "/Developer/ Applications/Performance Tools" setenv SYSTEM_DEVELOPER_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes" setenv SYSTEM_DEVELOPER_TOOLS /Developer/Tools setenv SYSTEM_DEVELOPER_TOOLS_DOC_DIR "/Developer/ADC Reference Library/documentation/DeveloperTools" setenv SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes/DeveloperTools" setenv SYSTEM_DEVELOPER_USR_DIR /Developer/usr setenv SYSTEM_DEVELOPER_UTILITIES_DIR /Developer/Applications/ Utilities setenv SYSTEM_DOCUMENTATION_DIR /Library/Documentation setenv SYSTEM_LIBRARY_DIR /System/Library setenv TARGETNAME "Create ExternalSettings" setenv TARGET_BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default setenv TARGET_NAME "Create ExternalSettings" setenv TARGET_TEMP_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_FILES_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv UID 501 setenv UNSTRIPPED_PRODUCT NO setenv USER bcpierce setenv USER_APPS_DIR /Users/bcpierce/Applications setenv USER_HEADER_SEARCH_PATHS /usr/local/lib/ocaml setenv USER_LIBRARY_DIR /Users/bcpierce/Library setenv USE_DYNAMIC_NO_PIC YES setenv VALID_ARCHS "ppc64 ppc7400 ppc970 i386 x86_64 ppc" setenv VERBOSE_PBXCP NO setenv VERSION_INFO_BUILDER bcpierce setenv VERSION_INFO_FILE "Create ExternalSettings_vers.c" setenv VERSION_INFO_STRING "\"@(#)PROGRAM:Create ExternalSettings PROJECT:uimacnew-\"" setenv XCODE_APP_SUPPORT_DIR /Developer/Library/Xcode setenv XCODE_VERSION_ACTUAL 0300 setenv XCODE_VERSION_MAJOR 0300 setenv YACC /Developer/usr/bin/yacc /bin/sh -c "\"/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/Create ExternalSettings.build/ Script-2A124E7E0DE1C4BE00524237.sh\"" === BUILDING NATIVE TARGET uimac WITH THE DEFAULT CONFIGURATION (Default) === Checking Dependencies... The file ???ExternalSettings.xcconfig??? does not exist. (/Users/ bcpierce/current/unison/trunk/src/uimacnew/ExternalSettings.xcconfig) Processing /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Info.plist Info.plist mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Users/bcpierce/current/ unison/trunk/src/uimacnew/Info.plist -genpkginfo /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ PkgInfo -expandbuildsettings -o /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default/Unison.app/Contents/Info.plist PhaseScriptExecution /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/uimac.build/ Script-2E282CBA0D9AE17300439D01.sh cd /Users/bcpierce/current/unison/trunk/src/uimacnew setenv ACTION build setenv ALWAYS_SEARCH_USER_PATHS YES setenv APPLE_INTERNAL_DEVELOPER_DIR /AppleInternal/Developer setenv APPLE_INTERNAL_DIR /AppleInternal setenv APPLE_INTERNAL_DOCUMENTATION_DIR /AppleInternal/ Documentation setenv APPLE_INTERNAL_LIBRARY_DIR /AppleInternal/Library setenv APPLE_INTERNAL_TOOLS /AppleInternal/Developer/Tools setenv ARCHS i386 setenv BUILD_COMPONENTS "headers build" setenv BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_STYLE Default setenv BUILD_VARIANTS normal setenv BUILT_PRODUCTS_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default setenv CACHE_ROOT /Library/Caches/com.apple.Xcode.501 setenv CCHROOT /Library/Caches/com.apple.Xcode.501 setenv CHMOD /bin/chmod setenv CHOWN /usr/sbin/chown setenv CLASS_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/JavaClasses setenv CLEAN_PRECOMPS YES setenv COMMAND_MODE legacy setenv COMPOSITE_SDK_DIRS /Library/Caches/com.apple.Xcode.501/ CompositeSDKs setenv CONFIGURATION Default setenv CONFIGURATION_BUILD_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv CONFIGURATION_TEMP_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default setenv CONTENTS_FOLDER_PATH Unison.app/Contents setenv COPY_PHASE_STRIP YES setenv COPY_RESOURCES_FROM_STATIC_FRAMEWORKS YES setenv CP /bin/cp setenv CURRENT_ARCH i386 setenv CURRENT_VARIANT normal setenv DEBUGGING_SYMBOLS YES setenv DEBUG_INFORMATION_FORMAT dwarf setenv DEPLOYMENT_LOCATION NO setenv DERIVED_FILES_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources setenv DERIVED_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources setenv DERIVED_SOURCES_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources setenv DEVELOPER_APPLICATIONS_DIR /Developer/Applications setenv DEVELOPER_BIN_DIR /Developer/usr/bin setenv DEVELOPER_DIR /Developer setenv DEVELOPER_FRAMEWORKS_DIR /Developer/Library/Frameworks setenv DEVELOPER_FRAMEWORKS_DIR_QUOTED "\"/Developer/Library/ Frameworks\"" setenv DEVELOPER_LIBRARY_DIR /Developer/Library setenv DEVELOPER_SDK_DIR /Developer/SDKs setenv DEVELOPER_TOOLS_DIR /Developer/Tools setenv DEVELOPER_USR_DIR /Developer/usr setenv DEVELOPMENT_LANGUAGE English setenv DOCUMENTATION_FOLDER_PATH /Documentation setenv DSTROOT /tmp/uimacnew.dst setenv DWARF_DSYM_FILE_NAME Unison.app.dSYM setenv DWARF_DSYM_FOLDER_PATH /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv ENABLE_HEADER_DEPENDENCIES YES setenv EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES "*.nib *.lproj *.framework *.gch (*) CVS .svn *.xcodeproj *.xcode *.pbproj *.pbxproj" setenv EXECUTABLES_FOLDER_PATH Unison.app/Contents/Executables setenv EXECUTABLE_FOLDER_PATH Unison.app/Contents/MacOS setenv EXECUTABLE_NAME Unison setenv EXECUTABLE_PATH Unison.app/Contents/MacOS/Unison setenv FIXED_FILES_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/FixedFiles setenv FRAMEWORKS_FOLDER_PATH Unison.app/Contents/Frameworks setenv FRAMEWORK_FLAG_PREFIX -framework setenv FRAMEWORK_SEARCH_PATHS " /Users/bcpierce/current/unison/ trunk/src/uimacnew" setenv FRAMEWORK_VERSION A setenv FULL_PRODUCT_NAME Unison.app setenv GCC_DYNAMIC_NO_PIC YES setenv GCC_ENABLE_OBJC_EXCEPTIONS YES setenv GCC_INLINES_ARE_PRIVATE_EXTERN YES setenv GCC_PFE_FILE_C_DIALECTS "c objective-c c++ objective-c++" setenv GCC_PRECOMPILE_PREFIX_HEADER YES setenv GCC_SYMBOLS_PRIVATE_EXTERN YES setenv GCC_TREAT_WARNINGS_AS_ERRORS NO setenv GCC_VERSION 4.0 setenv GENERATE_PKGINFO_FILE YES setenv GENERATE_PROFILING_CODE NO setenv GID 501 setenv GROUP bcpierce setenv HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT YES setenv HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES YES setenv HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS YES setenv HEADERMAP_INCLUDES_PROJECT_HEADERS YES setenv INFOPLIST_EXPAND_BUILD_SETTINGS YES setenv INFOPLIST_FILE Info.plist setenv INFOPLIST_PATH Unison.app/Contents/Info.plist setenv INFOSTRINGS_PATH /InfoPlist.strings setenv INSTALL_DIR /tmp/uimacnew.dst/Users/bcpierce/Applications setenv INSTALL_GROUP bcpierce setenv INSTALL_MODE_FLAG a-w,a+rX setenv INSTALL_OWNER bcpierce setenv INSTALL_PATH /Users/bcpierce/Applications setenv INSTALL_ROOT /tmp/uimacnew.dst setenv JAVAC_DEFAULT_FLAGS "-J-Xms64m -J-XX:NewSize=4M -J- Dfile.encoding=UTF8" setenv JAVA_APP_STUB /System/Library/Frameworks/JavaVM.framework/ Resources/MacOS/JavaApplicationStub setenv JAVA_ARCHIVE_CLASSES YES setenv JAVA_ARCHIVE_TYPE JAR setenv JAVA_COMPILER /usr/bin/javac setenv JAVA_FOLDER_PATH Unison.app/Contents/Resources/Java setenv JAVA_FRAMEWORK_RESOURCES_DIRS Resources setenv JAVA_JAR_FLAGS cv setenv JAVA_SOURCE_SUBDIR . setenv JAVA_USE_DEPENDENCIES YES setenv JAVA_ZIP_FLAGS -urg setenv JIKES_DEFAULT_FLAGS "+E +OLDCSO" setenv LEX /Developer/usr/bin/lex setenv LIBRARY_FLAG_NOSPACE YES setenv LIBRARY_FLAG_PREFIX -l setenv LINK_FILE_LIST_normal_i386 /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal/i386/Unison.LinkFileList setenv LOCAL_ADMIN_APPS_DIR /Applications/Utilities setenv LOCAL_APPS_DIR /Applications setenv LOCAL_DEVELOPER_DIR /Library/Developer setenv LOCAL_LIBRARY_DIR /Library setenv MACH_O_TYPE mh_execute setenv MAC_OS_X_VERSION_ACTUAL 1057 setenv MAC_OS_X_VERSION_MAJOR 1050 setenv MAC_OS_X_VERSION_MINOR 0507 setenv NATIVE_ARCH i386 setenv NATIVE_ARCH_32_BIT i386 setenv NATIVE_ARCH_64_BIT x86_64 setenv NATIVE_ARCH_ACTUAL i386 setenv NO_COMMON YES setenv OBJECT_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/Objects setenv OBJECT_FILE_DIR_normal /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal setenv OBJROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv OCAMLLIBDIR /usr/local/lib/ocaml setenv OPTIMIZATION_LEVEL 0 setenv OS MACOS setenv OSAC /usr/bin/osacompile setenv OTHER_LDFLAGS "-L/usr/local/lib/ocaml -lunix -lthreadsnat - lstr -lbigarray -lasmrun" setenv PACKAGE_TYPE com.apple.package-type.wrapper.application setenv PASCAL_STRINGS YES setenv PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES "/usr/ include /usr/local/include /System/Library/Frameworks /System/Library/ PrivateFrameworks /Developer/Headers" setenv PBDEVELOPMENTPLIST_PATH Unison.app/Contents/ pbdevelopment.plist setenv PFE_FILE_C_DIALECTS objective-c setenv PKGINFO_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/PkgInfo setenv PKGINFO_PATH Unison.app/Contents/PkgInfo setenv PLUGINS_FOLDER_PATH Unison.app/Contents/PlugIns setenv PREBINDING NO setenv PRECOMP_DESTINATION_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ PrefixHeaders setenv PRIVATE_HEADERS_FOLDER_PATH Unison.app/Contents/ PrivateHeaders setenv PRODUCT_NAME Unison setenv PRODUCT_SETTINGS_PATH /Users/bcpierce/current/unison/trunk/ src/uimacnew/Info.plist setenv PRODUCT_TYPE com.apple.product-type.application setenv PROJECT uimacnew setenv PROJECT_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/DerivedSources setenv PROJECT_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv PROJECT_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/uimacnew.xcodeproj setenv PROJECT_NAME uimacnew setenv PROJECT_TEMP_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build setenv PUBLIC_HEADERS_FOLDER_PATH Unison.app/Contents/Headers setenv RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS YES setenv REMOVE_CVS_FROM_RESOURCES YES setenv REMOVE_SVN_FROM_RESOURCES YES setenv REZ_COLLECTOR_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/ ResourceManagerResources setenv REZ_OBJECTS_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/ ResourceManagerResources/Objects setenv SCRIPTS_FOLDER_PATH Unison.app/Contents/Resources/Scripts setenv SCRIPT_INPUT_FILE_COUNT 0 setenv SCRIPT_OUTPUT_FILE_COUNT 0 setenv SDKROOT /Developer/SDKs/MacOSX10.4u.sdk setenv SED /usr/bin/sed setenv SET_DIR_MODE_OWNER_GROUP YES setenv SET_FILE_MODE_OWNER_GROUP NO setenv SHARED_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/DerivedSources setenv SHARED_FRAMEWORKS_FOLDER_PATH Unison.app/Contents/ SharedFrameworks setenv SHARED_PRECOMPS_DIR /Library/Caches/com.apple.Xcode.501/ SharedPrecompiledHeaders setenv SHARED_SUPPORT_FOLDER_PATH Unison.app/Contents/SharedSupport setenv SOURCE_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv SRCROOT /Users/bcpierce/current/unison/trunk/src/uimacnew setenv STRIP_INSTALLED_PRODUCT YES setenv STRIP_STYLE all setenv SYMBOL_REPOSITORY_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/SymbolRepositories setenv SYMROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv SYSTEM_ADMIN_APPS_DIR /Applications/Utilities setenv SYSTEM_APPS_DIR /Applications setenv SYSTEM_CORE_SERVICES_DIR /System/Library/CoreServices setenv SYSTEM_DEMOS_DIR /Applications/Extras setenv SYSTEM_DEVELOPER_APPS_DIR /Developer/Applications setenv SYSTEM_DEVELOPER_BIN_DIR /Developer/usr/bin setenv SYSTEM_DEVELOPER_DEMOS_DIR "/Developer/Applications/ Utilities/Built Examples" setenv SYSTEM_DEVELOPER_DIR /Developer setenv SYSTEM_DEVELOPER_DOC_DIR "/Developer/ADC Reference Library" setenv SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR "/Developer/ Applications/Graphics Tools" setenv SYSTEM_DEVELOPER_JAVA_TOOLS_DIR "/Developer/Applications/ Java Tools" setenv SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR "/Developer/ Applications/Performance Tools" setenv SYSTEM_DEVELOPER_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes" setenv SYSTEM_DEVELOPER_TOOLS /Developer/Tools setenv SYSTEM_DEVELOPER_TOOLS_DOC_DIR "/Developer/ADC Reference Library/documentation/DeveloperTools" setenv SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes/DeveloperTools" setenv SYSTEM_DEVELOPER_USR_DIR /Developer/usr setenv SYSTEM_DEVELOPER_UTILITIES_DIR /Developer/Applications/ Utilities setenv SYSTEM_DOCUMENTATION_DIR /Library/Documentation setenv SYSTEM_LIBRARY_DIR /System/Library setenv TARGETNAME uimac setenv TARGET_BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default setenv TARGET_NAME uimac setenv TARGET_TEMP_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build setenv TEMP_DIR /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/uimac.build setenv TEMP_FILES_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build setenv TEMP_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build setenv TEMP_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv UID 501 setenv UNLOCALIZED_RESOURCES_FOLDER_PATH Unison.app/Contents/ Resources setenv UNSTRIPPED_PRODUCT NO setenv USER bcpierce setenv USER_APPS_DIR /Users/bcpierce/Applications setenv USER_HEADER_SEARCH_PATHS /usr/local/lib/ocaml setenv USER_LIBRARY_DIR /Users/bcpierce/Library setenv USE_DYNAMIC_NO_PIC YES setenv VALID_ARCHS "ppc64 ppc7400 ppc970 i386 x86_64 ppc" setenv VERBOSE_PBXCP NO setenv VERSIONPLIST_PATH Unison.app/Contents/version.plist setenv VERSION_INFO_BUILDER bcpierce setenv VERSION_INFO_FILE Unison_vers.c setenv VERSION_INFO_STRING "\"@(#)PROGRAM:Unison PROJECT:uimacnew-\"" setenv WARNING_CFLAGS "-Wmost -Wno-four-char-constants -Wno- unknown-pragmas" setenv WRAPPER_EXTENSION app setenv WRAPPER_NAME Unison.app setenv WRAPPER_SUFFIX .app setenv XCODE_APP_SUPPORT_DIR /Developer/Library/Xcode setenv XCODE_VERSION_ACTUAL 0300 setenv XCODE_VERSION_MAJOR 0300 setenv YACC /Developer/usr/bin/yacc /bin/sh -c /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/uimac.build/ Script-2E282CBA0D9AE17300439D01.sh Building unison-blob.o... echo 'let myName = "'unison'";;' > ubase/projectInfo.ml echo 'let myVersion = "'2.37.1'";;' >> ubase/projectInfo.ml echo 'let myMajorVersion = "'2.37'";;' >> ubase/projectInfo.ml ocamlopt: ubase/projectInfo.ml ---> ubase/projectInfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ ubase/projectInfo.ml ocamlopt: uutil.ml ---> uutil.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uutil.ml ocamlopt: fspath.ml ---> fspath.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fspath.ml ocamlopt: fs.ml ---> fs.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fs.ml ocamlopt: fingerprint.ml ---> fingerprint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fingerprint.ml ocamlopt: abort.ml ---> abort.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ abort.ml ocamlopt: osx.ml ---> osx.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ osx.ml ocamlopt: props.ml ---> props.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ props.ml ocamlopt: fileinfo.ml ---> fileinfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ fileinfo.ml ocamlopt: os.ml ---> os.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ os.ml ocamlopt: common.ml ---> common.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ common.ml ocamlopt: transfer.ml ---> transfer.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ transfer.ml ocamlopt: xferhint.ml ---> xferhint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ xferhint.ml ocamlopt: remote.ml ---> remote.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ remote.ml ocamlopt: globals.ml ---> globals.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ globals.ml ocamlopt: update.ml ---> update.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ update.ml ocamlopt: copy.ml ---> copy.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ copy.ml ocamlopt: stasher.ml ---> stasher.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ stasher.ml ocamlopt: files.ml ---> files.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ files.ml ocamlopt: sortri.ml ---> sortri.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ sortri.ml ocamlopt: recon.ml ---> recon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ recon.ml ocamlopt: transport.ml ---> transport.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ transport.ml ocamlopt: uicommon.ml ---> uicommon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uicommon.ml ocamlopt: uitext.ml ---> uitext.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uitext.ml ocamlopt: test.ml ---> test.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ test.ml ocamlopt: main.ml ---> main.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ main.ml ocamlopt: uimacbridgenew.ml ---> uimacbridgenew.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.4 -c /Users/bcpierce/current/unison/trunk/src/ uimacbridgenew.ml Linking unison-blob.o ocamlopt -output-obj -verbose -I lwt -I ubase -I system -thread -I system/generic -ccopt -mmacosx-version-min=10.4 -o u-b.o unix.cmxa str.cmxa bigarray.cmxa threads.cmxa ubase/rx.cmx unicode_tables.cmx unicode.cmx bytearray.cmx system/system_generic.cmx system/generic/ system_impl.cmx system.cmx ubase/projectInfo.cmx ubase/myMap.cmx ubase/ safelist.cmx ubase/uprintf.cmx ubase/util.cmx ubase/uarg.cmx ubase/ prefs.cmx ubase/trace.cmx ubase/proplist.cmx lwt/pqueue.cmx lwt/ lwt.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx case.cmx pred.cmx uutil.cmx fileutil.cmx name.cmx path.cmx fspath.cmx fs.cmx fingerprint.cmx abort.cmx osx.cmx external.cmx props.cmx fileinfo.cmx os.cmx lock.cmx clroot.cmx common.cmx tree.cmx checksum.cmx terminal.cmx transfer.cmx xferhint.cmx remote.cmx globals.cmx update.cmx copy.cmx stasher.cmx files.cmx sortri.cmx recon.cmx transport.cmx strings.cmx uicommon.cmx uitext.cmx test.cmx main.cmx uimacbridgenew.cmx + as -o '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartupa1302f.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Tmp-/camlstartupa5bacb.s' + ld -r -o 'u-b.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartupa1302f.o' 'uimacbridgenew.o' 'main.o' 'test.o' 'uitext.o' 'uicommon.o' 'strings.o' 'transport.o' 'recon.o' 'sortri.o' 'files.o' 'stasher.o' 'copy.o' 'update.o' 'globals.o' 'remote.o' 'xferhint.o' 'transfer.o' 'terminal.o' 'checksum.o' 'tree.o' 'common.o' 'clroot.o' 'lock.o' 'os.o' 'fileinfo.o' 'props.o' 'external.o' 'osx.o' 'abort.o' 'fingerprint.o' 'fs.o' 'fspath.o' 'path.o' 'name.o' 'fileutil.o' 'uutil.o' 'pred.o' 'case.o' 'lwt/lwt_unix.o' 'lwt/lwt_util.o' 'lwt/ lwt.o' 'lwt/pqueue.o' 'ubase/proplist.o' 'ubase/trace.o' 'ubase/ prefs.o' 'ubase/uarg.o' 'ubase/util.o' 'ubase/uprintf.o' 'ubase/ safelist.o' 'ubase/myMap.o' 'ubase/projectInfo.o' 'system.o' 'system/ generic/system_impl.o' 'system/system_generic.o' 'bytearray.o' 'unicode.o' 'unicode_tables.o' 'ubase/rx.o' '/usr/local/lib/ocaml/ threads/threads.a' '/usr/local/lib/ocaml/bigarray.a' '/usr/local/lib/ ocaml/str.a' '/usr/local/lib/ocaml/unix.a' '/usr/local/lib/ocaml/ stdlib.a' ld -r -o unison-blob.o u-b.o osxsupport.o pty.o bytearray_stubs.o rm -f u-b.o done CpResource build/Default/Unison.app/Contents/Resources/English.lproj/ MainMenu.nib English.lproj/MainMenu.nib mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/English.lproj cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/English.lproj/MainMenu.nib /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources/ English.lproj CpResource build/Default/Unison.app/Contents/Resources/English.lproj/ InfoPlist.strings English.lproj/InfoPlist.strings cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/English.lproj/InfoPlist.strings /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources/English.lproj CpResource build/Default/Unison.app/Contents/Resources/Unison.icns Unison.icns cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/Unison.icns /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/add.tif toolbar/ add.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/add.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/diff.tif toolbar/diff.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/diff.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/go.tif toolbar/ go.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/go.tif /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/left.tif toolbar/left.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/left.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/merge.tif toolbar/merge.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/merge.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/right.tif toolbar/right.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/right.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/save.tif toolbar/save.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/save.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/skip.tif toolbar/skip.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/skip.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/table- conflict.tif tableicons/table-conflict.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-conflict.tif /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/table-error.tif tableicons/table-error.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-error.tif /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/table-left- blue.tif tableicons/table-left-blue.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-left-blue.tif /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/table-left- green.tif tableicons/table-left-green.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-left-green.tif /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/quit.tif toolbar/quit.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/quit.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/restart.tif toolbar/restart.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/restart.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/table-merge.tif tableicons/table-merge.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-merge.tif /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/table-right- blue.tif tableicons/table-right-blue.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-right-blue.tif /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/table-right- green.tif tableicons/table-right-green.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-right-green.tif /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/table-skip.tif tableicons/table-skip.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-skip.tif /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/rescan.tif toolbar/rescan.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/toolbar/rescan.tif /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/table-mixed.tif tableicons/table-mixed.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/table-mixed.tif /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarAdvanced.png progressicons/ProgressBarAdvanced.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarAdvanced.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarBlue.png progressicons/ProgressBarBlue.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarBlue.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndAdvanced.png progressicons/ProgressBarEndAdvanced.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndAdvanced.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndBlue.png progressicons/ProgressBarEndBlue.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndBlue.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndGray.png progressicons/ProgressBarEndGray.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndGray.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndGreen.png progressicons/ProgressBarEndGreen.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndGreen.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndWhite.png progressicons/ProgressBarEndWhite.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndWhite.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarGray.png progressicons/ProgressBarGray.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarGray.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarGreen.png progressicons/ProgressBarGreen.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarGreen.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarLightGreen.png progressicons/ProgressBarLightGreen.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarLightGreen.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarWhite.png progressicons/ProgressBarWhite.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarWhite.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/Outline- Flattened.png tableicons/Outline-Flattened.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Outline-Flattened.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Created.png tableicons/Change_Created.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Created.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Deleted.png tableicons/Change_Deleted.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Deleted.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Modified.png tableicons/Change_Modified.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Modified.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_PropsChanged.png tableicons/Change_PropsChanged.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_PropsChanged.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Absent.png tableicons/Change_Absent.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Absent.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Unmodified.png tableicons/Change_Unmodified.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Unmodified.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/Outline- Deep.png tableicons/Outline-Deep.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Outline-Deep.png /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/Outline- Flat.png tableicons/Outline-Flat.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Outline-Flat.png /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ main.o /Users/bcpierce/current/unison/trunk/src/uimacnew/main.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/main.m -o /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal/i386/main.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ MyController.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ MyController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/MyController.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/MyController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ProfileController.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ProfileController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/ProfileController.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/ProfileController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ReconItem.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ReconItem.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/ReconItem.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/ReconItem.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ReconTableView.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ReconTableView.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/ReconTableView.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/ReconTableView.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ PreferencesController.o /Users/bcpierce/current/unison/trunk/src/ uimacnew/PreferencesController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/PreferencesController.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/PreferencesController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ProfileTableView.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ProfileTableView.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/ProfileTableView.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/ProfileTableView.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ NotificationController.o /Users/bcpierce/current/unison/trunk/src/ uimacnew/NotificationController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/NotificationController.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/NotificationController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ UnisonToolbar.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ UnisonToolbar.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/UnisonToolbar.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/UnisonToolbar.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ Bridge.o /Users/bcpierce/current/unison/trunk/src/uimacnew/Bridge.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/Bridge.m -o /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal/i386/Bridge.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ProgressCell.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ProgressCell.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/ProgressCell.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/ProgressCell.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ImageAndTextCell.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ImageAndTextCell.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -pipe -Wno- trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -fmessage- length=0 -fvisibility=hidden -mmacosx-version-min=10.4 -gdwarf-2 -I/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources - isysroot /Developer/SDKs/MacOSX10.4u.sdk -c /Users/bcpierce/current/ unison/trunk/src/uimacnew/ImageAndTextCell.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/ImageAndTextCell.o Ld /Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/MacOS/Unison normal i386 mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/MacOS cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -o /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/MacOS/Unison -L/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default -F/ Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default -F/ Users/bcpierce/current/unison/trunk/src/uimacnew -filelist /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Objects-normal/i386/Unison.LinkFileList -framework Cocoa -framework Security -framework Growl -framework ExceptionHandling -arch i386 -mmacosx-version-min=10.4 -L/usr/local/ lib/ocaml -lunix -lthreadsnat -lstr -lbigarray -lasmrun -isysroot / Developer/SDKs/MacOSX10.4u.sdk Undefined symbols: "_fcntl$UNIX2003", referenced from: _caml_sys_open in libasmrun.a(sys.o) _unix_set_nonblock in libunix.a(fcntl.o) _unix_set_nonblock in libunix.a(fcntl.o) _unix_clear_nonblock in libunix.a(fcntl.o) _unix_clear_nonblock in libunix.a(fcntl.o) _unix_set_close_on_exec in libunix.a(fcntl.o) _unix_set_close_on_exec in libunix.a(fcntl.o) _unix_clear_close_on_exec in libunix.a(fcntl.o) _unix_clear_close_on_exec in libunix.a(fcntl.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) "_tcdrain$UNIX2003", referenced from: _unix_tcdrain in libunix.a(termios.o) "_pthread_cond_init$UNIX2003", referenced from: _caml_thread_reinitialize in libthreadsnat.a(posix_n.o) _caml_threadstatus_new in libthreadsnat.a(posix_n.o) _caml_condition_new in libthreadsnat.a(posix_n.o) "_open$UNIX2003", referenced from: _caml_sys_open in libasmrun.a(sys.o) _unix_open in libunix.a(open.o) "_write$UNIX2003", referenced from: _unix_write in libunix.a(write.o) _unix_single_write in libunix.a(write.o) _do_write in libasmrun.a(io.o) _caml_ba_map_file in libbigarray.a(mmap_unix.o) "_waitpid$UNIX2003", referenced from: _unix_waitpid in libunix.a(wait.o) "_strerror$UNIX2003", referenced from: _caml_sys_error in libasmrun.a(sys.o) _caml_pthread_check in libthreadsnat.a(posix_n.o) _unix_error_message in libunix.a(errmsg.o) "_sigsuspend$UNIX2003", referenced from: _unix_sigsuspend in libunix.a(signals.o) "_kill$UNIX2003", referenced from: _unix_kill in libunix.a(kill.o) "_fchmod$UNIX2003", referenced from: _unix_fchmod in libunix.a(fchmod.o) "_getrlimit$UNIX2003", referenced from: _segv_handler in libasmrun.a(signals_asm.o) "_close$UNIX2003", referenced from: _caml_sys_close in libasmrun.a(sys.o) _caml_close_channel in libasmrun.a(io.o) _caml_ml_close_channel in libasmrun.a(io.o) _unix_close in libunix.a(close.o) _alloc_sockaddr in libunix.a(socketaddr.o) "_pthread_sigmask$UNIX2003", referenced from: _caml_thread_tick in libthreadsnat.a(posix_n.o) _caml_thread_sigmask in libthreadsnat.a(posix_n.o) "_strtod$UNIX2003", referenced from: _caml_float_of_substring in libasmrun.a(floats.o) _caml_float_of_string in libasmrun.a(floats.o) "_read$UNIX2003", referenced from: _caml_do_read in libasmrun.a(io.o) _unix_read in libunix.a(read.o) "_caml_apply2", referenced from: _caml_callback2_exn in libasmrun.a(i386.o) "_caml_apply3", referenced from: _caml_callback3_exn in libasmrun.a(i386.o) "_wait$UNIX2003", referenced from: _unix_wait in libunix.a(wait.o) "_sleep$UNIX2003", referenced from: _unix_sleep in libunix.a(sleep.o) "_select$UNIX2003", referenced from: _caml_thread_tick in libthreadsnat.a(posix_n.o) _unix_select in libunix.a(select.o) "_fputs$UNIX2003", referenced from: _caml_fatal_error in libasmrun.a(misc.o) _caml_parse_engine in libasmrun.a(parsing.o) "_sigaltstack$UNIX2003", referenced from: _caml_init_signals in libasmrun.a(signals_asm.o) "_nice$UNIX2003", referenced from: _unix_nice in libunix.a(nice.o) "_sigwait$UNIX2003", referenced from: _caml_wait_signal in libthreadsnat.a(posix_n.o) "_chmod$UNIX2003", referenced from: _unix_chmod in libunix.a(chmod.o) "_system$UNIX2003", referenced from: _caml_sys_system_command in libasmrun.a(sys.o) "_mktime$UNIX2003", referenced from: _unix_mktime in libunix.a(gmtime.o) ld: symbol(s) not found collect2: ld returned 1 exit status ** BUILD FAILED ** make: *** [macexecutable] Error 1 ~/current/unison/trunk/src> From Jerome.Vouillon at pps.jussieu.fr Mon Jul 20 11:16:48 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 20 Jul 2009 17:16:48 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> Message-ID: <20090720151648.GA21753@pps.jussieu.fr> On Mon, Jul 20, 2009 at 10:06:20AM -0400, Benjamin Pierce wrote: > > It would be great if someone could try with Ocaml 3.11.1 (where this > > bug is fixed) and report back. > > I tried again to get 3.11.1 working on my laptop, but I'm not quite > there yet. Any idea what's wrong? (This is with a newly compiled > OCaml.) Apparently, the Ocaml libraries has been compiled for Mac OS X 10.5 at least: > "_open$UNIX2003", referenced from: > _caml_sys_open in libasmrun.a(sys.o) > _unix_open in libunix.a(open.o) What happens if you change MINOSXVERSION=10.4 to MINOSXVERSION=10.5 in Makefile.Ocaml? -- Jerome From bcpierce at cis.upenn.edu Mon Jul 20 14:52:31 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 20 Jul 2009 14:52:31 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090720151648.GA21753@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> Message-ID: <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> OK, I changed 10.5 in the makefile and project file, updated XCode, recompiled OCaml, and tried again. It looks closer, but not quite there... - B ocamlc -o mkProjectInfo unix.cma str.cma mkProjectInfo.ml ./mkProjectInfo > Makefile.ProjectInfo UISTYLE = macnew Building for Unix NATIVE = true THREADS = true STATIC = false OSTYPE = OSARCH = osx ocamlopt: ubase/rx.mli ---> ubase/rx.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/rx.mli ocamlopt: ubase/rx.ml ---> ubase/rx.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/rx.ml ocamlopt: unicode_tables.ml ---> unicode_tables.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ unicode_tables.ml ocamlopt: unicode.mli ---> unicode.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ unicode.mli ocamlopt: unicode.ml ---> unicode.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ unicode.ml ocamlopt: bytearray.mli ---> bytearray.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ bytearray.mli ocamlopt: bytearray.ml ---> bytearray.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ bytearray.ml ocamlopt: system/system_generic.ml ---> system/system_generic.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ system/system_generic.ml ocamlopt: system/generic/system_impl.ml ---> system/generic/ system_impl.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ system/generic/system_impl.ml ocamlc: system/system_intf.ml ---> system/system_intf.cmo ocamlc -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ system/system_intf.ml ocamlopt: system.mli ---> system.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ system.mli ocamlopt: system.ml ---> system.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ system.ml echo 'let myName = "'unison'";;' > ubase/projectInfo.ml echo 'let myVersion = "'2.37.1'";;' >> ubase/projectInfo.ml echo 'let myMajorVersion = "'2.37'";;' >> ubase/projectInfo.ml ocamlopt: ubase/projectInfo.ml ---> ubase/projectInfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/projectInfo.ml ocamlopt: ubase/myMap.mli ---> ubase/myMap.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/myMap.mli ocamlopt: ubase/myMap.ml ---> ubase/myMap.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/myMap.ml ocamlopt: ubase/safelist.mli ---> ubase/safelist.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/safelist.mli ocamlopt: ubase/safelist.ml ---> ubase/safelist.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/safelist.ml ocamlopt: ubase/uprintf.mli ---> ubase/uprintf.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uprintf.mli ocamlopt: ubase/uprintf.ml ---> ubase/uprintf.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uprintf.ml ocamlopt: ubase/util.mli ---> ubase/util.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/util.mli ocamlopt: ubase/util.ml ---> ubase/util.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/util.ml ocamlopt: ubase/uarg.mli ---> ubase/uarg.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uarg.mli ocamlopt: ubase/uarg.ml ---> ubase/uarg.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/uarg.ml ocamlopt: ubase/prefs.mli ---> ubase/prefs.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/prefs.mli ocamlopt: ubase/prefs.ml ---> ubase/prefs.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/prefs.ml ocamlopt: ubase/trace.mli ---> ubase/trace.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/trace.mli ocamlopt: ubase/trace.ml ---> ubase/trace.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/trace.ml ocamlopt: ubase/proplist.mli ---> ubase/proplist.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/proplist.mli ocamlopt: ubase/proplist.ml ---> ubase/proplist.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/proplist.ml ocamlopt: lwt/pqueue.mli ---> lwt/pqueue.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/pqueue.mli ocamlopt: lwt/pqueue.ml ---> lwt/pqueue.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/pqueue.ml ocamlopt: lwt/lwt.mli ---> lwt/lwt.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt.mli ocamlopt: lwt/lwt.ml ---> lwt/lwt.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt.ml ocamlopt: lwt/lwt_util.mli ---> lwt/lwt_util.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_util.mli ocamlopt: lwt/lwt_util.ml ---> lwt/lwt_util.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_util.ml ocamlopt: lwt/lwt_unix.mli ---> lwt/lwt_unix.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_unix.mli ocamlopt: lwt/lwt_unix.ml ---> lwt/lwt_unix.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lwt/lwt_unix.ml ocamlopt: case.mli ---> case.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ case.mli ocamlopt: case.ml ---> case.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ case.ml ocamlopt: pred.mli ---> pred.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ pred.mli ocamlopt: pred.ml ---> pred.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ pred.ml ocamlopt: uutil.mli ---> uutil.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uutil.mli ocamlopt: uutil.ml ---> uutil.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uutil.ml ocamlopt: fileutil.mli ---> fileutil.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fileutil.mli ocamlopt: fileutil.ml ---> fileutil.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fileutil.ml ocamlopt: name.mli ---> name.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ name.mli ocamlopt: name.ml ---> name.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ name.ml ocamlopt: path.mli ---> path.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ path.mli ocamlopt: path.ml ---> path.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ path.ml ocamlopt: fspath.mli ---> fspath.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fspath.mli ocamlopt: fspath.ml ---> fspath.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fspath.ml ocamlopt: fs.mli ---> fs.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fs.mli ocamlopt: fs.ml ---> fs.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fs.ml ocamlopt: fingerprint.mli ---> fingerprint.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fingerprint.mli ocamlopt: fingerprint.ml ---> fingerprint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fingerprint.ml ocamlopt: abort.mli ---> abort.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ abort.mli ocamlopt: abort.ml ---> abort.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ abort.ml ocamlopt: osx.mli ---> osx.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ osx.mli ocamlopt: osx.ml ---> osx.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ osx.ml ocamlopt: external.mli ---> external.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ external.mli ocamlopt: external.ml ---> external.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ external.ml ocamlopt: props.mli ---> props.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ props.mli ocamlopt: props.ml ---> props.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ props.ml ocamlopt: fileinfo.mli ---> fileinfo.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fileinfo.mli ocamlopt: fileinfo.ml ---> fileinfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fileinfo.ml ocamlopt: os.mli ---> os.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ os.mli ocamlopt: os.ml ---> os.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ os.ml ocamlopt: lock.mli ---> lock.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lock.mli ocamlopt: lock.ml ---> lock.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ lock.ml ocamlopt: clroot.mli ---> clroot.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ clroot.mli ocamlopt: clroot.ml ---> clroot.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ clroot.ml ocamlopt: common.mli ---> common.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ common.mli ocamlopt: common.ml ---> common.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ common.ml ocamlopt: tree.mli ---> tree.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ tree.mli ocamlopt: tree.ml ---> tree.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ tree.ml ocamlopt: checksum.mli ---> checksum.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ checksum.mli ocamlopt: checksum.ml ---> checksum.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ checksum.ml ocamlopt: terminal.mli ---> terminal.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ terminal.mli ocamlopt: terminal.ml ---> terminal.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ terminal.ml ocamlopt: transfer.mli ---> transfer.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ transfer.mli ocamlopt: transfer.ml ---> transfer.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ transfer.ml ocamlopt: xferhint.mli ---> xferhint.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ xferhint.mli ocamlopt: xferhint.ml ---> xferhint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ xferhint.ml ocamlopt: remote.mli ---> remote.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ remote.mli ocamlopt: remote.ml ---> remote.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ remote.ml ocamlopt: globals.mli ---> globals.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ globals.mli ocamlopt: globals.ml ---> globals.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ globals.ml ocamlopt: update.mli ---> update.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ update.mli ocamlopt: update.ml ---> update.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ update.ml ocamlopt: copy.mli ---> copy.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ copy.mli ocamlopt: copy.ml ---> copy.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ copy.ml ocamlopt: stasher.mli ---> stasher.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ stasher.mli ocamlopt: stasher.ml ---> stasher.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ stasher.ml ocamlopt: files.mli ---> files.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ files.mli ocamlopt: files.ml ---> files.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ files.ml ocamlopt: sortri.mli ---> sortri.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ sortri.mli ocamlopt: sortri.ml ---> sortri.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ sortri.ml ocamlopt: recon.mli ---> recon.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ recon.mli ocamlopt: recon.ml ---> recon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ recon.ml ocamlopt: transport.mli ---> transport.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ transport.mli ocamlopt: transport.ml ---> transport.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ transport.ml ocamlopt: strings.mli ---> strings.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ strings.mli ocamlopt: strings.ml ---> strings.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ strings.ml ocamlopt: uicommon.mli ---> uicommon.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uicommon.mli ocamlopt: uicommon.ml ---> uicommon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uicommon.ml ocamlopt: uitext.mli ---> uitext.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uitext.mli ocamlopt: uitext.ml ---> uitext.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uitext.ml ocamlopt: test.mli ---> test.cmi ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ test.mli ocamlopt: test.ml ---> test.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ test.ml ocamlopt: main.ml ---> main.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ main.ml ocamlopt: uimacbridgenew.ml ---> uimacbridgenew.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uimacbridgenew.ml ocamlopt: osxsupport.c ---> osxsupport.o ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -ccopt -o -ccopt /Users/bcpierce/current/ unison/trunk/src/osxsupport.o -c /Users/bcpierce/current/unison/trunk/ src/osxsupport.c ocamlopt: pty.c ---> pty.o ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -ccopt -o -ccopt /Users/bcpierce/current/ unison/trunk/src/pty.o -c /Users/bcpierce/current/unison/trunk/src/pty.c ocamlopt: bytearray_stubs.c ---> bytearray_stubs.o ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -ccopt -o -ccopt /Users/bcpierce/current/ unison/trunk/src/bytearray_stubs.o -c /Users/bcpierce/current/unison/ trunk/src/bytearray_stubs.c Linking unison-blob.o ocamlopt -output-obj -verbose -I lwt -I ubase -I system -thread -I system/generic -ccopt -mmacosx-version-min=10.5 -o u-b.o unix.cmxa str.cmxa bigarray.cmxa threads.cmxa ubase/rx.cmx unicode_tables.cmx unicode.cmx bytearray.cmx system/system_generic.cmx system/generic/ system_impl.cmx system.cmx ubase/projectInfo.cmx ubase/myMap.cmx ubase/ safelist.cmx ubase/uprintf.cmx ubase/util.cmx ubase/uarg.cmx ubase/ prefs.cmx ubase/trace.cmx ubase/proplist.cmx lwt/pqueue.cmx lwt/ lwt.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx case.cmx pred.cmx uutil.cmx fileutil.cmx name.cmx path.cmx fspath.cmx fs.cmx fingerprint.cmx abort.cmx osx.cmx external.cmx props.cmx fileinfo.cmx os.cmx lock.cmx clroot.cmx common.cmx tree.cmx checksum.cmx terminal.cmx transfer.cmx xferhint.cmx remote.cmx globals.cmx update.cmx copy.cmx stasher.cmx files.cmx sortri.cmx recon.cmx transport.cmx strings.cmx uicommon.cmx uitext.cmx test.cmx main.cmx uimacbridgenew.cmx + as -o '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartup882fc8.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Tmp-/camlstartup74dd42.s' + ld -r -o 'u-b.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartup882fc8.o' 'uimacbridgenew.o' 'main.o' 'test.o' 'uitext.o' 'uicommon.o' 'strings.o' 'transport.o' 'recon.o' 'sortri.o' 'files.o' 'stasher.o' 'copy.o' 'update.o' 'globals.o' 'remote.o' 'xferhint.o' 'transfer.o' 'terminal.o' 'checksum.o' 'tree.o' 'common.o' 'clroot.o' 'lock.o' 'os.o' 'fileinfo.o' 'props.o' 'external.o' 'osx.o' 'abort.o' 'fingerprint.o' 'fs.o' 'fspath.o' 'path.o' 'name.o' 'fileutil.o' 'uutil.o' 'pred.o' 'case.o' 'lwt/lwt_unix.o' 'lwt/lwt_util.o' 'lwt/ lwt.o' 'lwt/pqueue.o' 'ubase/proplist.o' 'ubase/trace.o' 'ubase/ prefs.o' 'ubase/uarg.o' 'ubase/util.o' 'ubase/uprintf.o' 'ubase/ safelist.o' 'ubase/myMap.o' 'ubase/projectInfo.o' 'system.o' 'system/ generic/system_impl.o' 'system/system_generic.o' 'bytearray.o' 'unicode.o' 'unicode_tables.o' 'ubase/rx.o' '/usr/local/lib/ocaml/ threads/threads.a' '/usr/local/lib/ocaml/bigarray.a' '/usr/local/lib/ ocaml/str.a' '/usr/local/lib/ocaml/unix.a' '/usr/local/lib/ocaml/ stdlib.a' ld -r -o unison-blob.o u-b.o osxsupport.o pty.o bytearray_stubs.o rm -f u-b.o (cd uimacnew; xcodebuild OCAMLLIBDIR="/usr/local/lib/ocaml" SYMROOT=build) === BUILDING AGGREGATE TARGET Create ExternalSettings OF PROJECT uimacnew WITH THE DEFAULT CONFIGURATION (Default) === Checking Dependencies... The file ???ExternalSettings.xcconfig??? does not exist. (/Users/ bcpierce/current/unison/trunk/src/uimacnew/ExternalSettings.xcconfig) PhaseScriptExecution "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ Script-2A124E7E0DE1C4BE00524237.sh" cd /Users/bcpierce/current/unison/trunk/src/uimacnew setenv ACTION build setenv ALTERNATE_GROUP bcpierce setenv ALTERNATE_MODE u+w,go-w,a+rX setenv ALTERNATE_OWNER bcpierce setenv ALWAYS_SEARCH_USER_PATHS YES setenv APPLE_INTERNAL_DEVELOPER_DIR /AppleInternal/Developer setenv APPLE_INTERNAL_DIR /AppleInternal setenv APPLE_INTERNAL_DOCUMENTATION_DIR /AppleInternal/ Documentation setenv APPLE_INTERNAL_LIBRARY_DIR /AppleInternal/Library setenv APPLE_INTERNAL_TOOLS /AppleInternal/Developer/Tools setenv APPLY_RULES_IN_COPY_FILES NO setenv ARCHS i386 setenv ARCHS_STANDARD_32_64_BIT "i386 x86_64 ppc ppc64" setenv ARCHS_STANDARD_32_BIT "i386 ppc" setenv ARCHS_STANDARD_64_BIT "x86_64 ppc64" setenv BUILD_COMPONENTS "headers build" setenv BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_STYLE Default setenv BUILD_VARIANTS normal setenv BUILT_PRODUCTS_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default setenv CACHE_ROOT /var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Caches-/com.apple.Xcode.501 setenv CCHROOT /var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Caches-/com.apple.Xcode.501 setenv CHMOD /bin/chmod setenv CHOWN /usr/sbin/chown setenv CLASS_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ JavaClasses" setenv CLEAN_PRECOMPS YES setenv CLONE_HEADERS NO setenv COMMAND_MODE legacy setenv COMPOSITE_SDK_DIRS /var/folders/al/al6Jx9nMEg0YTrA5zjZmt+++ +TI/-Caches-/com.apple.Xcode.501/CompositeSDKs setenv CONFIGURATION Default setenv CONFIGURATION_BUILD_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv CONFIGURATION_TEMP_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default setenv COPYING_PRESERVES_HFS_DATA NO setenv COPY_PHASE_STRIP YES setenv COPY_RESOURCES_FROM_STATIC_FRAMEWORKS YES setenv CP /bin/cp setenv CURRENT_ARCH i386 setenv CURRENT_VARIANT normal setenv DEAD_CODE_STRIPPING NO setenv DEBUGGING_SYMBOLS YES setenv DEBUG_INFORMATION_FORMAT dwarf setenv DEPLOYMENT_LOCATION NO setenv DEPLOYMENT_POSTPROCESSING NO setenv DERIVED_FILES_DIR "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/DerivedSources" setenv DERIVED_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ DerivedSources" setenv DERIVED_SOURCES_DIR "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/DerivedSources" setenv DEVELOPER_APPLICATIONS_DIR /Developer/Applications setenv DEVELOPER_BIN_DIR /Developer/usr/bin setenv DEVELOPER_DIR /Developer setenv DEVELOPER_FRAMEWORKS_DIR /Developer/Library/Frameworks setenv DEVELOPER_FRAMEWORKS_DIR_QUOTED "\"/Developer/Library/ Frameworks\"" setenv DEVELOPER_LIBRARY_DIR /Developer/Library setenv DEVELOPER_SDK_DIR /Developer/SDKs setenv DEVELOPER_TOOLS_DIR /Developer/Tools setenv DEVELOPER_USR_DIR /Developer/usr setenv DEVELOPMENT_LANGUAGE English setenv DO_HEADER_SCANNING_IN_JAM NO setenv DSTROOT /tmp/uimacnew.dst setenv DWARF_DSYM_FILE_NAME .dSYM setenv DWARF_DSYM_FOLDER_PATH /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv ENABLE_HEADER_DEPENDENCIES YES setenv ENABLE_OPENMP_SUPPORT NO setenv EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES "*.nib *.lproj *.framework *.gch (*) CVS .svn *.xcodeproj *.xcode *.pbproj *.pbxproj" setenv FILE_LIST "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ Objects/LinkFileList" setenv FIXED_FILES_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ FixedFiles" setenv FRAMEWORK_VERSION A setenv GCC3_VERSION 3.3 setenv GCC_PFE_FILE_C_DIALECTS "c objective-c c++ objective-c++" setenv GCC_TREAT_WARNINGS_AS_ERRORS NO setenv GCC_VERSION 4.0 setenv GENERATE_MASTER_OBJECT_FILE NO setenv GENERATE_PKGINFO_FILE NO setenv GENERATE_PROFILING_CODE NO setenv GID 501 setenv GROUP bcpierce setenv HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT YES setenv HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES YES setenv HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS YES setenv HEADERMAP_INCLUDES_PROJECT_HEADERS YES setenv ICONV /usr/bin/iconv setenv INFOPLIST_EXPAND_BUILD_SETTINGS YES setenv INFOPLIST_OUTPUT_FORMAT same-as-input setenv INFOPLIST_PREPROCESS NO setenv INSTALL_DIR /tmp/uimacnew.dst setenv INSTALL_GROUP bcpierce setenv INSTALL_MODE_FLAG u+w,go-w,a+rX setenv INSTALL_OWNER bcpierce setenv INSTALL_ROOT /tmp/uimacnew.dst setenv JAVAC_DEFAULT_FLAGS "-J-Xms64m -J-XX:NewSize=4M -J- Dfile.encoding=UTF8" setenv JAVA_APP_STUB /System/Library/Frameworks/JavaVM.framework/ Resources/MacOS/JavaApplicationStub setenv JAVA_ARCHIVE_CLASSES YES setenv JAVA_ARCHIVE_TYPE JAR setenv JAVA_COMPILER /usr/bin/javac setenv JAVA_FRAMEWORK_RESOURCES_DIRS Resources setenv JAVA_JAR_FLAGS cv setenv JAVA_SOURCE_SUBDIR . setenv JAVA_USE_DEPENDENCIES YES setenv JAVA_ZIP_FLAGS -urg setenv JIKES_DEFAULT_FLAGS "+E +OLDCSO" setenv KEEP_PRIVATE_EXTERNS NO setenv LD_GENERATE_MAP_FILE NO setenv LD_MAP_FILE_PATH "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ Create ExternalSettings-LinkMap-normal-i386.txt" setenv LD_OPENMP_FLAGS -fopenmp setenv LEX /Developer/usr/bin/lex setenv LINKER_DISPLAYS_MANGLED_NAMES NO setenv LINK_FILE_LIST_normal_i386 setenv LINK_WITH_STANDARD_LIBRARIES YES setenv LOCAL_ADMIN_APPS_DIR /Applications/Utilities setenv LOCAL_APPS_DIR /Applications setenv LOCAL_DEVELOPER_DIR /Library/Developer setenv LOCAL_LIBRARY_DIR /Library setenv MACOSX_DEPLOYMENT_TARGET 10.5 setenv MAC_OS_X_VERSION_ACTUAL 1057 setenv MAC_OS_X_VERSION_MAJOR 1050 setenv MAC_OS_X_VERSION_MINOR 0500 setenv NATIVE_ARCH i386 setenv NATIVE_ARCH_32_BIT i386 setenv NATIVE_ARCH_64_BIT x86_64 setenv NATIVE_ARCH_ACTUAL i386 setenv NO_COMMON YES setenv OBJECT_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ Objects" setenv OBJECT_FILE_DIR_normal "/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/Objects-normal" setenv OBJROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv OCAMLLIBDIR /usr/local/lib/ocaml setenv ONLY_ACTIVE_ARCH NO setenv OPTIMIZATION_LEVEL 0 setenv OS MACOS setenv OSAC /usr/bin/osacompile setenv PASCAL_STRINGS YES setenv PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES "/usr/ include /usr/local/include /System/Library/Frameworks /System/Library/ PrivateFrameworks /Developer/Headers" setenv PKGINFO_FILE_PATH "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/PkgInfo" setenv PLATFORM_DEVELOPER_APPLICATIONS_DIR /Developer/Applications setenv PLATFORM_DEVELOPER_BIN_DIR /Developer/usr/bin setenv PLATFORM_DEVELOPER_LIBRARY_DIR /Developer/Library setenv PLATFORM_DEVELOPER_SDK_DIR /Developer/SDKs setenv PLATFORM_DEVELOPER_TOOLS_DIR /Developer/Tools setenv PLATFORM_DEVELOPER_USR_DIR /Developer/usr setenv PLATFORM_NAME macosx setenv PLIST_FILE_OUTPUT_FORMAT same-as-input setenv PREBINDING YES setenv PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR YES setenv PRECOMP_DESTINATION_DIR "/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/PrefixHeaders" setenv PRESERVE_DEAD_CODE_INITS_AND_TERMS NO setenv PRODUCT_NAME "Create ExternalSettings" setenv PRODUCT_SETTINGS_PATH setenv PROFILING_CODE NO setenv PROJECT uimacnew setenv PROJECT_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/DerivedSources setenv PROJECT_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv PROJECT_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/uimacnew.xcodeproj setenv PROJECT_NAME uimacnew setenv PROJECT_TEMP_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build setenv RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS YES setenv REMOVE_CVS_FROM_RESOURCES YES setenv REMOVE_SVN_FROM_RESOURCES YES setenv REZ_COLLECTOR_DIR "/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ResourceManagerResources" setenv REZ_OBJECTS_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/ ResourceManagerResources/Objects" setenv SCAN_ALL_SOURCE_FILES_FOR_INCLUDES NO setenv SCRIPT_INPUT_FILE_COUNT 0 setenv SCRIPT_OUTPUT_FILE_COUNT 0 setenv SDKROOT /Developer/SDKs/MacOSX10.5.sdk setenv SDK_DIR /Developer/SDKs/MacOSX10.5.sdk setenv SDK_NAME macosx10.5 setenv SED /usr/bin/sed setenv SEPARATE_STRIP NO setenv SEPARATE_SYMBOL_EDIT NO setenv SET_DIR_MODE_OWNER_GROUP YES setenv SET_FILE_MODE_OWNER_GROUP NO setenv SHARED_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/DerivedSources setenv SHARED_PRECOMPS_DIR /var/folders/al/al6Jx9nMEg0YTrA5zjZmt++ ++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders setenv SKIP_INSTALL YES setenv SOURCE_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv SRCROOT /Users/bcpierce/current/unison/trunk/src/uimacnew setenv STANDARD_C_PLUS_PLUS_LIBRARY_TYPE dynamic setenv STRINGS_FILE_OUTPUT_ENCODING UTF-16 setenv STRIP_INSTALLED_PRODUCT YES setenv STRIP_STYLE all setenv SYMBOL_REPOSITORY_DIR "/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build/SymbolRepositories" setenv SYMROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv SYSTEM_ADMIN_APPS_DIR /Applications/Utilities setenv SYSTEM_APPS_DIR /Applications setenv SYSTEM_CORE_SERVICES_DIR /System/Library/CoreServices setenv SYSTEM_DEMOS_DIR /Applications/Extras setenv SYSTEM_DEVELOPER_APPS_DIR /Developer/Applications setenv SYSTEM_DEVELOPER_BIN_DIR /Developer/usr/bin setenv SYSTEM_DEVELOPER_DEMOS_DIR "/Developer/Applications/ Utilities/Built Examples" setenv SYSTEM_DEVELOPER_DIR /Developer setenv SYSTEM_DEVELOPER_DOC_DIR "/Developer/ADC Reference Library" setenv SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR "/Developer/ Applications/Graphics Tools" setenv SYSTEM_DEVELOPER_JAVA_TOOLS_DIR "/Developer/Applications/ Java Tools" setenv SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR "/Developer/ Applications/Performance Tools" setenv SYSTEM_DEVELOPER_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes" setenv SYSTEM_DEVELOPER_TOOLS /Developer/Tools setenv SYSTEM_DEVELOPER_TOOLS_DOC_DIR "/Developer/ADC Reference Library/documentation/DeveloperTools" setenv SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes/DeveloperTools" setenv SYSTEM_DEVELOPER_USR_DIR /Developer/usr setenv SYSTEM_DEVELOPER_UTILITIES_DIR /Developer/Applications/ Utilities setenv SYSTEM_DOCUMENTATION_DIR /Library/Documentation setenv SYSTEM_LIBRARY_DIR /System/Library setenv TARGETNAME "Create ExternalSettings" setenv TARGET_BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default setenv TARGET_NAME "Create ExternalSettings" setenv TARGET_TEMP_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_FILES_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_FILE_DIR "/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/Create ExternalSettings.build" setenv TEMP_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv UID 501 setenv UNSTRIPPED_PRODUCT NO setenv USER bcpierce setenv USER_APPS_DIR /Users/bcpierce/Applications setenv USER_HEADER_SEARCH_PATHS /usr/local/lib/ocaml setenv USER_LIBRARY_DIR /Users/bcpierce/Library setenv USE_DYNAMIC_NO_PIC YES setenv USE_HEADERMAP YES setenv USE_HEADER_SYMLINKS NO setenv VALID_ARCHS "i386 ppc ppc64 ppc7400 ppc970 x86_64" setenv VERBOSE_PBXCP NO setenv VERSION_INFO_BUILDER bcpierce setenv VERSION_INFO_FILE "Create ExternalSettings_vers.c" setenv VERSION_INFO_STRING "\"@(#)PROGRAM:Create ExternalSettings PROJECT:uimacnew-\"" setenv XCODE_APP_SUPPORT_DIR /Developer/Library/Xcode setenv XCODE_VERSION_ACTUAL 0313 setenv XCODE_VERSION_MAJOR 0300 setenv XCODE_VERSION_MINOR 0310 setenv YACC /Developer/usr/bin/yacc /bin/sh -c "\"/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/Create ExternalSettings.build/ Script-2A124E7E0DE1C4BE00524237.sh\"" === BUILDING NATIVE TARGET uimac OF PROJECT uimacnew WITH THE DEFAULT CONFIGURATION (Default) === Checking Dependencies... The file ???ExternalSettings.xcconfig??? does not exist. (/Users/ bcpierce/current/unison/trunk/src/uimacnew/ExternalSettings.xcconfig) Processing /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Info.plist Info.plist mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents cd /Users/bcpierce/current/unison/trunk/src/uimacnew Info.plist -genpkginfo / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/PkgInfo -expandbuildsettings -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Info.plist PhaseScriptExecution /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/uimac.build/ Script-2E282CBA0D9AE17300439D01.sh cd /Users/bcpierce/current/unison/trunk/src/uimacnew setenv ACTION build setenv ALTERNATE_GROUP bcpierce setenv ALTERNATE_MODE u+w,go-w,a+rX setenv ALTERNATE_OWNER bcpierce setenv ALWAYS_SEARCH_USER_PATHS YES setenv APPLE_INTERNAL_DEVELOPER_DIR /AppleInternal/Developer setenv APPLE_INTERNAL_DIR /AppleInternal setenv APPLE_INTERNAL_DOCUMENTATION_DIR /AppleInternal/ Documentation setenv APPLE_INTERNAL_LIBRARY_DIR /AppleInternal/Library setenv APPLE_INTERNAL_TOOLS /AppleInternal/Developer/Tools setenv APPLY_RULES_IN_COPY_FILES NO setenv ARCHS i386 setenv ARCHS_STANDARD_32_64_BIT "i386 x86_64 ppc ppc64" setenv ARCHS_STANDARD_32_BIT "i386 ppc" setenv ARCHS_STANDARD_64_BIT "x86_64 ppc64" setenv BUILD_COMPONENTS "headers build" setenv BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv BUILD_STYLE Default setenv BUILD_VARIANTS normal setenv BUILT_PRODUCTS_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default setenv CACHE_ROOT /var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Caches-/com.apple.Xcode.501 setenv CCHROOT /var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Caches-/com.apple.Xcode.501 setenv CHMOD /bin/chmod setenv CHOWN /usr/sbin/chown setenv CLASS_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/JavaClasses setenv CLEAN_PRECOMPS YES setenv CLONE_HEADERS NO setenv CODE_SIGNING_ALLOWED YES setenv COMMAND_MODE legacy setenv COMPOSITE_SDK_DIRS /var/folders/al/al6Jx9nMEg0YTrA5zjZmt+++ +TI/-Caches-/com.apple.Xcode.501/CompositeSDKs setenv CONFIGURATION Default setenv CONFIGURATION_BUILD_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv CONFIGURATION_TEMP_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default setenv CONTENTS_FOLDER_PATH Unison.app/Contents setenv COPYING_PRESERVES_HFS_DATA NO setenv COPY_PHASE_STRIP YES setenv COPY_RESOURCES_FROM_STATIC_FRAMEWORKS YES setenv CP /bin/cp setenv CURRENT_ARCH i386 setenv CURRENT_VARIANT normal setenv DEAD_CODE_STRIPPING NO setenv DEBUGGING_SYMBOLS YES setenv DEBUG_INFORMATION_FORMAT dwarf setenv DEPLOYMENT_LOCATION NO setenv DEPLOYMENT_POSTPROCESSING NO setenv DERIVED_FILES_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources setenv DERIVED_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources setenv DERIVED_SOURCES_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources setenv DEVELOPER_APPLICATIONS_DIR /Developer/Applications setenv DEVELOPER_BIN_DIR /Developer/usr/bin setenv DEVELOPER_DIR /Developer setenv DEVELOPER_FRAMEWORKS_DIR /Developer/Library/Frameworks setenv DEVELOPER_FRAMEWORKS_DIR_QUOTED "\"/Developer/Library/ Frameworks\"" setenv DEVELOPER_LIBRARY_DIR /Developer/Library setenv DEVELOPER_SDK_DIR /Developer/SDKs setenv DEVELOPER_TOOLS_DIR /Developer/Tools setenv DEVELOPER_USR_DIR /Developer/usr setenv DEVELOPMENT_LANGUAGE English setenv DOCUMENTATION_FOLDER_PATH /Documentation setenv DO_HEADER_SCANNING_IN_JAM NO setenv DSTROOT /tmp/uimacnew.dst setenv DWARF_DSYM_FILE_NAME Unison.app.dSYM setenv DWARF_DSYM_FOLDER_PATH /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default setenv ENABLE_HEADER_DEPENDENCIES YES setenv ENABLE_OPENMP_SUPPORT NO setenv EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES "*.nib *.lproj *.framework *.gch (*) CVS .svn *.xcodeproj *.xcode *.pbproj *.pbxproj" setenv EXECUTABLES_FOLDER_PATH Unison.app/Contents/Executables setenv EXECUTABLE_FOLDER_PATH Unison.app/Contents/MacOS setenv EXECUTABLE_NAME Unison setenv EXECUTABLE_PATH Unison.app/Contents/MacOS/Unison setenv FILE_LIST /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/Objects/LinkFileList setenv FIXED_FILES_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/FixedFiles setenv FRAMEWORKS_FOLDER_PATH Unison.app/Contents/Frameworks setenv FRAMEWORK_FLAG_PREFIX -framework setenv FRAMEWORK_SEARCH_PATHS "\"/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default\" /Users/bcpierce/current/unison/ trunk/src/uimacnew" setenv FRAMEWORK_VERSION A setenv FULL_PRODUCT_NAME Unison.app setenv GCC3_VERSION 3.3 setenv GCC_DYNAMIC_NO_PIC YES setenv GCC_ENABLE_OBJC_EXCEPTIONS YES setenv GCC_INLINES_ARE_PRIVATE_EXTERN YES setenv GCC_PFE_FILE_C_DIALECTS "c objective-c c++ objective-c++" setenv GCC_PRECOMPILE_PREFIX_HEADER YES setenv GCC_SYMBOLS_PRIVATE_EXTERN YES setenv GCC_TREAT_WARNINGS_AS_ERRORS NO setenv GCC_VERSION 4.0 setenv GENERATE_MASTER_OBJECT_FILE NO setenv GENERATE_PKGINFO_FILE YES setenv GENERATE_PROFILING_CODE NO setenv GID 501 setenv GROUP bcpierce setenv HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT YES setenv HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES YES setenv HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS YES setenv HEADERMAP_INCLUDES_PROJECT_HEADERS YES setenv HEADER_SEARCH_PATHS "\"/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/include\" " setenv ICONV /usr/bin/iconv setenv INFOPLIST_EXPAND_BUILD_SETTINGS YES setenv INFOPLIST_FILE Info.plist setenv INFOPLIST_OUTPUT_FORMAT same-as-input setenv INFOPLIST_PATH Unison.app/Contents/Info.plist setenv INFOPLIST_PREPROCESS NO setenv INFOSTRINGS_PATH /InfoPlist.strings setenv INSTALL_DIR /tmp/uimacnew.dst/Users/bcpierce/Applications setenv INSTALL_GROUP bcpierce setenv INSTALL_MODE_FLAG u+w,go-w,a+rX setenv INSTALL_OWNER bcpierce setenv INSTALL_PATH /Users/bcpierce/Applications setenv INSTALL_ROOT /tmp/uimacnew.dst setenv JAVAC_DEFAULT_FLAGS "-J-Xms64m -J-XX:NewSize=4M -J- Dfile.encoding=UTF8" setenv JAVA_APP_STUB /System/Library/Frameworks/JavaVM.framework/ Resources/MacOS/JavaApplicationStub setenv JAVA_ARCHIVE_CLASSES YES setenv JAVA_ARCHIVE_TYPE JAR setenv JAVA_COMPILER /usr/bin/javac setenv JAVA_FOLDER_PATH Unison.app/Contents/Resources/Java setenv JAVA_FRAMEWORK_RESOURCES_DIRS Resources setenv JAVA_JAR_FLAGS cv setenv JAVA_SOURCE_SUBDIR . setenv JAVA_USE_DEPENDENCIES YES setenv JAVA_ZIP_FLAGS -urg setenv JIKES_DEFAULT_FLAGS "+E +OLDCSO" setenv KEEP_PRIVATE_EXTERNS NO setenv LD_GENERATE_MAP_FILE NO setenv LD_MAP_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/Unison-LinkMap- normal-i386.txt setenv LD_OPENMP_FLAGS -fopenmp setenv LEX /Developer/usr/bin/lex setenv LIBRARY_FLAG_NOSPACE YES setenv LIBRARY_FLAG_PREFIX -l setenv LIBRARY_SEARCH_PATHS "\"/Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default\" " setenv LINKER_DISPLAYS_MANGLED_NAMES NO setenv LINK_FILE_LIST_normal_i386 /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal/i386/Unison.LinkFileList setenv LINK_WITH_STANDARD_LIBRARIES YES setenv LOCAL_ADMIN_APPS_DIR /Applications/Utilities setenv LOCAL_APPS_DIR /Applications setenv LOCAL_DEVELOPER_DIR /Library/Developer setenv LOCAL_LIBRARY_DIR /Library setenv MACH_O_TYPE mh_execute setenv MACOSX_DEPLOYMENT_TARGET 10.5 setenv MAC_OS_X_VERSION_ACTUAL 1057 setenv MAC_OS_X_VERSION_MAJOR 1050 setenv MAC_OS_X_VERSION_MINOR 0500 setenv NATIVE_ARCH i386 setenv NATIVE_ARCH_32_BIT i386 setenv NATIVE_ARCH_64_BIT x86_64 setenv NATIVE_ARCH_ACTUAL i386 setenv NO_COMMON YES setenv OBJECT_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/Objects setenv OBJECT_FILE_DIR_normal /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal setenv OBJROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv OCAMLLIBDIR /usr/local/lib/ocaml setenv ONLY_ACTIVE_ARCH NO setenv OPTIMIZATION_LEVEL 0 setenv OS MACOS setenv OSAC /usr/bin/osacompile setenv OTHER_LDFLAGS "-L/usr/local/lib/ocaml -lunix -lthreadsnat - lstr -lbigarray -lasmrun" setenv PACKAGE_TYPE com.apple.package-type.wrapper.application setenv PASCAL_STRINGS YES setenv PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES "/usr/ include /usr/local/include /System/Library/Frameworks /System/Library/ PrivateFrameworks /Developer/Headers" setenv PBDEVELOPMENTPLIST_PATH Unison.app/Contents/ pbdevelopment.plist setenv PFE_FILE_C_DIALECTS objective-c setenv PKGINFO_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/PkgInfo setenv PKGINFO_PATH Unison.app/Contents/PkgInfo setenv PLATFORM_DEVELOPER_APPLICATIONS_DIR /Developer/Applications setenv PLATFORM_DEVELOPER_BIN_DIR /Developer/usr/bin setenv PLATFORM_DEVELOPER_LIBRARY_DIR /Developer/Library setenv PLATFORM_DEVELOPER_SDK_DIR /Developer/SDKs setenv PLATFORM_DEVELOPER_TOOLS_DIR /Developer/Tools setenv PLATFORM_DEVELOPER_USR_DIR /Developer/usr setenv PLATFORM_NAME macosx setenv PLIST_FILE_OUTPUT_FORMAT same-as-input setenv PLUGINS_FOLDER_PATH Unison.app/Contents/PlugIns setenv PREBINDING NO setenv PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR YES setenv PRECOMP_DESTINATION_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ PrefixHeaders setenv PRESERVE_DEAD_CODE_INITS_AND_TERMS NO setenv PRIVATE_HEADERS_FOLDER_PATH Unison.app/Contents/ PrivateHeaders setenv PRODUCT_NAME Unison setenv PRODUCT_SETTINGS_PATH /Users/bcpierce/current/unison/trunk/ src/uimacnew/Info.plist setenv PRODUCT_TYPE com.apple.product-type.application setenv PROFILING_CODE NO setenv PROJECT uimacnew setenv PROJECT_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/DerivedSources setenv PROJECT_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv PROJECT_FILE_PATH /Users/bcpierce/current/unison/trunk/src/ uimacnew/uimacnew.xcodeproj setenv PROJECT_NAME uimacnew setenv PROJECT_TEMP_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build setenv PUBLIC_HEADERS_FOLDER_PATH Unison.app/Contents/Headers setenv RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS YES setenv REMOVE_CVS_FROM_RESOURCES YES setenv REMOVE_SVN_FROM_RESOURCES YES setenv REZ_COLLECTOR_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/ ResourceManagerResources setenv REZ_OBJECTS_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build/ ResourceManagerResources/Objects setenv REZ_SEARCH_PATHS "\"/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default\" " setenv SCAN_ALL_SOURCE_FILES_FOR_INCLUDES NO setenv SCRIPTS_FOLDER_PATH Unison.app/Contents/Resources/Scripts setenv SCRIPT_INPUT_FILE_COUNT 0 setenv SCRIPT_OUTPUT_FILE_COUNT 0 setenv SDKROOT /Developer/SDKs/MacOSX10.5.sdk setenv SDK_DIR /Developer/SDKs/MacOSX10.5.sdk setenv SDK_NAME macosx10.5 setenv SED /usr/bin/sed setenv SEPARATE_STRIP NO setenv SEPARATE_SYMBOL_EDIT NO setenv SET_DIR_MODE_OWNER_GROUP YES setenv SET_FILE_MODE_OWNER_GROUP NO setenv SHARED_DERIVED_FILE_DIR /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/DerivedSources setenv SHARED_FRAMEWORKS_FOLDER_PATH Unison.app/Contents/ SharedFrameworks setenv SHARED_PRECOMPS_DIR /var/folders/al/al6Jx9nMEg0YTrA5zjZmt++ ++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders setenv SHARED_SUPPORT_FOLDER_PATH Unison.app/Contents/SharedSupport setenv SKIP_INSTALL NO setenv SOURCE_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew setenv SRCROOT /Users/bcpierce/current/unison/trunk/src/uimacnew setenv STANDARD_C_PLUS_PLUS_LIBRARY_TYPE dynamic setenv STRINGS_FILE_OUTPUT_ENCODING UTF-16 setenv STRIP_INSTALLED_PRODUCT YES setenv STRIP_STYLE all setenv SYMBOL_REPOSITORY_DIR /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/SymbolRepositories setenv SYMROOT /Users/bcpierce/current/unison/trunk/src/uimacnew/ build setenv SYSTEM_ADMIN_APPS_DIR /Applications/Utilities setenv SYSTEM_APPS_DIR /Applications setenv SYSTEM_CORE_SERVICES_DIR /System/Library/CoreServices setenv SYSTEM_DEMOS_DIR /Applications/Extras setenv SYSTEM_DEVELOPER_APPS_DIR /Developer/Applications setenv SYSTEM_DEVELOPER_BIN_DIR /Developer/usr/bin setenv SYSTEM_DEVELOPER_DEMOS_DIR "/Developer/Applications/ Utilities/Built Examples" setenv SYSTEM_DEVELOPER_DIR /Developer setenv SYSTEM_DEVELOPER_DOC_DIR "/Developer/ADC Reference Library" setenv SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR "/Developer/ Applications/Graphics Tools" setenv SYSTEM_DEVELOPER_JAVA_TOOLS_DIR "/Developer/Applications/ Java Tools" setenv SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR "/Developer/ Applications/Performance Tools" setenv SYSTEM_DEVELOPER_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes" setenv SYSTEM_DEVELOPER_TOOLS /Developer/Tools setenv SYSTEM_DEVELOPER_TOOLS_DOC_DIR "/Developer/ADC Reference Library/documentation/DeveloperTools" setenv SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR "/Developer/ADC Reference Library/releasenotes/DeveloperTools" setenv SYSTEM_DEVELOPER_USR_DIR /Developer/usr setenv SYSTEM_DEVELOPER_UTILITIES_DIR /Developer/Applications/ Utilities setenv SYSTEM_DOCUMENTATION_DIR /Library/Documentation setenv SYSTEM_LIBRARY_DIR /System/Library setenv TARGETNAME uimac setenv TARGET_BUILD_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default setenv TARGET_NAME uimac setenv TARGET_TEMP_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build setenv TEMP_DIR /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/uimac.build setenv TEMP_FILES_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build setenv TEMP_FILE_DIR /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/uimacnew.build/Default/uimac.build setenv TEMP_ROOT /Users/bcpierce/current/unison/trunk/src/ uimacnew/build setenv UID 501 setenv UNLOCALIZED_RESOURCES_FOLDER_PATH Unison.app/Contents/ Resources setenv UNSTRIPPED_PRODUCT NO setenv USER bcpierce setenv USER_APPS_DIR /Users/bcpierce/Applications setenv USER_HEADER_SEARCH_PATHS /usr/local/lib/ocaml setenv USER_LIBRARY_DIR /Users/bcpierce/Library setenv USE_DYNAMIC_NO_PIC YES setenv USE_HEADERMAP YES setenv USE_HEADER_SYMLINKS NO setenv VALID_ARCHS "i386 ppc ppc64 ppc7400 ppc970 x86_64" setenv VERBOSE_PBXCP NO setenv VERSIONPLIST_PATH Unison.app/Contents/version.plist setenv VERSION_INFO_BUILDER bcpierce setenv VERSION_INFO_FILE Unison_vers.c setenv VERSION_INFO_STRING "\"@(#)PROGRAM:Unison PROJECT:uimacnew-\"" setenv WARNING_CFLAGS "-Wmost -Wno-four-char-constants -Wno- unknown-pragmas" setenv WRAPPER_EXTENSION app setenv WRAPPER_NAME Unison.app setenv WRAPPER_SUFFIX .app setenv XCODE_APP_SUPPORT_DIR /Developer/Library/Xcode setenv XCODE_VERSION_ACTUAL 0313 setenv XCODE_VERSION_MAJOR 0300 setenv XCODE_VERSION_MINOR 0310 setenv YACC /Developer/usr/bin/yacc /bin/sh -c /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/uimacnew.build/Default/uimac.build/ Script-2E282CBA0D9AE17300439D01.sh Building unison-blob.o... echo 'let myName = "'unison'";;' > ubase/projectInfo.ml echo 'let myVersion = "'2.37.1'";;' >> ubase/projectInfo.ml echo 'let myMajorVersion = "'2.37'";;' >> ubase/projectInfo.ml ocamlopt: ubase/projectInfo.ml ---> ubase/projectInfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ ubase/projectInfo.ml ocamlopt: uutil.ml ---> uutil.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uutil.ml ocamlopt: fspath.ml ---> fspath.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fspath.ml ocamlopt: fs.ml ---> fs.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fs.ml ocamlopt: fingerprint.ml ---> fingerprint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fingerprint.ml ocamlopt: abort.ml ---> abort.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ abort.ml ocamlopt: osx.ml ---> osx.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ osx.ml ocamlopt: props.ml ---> props.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ props.ml ocamlopt: fileinfo.ml ---> fileinfo.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ fileinfo.ml ocamlopt: os.ml ---> os.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ os.ml ocamlopt: common.ml ---> common.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ common.ml ocamlopt: transfer.ml ---> transfer.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ transfer.ml ocamlopt: xferhint.ml ---> xferhint.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ xferhint.ml ocamlopt: remote.ml ---> remote.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ remote.ml ocamlopt: globals.ml ---> globals.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ globals.ml ocamlopt: update.ml ---> update.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ update.ml ocamlopt: copy.ml ---> copy.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ copy.ml ocamlopt: stasher.ml ---> stasher.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ stasher.ml ocamlopt: files.ml ---> files.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ files.ml ocamlopt: sortri.ml ---> sortri.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ sortri.ml ocamlopt: recon.ml ---> recon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ recon.ml ocamlopt: transport.ml ---> transport.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ transport.ml ocamlopt: uicommon.ml ---> uicommon.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uicommon.ml ocamlopt: uitext.ml ---> uitext.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uitext.ml ocamlopt: test.ml ---> test.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ test.ml ocamlopt: main.ml ---> main.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ main.ml ocamlopt: uimacbridgenew.ml ---> uimacbridgenew.cmx ocamlopt -I lwt -I ubase -I system -thread -I system/generic -ccopt - mmacosx-version-min=10.5 -c /Users/bcpierce/current/unison/trunk/src/ uimacbridgenew.ml Linking unison-blob.o ocamlopt -output-obj -verbose -I lwt -I ubase -I system -thread -I system/generic -ccopt -mmacosx-version-min=10.5 -o u-b.o unix.cmxa str.cmxa bigarray.cmxa threads.cmxa ubase/rx.cmx unicode_tables.cmx unicode.cmx bytearray.cmx system/system_generic.cmx system/generic/ system_impl.cmx system.cmx ubase/projectInfo.cmx ubase/myMap.cmx ubase/ safelist.cmx ubase/uprintf.cmx ubase/util.cmx ubase/uarg.cmx ubase/ prefs.cmx ubase/trace.cmx ubase/proplist.cmx lwt/pqueue.cmx lwt/ lwt.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx case.cmx pred.cmx uutil.cmx fileutil.cmx name.cmx path.cmx fspath.cmx fs.cmx fingerprint.cmx abort.cmx osx.cmx external.cmx props.cmx fileinfo.cmx os.cmx lock.cmx clroot.cmx common.cmx tree.cmx checksum.cmx terminal.cmx transfer.cmx xferhint.cmx remote.cmx globals.cmx update.cmx copy.cmx stasher.cmx files.cmx sortri.cmx recon.cmx transport.cmx strings.cmx uicommon.cmx uitext.cmx test.cmx main.cmx uimacbridgenew.cmx + as -o '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartup8c0437.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/- Tmp-/camlstartup98098c.s' + ld -r -o 'u-b.o' '/var/folders/al/al6Jx9nMEg0YTrA5zjZmt++++TI/-Tmp-/ camlstartup8c0437.o' 'uimacbridgenew.o' 'main.o' 'test.o' 'uitext.o' 'uicommon.o' 'strings.o' 'transport.o' 'recon.o' 'sortri.o' 'files.o' 'stasher.o' 'copy.o' 'update.o' 'globals.o' 'remote.o' 'xferhint.o' 'transfer.o' 'terminal.o' 'checksum.o' 'tree.o' 'common.o' 'clroot.o' 'lock.o' 'os.o' 'fileinfo.o' 'props.o' 'external.o' 'osx.o' 'abort.o' 'fingerprint.o' 'fs.o' 'fspath.o' 'path.o' 'name.o' 'fileutil.o' 'uutil.o' 'pred.o' 'case.o' 'lwt/lwt_unix.o' 'lwt/lwt_util.o' 'lwt/ lwt.o' 'lwt/pqueue.o' 'ubase/proplist.o' 'ubase/trace.o' 'ubase/ prefs.o' 'ubase/uarg.o' 'ubase/util.o' 'ubase/uprintf.o' 'ubase/ safelist.o' 'ubase/myMap.o' 'ubase/projectInfo.o' 'system.o' 'system/ generic/system_impl.o' 'system/system_generic.o' 'bytearray.o' 'unicode.o' 'unicode_tables.o' 'ubase/rx.o' '/usr/local/lib/ocaml/ threads/threads.a' '/usr/local/lib/ocaml/bigarray.a' '/usr/local/lib/ ocaml/str.a' '/usr/local/lib/ocaml/unix.a' '/usr/local/lib/ocaml/ stdlib.a' ld -r -o unison-blob.o u-b.o osxsupport.o pty.o bytearray_stubs.o rm -f u-b.o done CpResource build/Default/Unison.app/Contents/Resources/English.lproj/ MainMenu.nib English.lproj/MainMenu.nib mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/English.lproj cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/English.lproj/MainMenu.nib /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources/ English.lproj CopyStringsFile /Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default/Unison.app/Contents/Resources/English.lproj/ InfoPlist.strings English.lproj/InfoPlist.strings cd /Users/bcpierce/current/unison/trunk/src/uimacnew setenv ICONV /usr/bin/iconv /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copystrings --validate --inputencoding UTF-16 -- outputencoding UTF-16 English.lproj/InfoPlist.strings --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources/English.lproj CpResource build/Default/Unison.app/Contents/Resources/Unison.icns Unison.icns cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/Unison.icns /Users/bcpierce/current/unison/trunk/ src/uimacnew/build/Default/Unison.app/Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/add.tif toolbar/add.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/add.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/diff.tif toolbar/diff.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/diff.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/go.tif toolbar/go.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/go.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/left.tif toolbar/left.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/left.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/merge.tif toolbar/merge.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/merge.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/quit.tif toolbar/quit.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/quit.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/restart.tif toolbar/restart.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/restart.tif --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/right.tif toolbar/right.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/right.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/save.tif toolbar/save.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/save.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/skip.tif toolbar/skip.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/skip.tif --outdir /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-conflict.tif tableicons/ table-conflict.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-conflict.tif --outdir / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-error.tif tableicons/table- error.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-error.tif --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-left-blue.tif tableicons/ table-left-blue.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-left-blue.tif --outdir / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-left-green.tif tableicons/ table-left-green.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-left-green.tif --outdir / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-merge.tif tableicons/table- merge.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-merge.tif --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-right-blue.tif tableicons/ table-right-blue.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-right-blue.tif --outdir / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-right-green.tif tableicons/ table-right-green.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-right-green.tif --outdir / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-skip.tif tableicons/table- skip.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-skip.tif --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/rescan.tif toolbar/rescan.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff toolbar/rescan.tif --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CopyTiffFile /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Resources/table-mixed.tif tableicons/table- mixed.tif cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/ Contents/Resources/copytiff tableicons/table-mixed.tif --outdir /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarAdvanced.png progressicons/ProgressBarAdvanced.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarAdvanced.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarBlue.png progressicons/ProgressBarBlue.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarBlue.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndAdvanced.png progressicons/ProgressBarEndAdvanced.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndAdvanced.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndBlue.png progressicons/ProgressBarEndBlue.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndBlue.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndGray.png progressicons/ProgressBarEndGray.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndGray.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndGreen.png progressicons/ProgressBarEndGreen.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndGreen.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarEndWhite.png progressicons/ProgressBarEndWhite.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarEndWhite.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarGray.png progressicons/ProgressBarGray.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarGray.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarWhite.png progressicons/ProgressBarWhite.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarWhite.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/Outline- Deep.png tableicons/Outline-Deep.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Outline-Deep.png /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/Outline- Flat.png tableicons/Outline-Flat.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Outline-Flat.png /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/Outline- Flattened.png tableicons/Outline-Flattened.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Outline-Flattened.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Created.png tableicons/Change_Created.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Created.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Deleted.png tableicons/Change_Deleted.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Deleted.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Modified.png tableicons/Change_Modified.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Modified.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarGreen.png progressicons/ProgressBarGreen.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarGreen.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ ProgressBarLightGreen.png progressicons/ProgressBarLightGreen.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/progressicons/ProgressBarLightGreen.png /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/Default/Unison.app/ Contents/Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_PropsChanged.png tableicons/Change_PropsChanged.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_PropsChanged.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Absent.png tableicons/Change_Absent.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Absent.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CpResource build/Default/Unison.app/Contents/Resources/ Change_Unmodified.png tableicons/Change_Unmodified.png cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/tableicons/Change_Unmodified.png /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/Default/Unison.app/Contents/ Resources CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ main.o /Users/bcpierce/current/unison/trunk/src/uimacnew/main.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/main.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/main.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ MyController.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ MyController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/MyController.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/MyController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ProfileController.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ProfileController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/ProfileController.m -o /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Objects-normal/i386/ProfileController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ReconItem.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ReconItem.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/ReconItem.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/ReconItem.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ReconTableView.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ReconTableView.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/ReconTableView.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/ReconTableView.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ PreferencesController.o /Users/bcpierce/current/unison/trunk/src/ uimacnew/PreferencesController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/PreferencesController.m -o /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Objects-normal/i386/PreferencesController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ProfileTableView.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ProfileTableView.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/ProfileTableView.m -o /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Objects-normal/i386/ProfileTableView.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ NotificationController.o /Users/bcpierce/current/unison/trunk/src/ uimacnew/NotificationController.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/NotificationController.m -o /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Objects-normal/i386/NotificationController.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ UnisonToolbar.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ UnisonToolbar.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/UnisonToolbar.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/UnisonToolbar.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ Bridge.o /Users/bcpierce/current/unison/trunk/src/uimacnew/Bridge.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/Bridge.m -o /Users/bcpierce/current/ unison/trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/ Objects-normal/i386/Bridge.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ProgressCell.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ProgressCell.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/ProgressCell.m -o /Users/bcpierce/ current/unison/trunk/src/uimacnew/build/uimacnew.build/Default/ uimac.build/Objects-normal/i386/ProgressCell.o CompileC build/uimacnew.build/Default/uimac.build/Objects-normal/i386/ ImageAndTextCell.o /Users/bcpierce/current/unison/trunk/src/uimacnew/ ImageAndTextCell.m normal i386 objective-c com.apple.compilers.gcc.4_0 cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/usr/bin/gcc-4.0 -x objective-c -arch i386 -fmessage- length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os - mdynamic-no-pic -isysroot /Developer/SDKs/MacOSX10.5.sdk - fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -I/Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Unison.hmap -Wmost -Wno-four-char-constants -Wno- unknown-pragmas -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew -I/ usr/local/lib/ocaml -I/Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/include -I/Users/bcpierce/current/unison/trunk/ src/uimacnew/build/uimacnew.build/Default/uimac.build/DerivedSources/ i386 -I/Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/DerivedSources -c /Users/bcpierce/ current/unison/trunk/src/uimacnew/ImageAndTextCell.m -o /Users/ bcpierce/current/unison/trunk/src/uimacnew/build/uimacnew.build/ Default/uimac.build/Objects-normal/i386/ImageAndTextCell.o Ld /Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/MacOS/Unison normal i386 mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/MacOS cd /Users/bcpierce/current/unison/trunk/src/uimacnew setenv MACOSX_DEPLOYMENT_TARGET 10.5 /Developer/usr/bin/gcc-4.0 -arch i386 -isysroot /Developer/SDKs/ MacOSX10.5.sdk -L/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew - filelist /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ uimacnew.build/Default/uimac.build/Objects-normal/i386/ Unison.LinkFileList -mmacosx-version-min=10.5 -L/usr/local/lib/ocaml - lunix -lthreadsnat -lstr -lbigarray -lasmrun -framework Cocoa - framework Security -framework Growl -framework ExceptionHandling / Users/bcpierce/current/unison/trunk/src/uimacnew/../unison-blob.o -o / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/MacOS/Unison Undefined symbols: "_caml_apply2", referenced from: _caml_callback2_exn in libasmrun.a(i386.o) "_caml_apply3", referenced from: _caml_callback3_exn in libasmrun.a(i386.o) ld: symbol(s) not found collect2: ld returned 1 exit status PBXCp build/Default/Unison.app/Contents/Frameworks/Growl.framework Growl.framework mkdir /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ Default/Unison.app/Contents/Frameworks cd /Users/bcpierce/current/unison/trunk/src/uimacnew /Developer/Library/PrivateFrameworks/DevToolsCore.framework/ Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -strip- debug-symbols -resolve-src-symlinks /Users/bcpierce/current/unison/ trunk/src/uimacnew/Growl.framework /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/Default/Unison.app/Contents/Frameworks ** BUILD FAILED ** The following build commands failed: uimac: Ld /Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/MacOS/Unison normal i386 (1 failure) make: *** [macexecutable] Error 1 ~/current/unison/trunk/src> On Jul 20, 2009, at 11:16 AM, Jerome Vouillon wrote: > On Mon, Jul 20, 2009 at 10:06:20AM -0400, Benjamin Pierce wrote: >>> It would be great if someone could try with Ocaml 3.11.1 (where this >>> bug is fixed) and report back. >> >> I tried again to get 3.11.1 working on my laptop, but I'm not quite >> there yet. Any idea what's wrong? (This is with a newly compiled >> OCaml.) > > Apparently, the Ocaml libraries has been compiled for Mac OS X 10.5 at > least: >> "_open$UNIX2003", referenced from: >> _caml_sys_open in libasmrun.a(sys.o) >> _unix_open in libunix.a(open.o) > > What happens if you change > MINOSXVERSION=10.4 > to > MINOSXVERSION=10.5 > in Makefile.Ocaml? > > -- Jerome > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From Jerome.Vouillon at pps.jussieu.fr Mon Jul 20 16:35:05 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 20 Jul 2009 22:35:05 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> Message-ID: <20090720203505.GA26741@pps.jussieu.fr> On Mon, Jul 20, 2009 at 02:52:31PM -0400, Benjamin Pierce wrote: > OK, I changed 10.5 in the makefile and project file, updated XCode, > recompiled OCaml, and tried again. It looks closer, but not quite > there... Does the following patch (in addition to changing MINOSXVERSION) make any difference? -- Jerome From bcpierce at cis.upenn.edu Mon Jul 20 17:18:11 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 20 Jul 2009 17:18:11 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090720203505.GA26741@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090720203505.GA26741@pps.jussieu.fr> Message-ID: Don't see a patch here -- Did an attachment get detached? On Jul 20, 2009, at 4:35 PM, Jerome Vouillon wrote: > On Mon, Jul 20, 2009 at 02:52:31PM -0400, Benjamin Pierce wrote: >> OK, I changed 10.5 in the makefile and project file, updated XCode, >> recompiled OCaml, and tried again. It looks closer, but not quite >> there... > > Does the following patch (in addition to changing MINOSXVERSION) make > any difference? > > -- Jerome > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From Jerome.Vouillon at pps.jussieu.fr Mon Jul 20 18:36:19 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Tue, 21 Jul 2009 00:36:19 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090720203505.GA26741@pps.jussieu.fr> Message-ID: <20090720223619.GA28721@pps.jussieu.fr> On Mon, Jul 20, 2009 at 05:18:11PM -0400, Benjamin Pierce wrote: > Don't see a patch here -- Did an attachment get detached? Here it is. I forgot it... :-( -------------- next part -------------- Index: src/uimacnew/uimacnew.xcodeproj/project.pbxproj =================================================================== --- src/uimacnew/uimacnew.xcodeproj/project.pbxproj (r?vision 378) +++ src/uimacnew/uimacnew.xcodeproj/project.pbxproj (copie de travail) @@ -664,6 +664,7 @@ "-Wno-unknown-pragmas", ); WRAPPER_EXTENSION = app; + ZERO_LINK = NO; }; name = Default; }; From bcpierce at cis.upenn.edu Mon Jul 20 21:31:26 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 20 Jul 2009 21:31:26 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090720223619.GA28721@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090720203505.GA26741@pps.jussieu.fr> <20090720223619.GA28721@pps.jussieu.fr> Message-ID: <7B4B7B02-18AF-459D-964F-7F4509E90821@cis.upenn.edu> Same problem. :-( (Sorry to be asking for so much help with silly compilation issues. I've just never taken the time to understand Apple's whole development environment, so the build process is a complete mystery to me!) - B On Jul 20, 2009, at 6:36 PM, Jerome Vouillon wrote: > On Mon, Jul 20, 2009 at 05:18:11PM -0400, Benjamin Pierce wrote: >> Don't see a patch here -- Did an attachment get detached? > > Here it is. I forgot it... :-( > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From Jerome.Vouillon at pps.jussieu.fr Tue Jul 21 07:39:49 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Tue, 21 Jul 2009 13:39:49 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> Message-ID: <20090721113949.GA8439@pps.jussieu.fr> First thing, I think you can remove the dependency on unison-blob.o from target macexecutable in Makefile.OCaml. At the moment, the Caml files are compiled twice! Replace the line: macexecutable: $(NAME)-blob.o by just macexecutable: Then, the patch had zero chance of working: the problem seems to happen at an earlier stage, when the Caml code is linked, not when the GUI is built. Can you try this, then: > make clean > export ZERO_LINK=NO > make If this still does not work, we have to investigate a bit more. The compilation process fails at the final step when linking everything together. The reason is that the two symbols below are not found: > Undefined symbols: > "_caml_apply2", referenced from: > _caml_callback2_exn in libasmrun.a(i386.o) > "_caml_apply3", referenced from: > _caml_callback3_exn in libasmrun.a(i386.o) These symbols should come from file unison-blob.o . You can check they are indeed defined there with the following command: > nm unison-blob.o | grep caml_apply2 0000000000005000 T caml_apply2 0000000000003ef0 T caml_apply21 0000000000003b70 T caml_apply23 00000000000037c0 T caml_apply24 If the symbols are not defined, we need to find out at which point they disappear. You need to change this rule: $(NAME)-blob.o: $(CAMLOBJS) $(COBJS) @echo Linking $@ $(CAMLC) -output-obj -verbose $(CAMLFLAGS) ... $(LD) -r -o $@ u-b.o $(COBJS) $(RM) u-b.o into: $(NAME)-blob.o: $(CAMLOBJS) $(COBJS) @echo Linking $@ $(CAMLC) -dstartup -output-obj -verbose $(CAMLFLAGS) ... $(LD) -r -o $@ u-b.o $(COBJS) (Add a "-dstartup" option to ocamlopt and remove the "rm" command.) Then, if you recompile, you should get two files u-b.o.startup.s and u-b.o in the build directory. Then, again, you can use "nm u-b.o" to find out whether caml_apply2 is defined in u-b.o. In the assembly file, there should be some lines that look like this: [...] .text .align 16 .globl caml_apply2 caml_apply2: subq $8, %rsp [...] Tell me the last point where you could find caml_apply2 defined (the corresponding output could be useful too). Now, if the symbols are actually defined in unison-blob.o, this may be a problem with the order in which the files are given to gcc for linking. So, in the following command (that should be a single line), you can try to move unison-blob.o before -lasmrun. (Under Linux, I have to put it before all the -lxxx, but this may different under Mac OS X.) > /Developer/usr/bin/gcc-4.0 -arch i386 -isysroot /Developer/SDKs/ > MacOSX10.5.sdk -L/Users/bcpierce/current/unison/trunk/src/uimacnew/ > build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ > build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew - > filelist /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ > uimacnew.build/Default/uimac.build/Objects-normal/i386/ > Unison.LinkFileList -mmacosx-version-min=10.5 -L/usr/local/lib/ocaml - > lunix -lthreadsnat -lstr -lbigarray -lasmrun -framework Cocoa - > framework Security -framework Growl -framework ExceptionHandling / > Users/bcpierce/current/unison/trunk/src/uimacnew/../unison-blob.o -o / > Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ > Unison.app/Contents/MacOS/Unison -- Jerome From vouillon at seas.upenn.edu Tue Jul 21 09:06:29 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Tue, 21 Jul 2009 09:06:29 -0400 Subject: [Unison-hackers] [unison-svn] r379 - in branches/2.32/src: . ubase Message-ID: <200907211306.n6LD6Tvb024448@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-21 09:06:29 -0400 (Tue, 21 Jul 2009) New Revision: 379 Modified: branches/2.32/src/RECENTNEWS branches/2.32/src/mkProjectInfo.ml branches/2.32/src/os.ml branches/2.32/src/ubase/prefs.ml branches/2.32/src/ubase/trace.ml branches/2.32/src/ubase/util.ml branches/2.32/src/ubase/util.mli branches/2.32/src/uicommon.ml branches/2.32/src/uigtk2.ml branches/2.32/src/uitext.ml Log: * GTK UI: Unison now take into account the arguments given (including roots if they are given this way) on the command line when rescanning. * Truncate temporary filename to remain under system limits. * Fix include directive failure when the line ends by CRLF (the CR was not removed) * Ignore errors when writing to the log file * Do not print the "Connected" message when the preference "silent" is set. * Print a warning when running "unison -ui graphic" with a text-only build of Unison Modified: branches/2.32/src/RECENTNEWS =================================================================== --- branches/2.32/src/RECENTNEWS 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/RECENTNEWS 2009-07-21 13:06:29 UTC (rev 379) @@ -1,3 +1,16 @@ +CHANGES FROM VERSION 2.32.52 + +* GTK UI: Unison now take into account the arguments given (including + roots if they are given this way) on the command line when rescanning. +* Truncate temporary filename to remain under system limits. +* Fix include directive failure when the line ends by CRLF + (the CR was not removed) +* Ignore errors when writing to the log file +* Do not print the "Connected" message when the preference "silent" is set. +* Print a warning when running "unison -ui graphic" with a text-only + build of Unison + +------------------------------- CHANGES FROM VERSION 2.32.44 * Describe recent changes in changelog Modified: branches/2.32/src/mkProjectInfo.ml =================================================================== --- branches/2.32/src/mkProjectInfo.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/mkProjectInfo.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -119,3 +119,4 @@ + Modified: branches/2.32/src/os.ml =================================================================== --- branches/2.32/src/os.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/os.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -334,6 +334,14 @@ (* TEMPORARY FILES *) (*****************************************************************************) +(* Truncate a filename to at most [l] bytes, making sure of not + truncating an UTF-8 character *) +let rec truncate_filename s l = + if l >= 0 && Char.code s.[l] land 0xC0 = 0x80 then + truncate_filename s (l - 1) + else + String.sub s 0 l + (* Generates an unused fspath for a temporary file. *) let genTempPath fresh fspath path prefix suffix = let rec f i = @@ -341,9 +349,19 @@ if i=0 then suffix else Printf.sprintf "..%03d.%s" i suffix in let tempPath = - Path.addPrefixToFinalName - (Path.addSuffixToFinalName path s) - prefix + match Path.deconstructRev path with + None -> + assert false + | Some (name, parentPath) -> + let name = Name.toString name in + let len = String.length name in + let maxlen = 64 in + let name = + if len <= maxlen then name else + (truncate_filename name maxlen ^ + Digest.to_hex (Digest.string name)) + in + Path.child parentPath (Name.fromString (prefix ^ name ^ s)) in if fresh && exists fspath tempPath then f (i + 1) else tempPath in f 0 Modified: branches/2.32/src/ubase/prefs.ml =================================================================== --- branches/2.32/src/ubase/prefs.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/ubase/prefs.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -276,6 +276,7 @@ match lines with [] -> res | theLine :: rest -> + let theLine = Util.removeTrailingCR theLine in let l = Util.trimWhitespace theLine in if l = "" || l.[0]='#' then loop rest (lineNum+1) res Modified: branches/2.32/src/ubase/trace.ml =================================================================== --- branches/2.32/src/ubase/trace.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/ubase/trace.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -151,8 +151,10 @@ | `FormatStdout -> Format.printf "%s " s); if Prefs.read logging then begin let ch = getLogch() in - output_string ch s; - flush ch + begin try + output_string ch s; + flush ch + with Sys_error _ -> () end end (* ---------------------------------------------------------------------- *) Modified: branches/2.32/src/ubase/util.ml =================================================================== --- branches/2.32/src/ubase/util.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/ubase/util.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -387,6 +387,11 @@ let concatmap sep f l = String.concat sep (Safelist.map f l) +let removeTrailingCR s = + let l = String.length s in + if l = 0 || s.[l - 1] <> '\r' then s else + String.sub s 0 (l - 1) + let rec trimWhitespace s = let l = String.length s in if l=0 then s Modified: branches/2.32/src/ubase/util.mli =================================================================== --- branches/2.32/src/ubase/util.mli 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/ubase/util.mli 2009-07-21 13:06:29 UTC (rev 379) @@ -53,6 +53,7 @@ val replacesubstring : string -> string -> string -> string (* IN,FROM,TO *) val replacesubstrings : string -> (string * string) list -> string val concatmap : string -> ('a -> string) -> 'a list -> string +val removeTrailingCR : string -> string val trimWhitespace : string -> string val splitIntoWords : string -> char -> string list val splitIntoWordsByString : string -> string -> string list Modified: branches/2.32/src/uicommon.ml =================================================================== --- branches/2.32/src/uicommon.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/uicommon.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -472,11 +472,15 @@ we ignore the command line *) let firstTime = ref(true) +(* Roots given on the command line *) +let rawRoots = ref [] + (* BCP: WARNING: Some of the code from here is duplicated in uimacbridge...! *) let initPrefs ~profileName ~displayWaitMessage ~getFirstRoot ~getSecondRoot ~termInteract = (* Restore prefs to their default values, if necessary *) if not !firstTime then Prefs.resetToDefaults(); + Globals.setRawRoots !rawRoots; (* Tell the preferences module the name of the profile *) Prefs.profileName := Some(profileName); @@ -505,7 +509,8 @@ end; (* Parse the command line. This will override settings from the profile. *) - if !firstTime then begin + (* JV (6/09): always reparse the command line *) + if true (*!firstTime*) then begin debug (fun() -> Util.msg "about to parse command line"); Prefs.parseCmdLine usageMsg; end; @@ -633,9 +638,9 @@ match Util.StringMap.find "rest" args with [] -> () | [profile] -> clprofile := Some profile - | [root1;root2] -> Globals.setRawRoots [root1;root2] + | [root1;root2] -> rawRoots := [root1;root2] | [root1;root2;profile] -> - Globals.setRawRoots [root1;root2]; + rawRoots := [root1;root2]; clprofile := Some profile | _ -> (reportError(Printf.sprintf @@ -653,7 +658,7 @@ (match !clprofile with None -> Util.msg "No profile given on command line" | Some s -> Printf.eprintf "Profile '%s' given on command line" s); - (match Globals.rawRoots() with + (match !rawRoots with [] -> Util.msg "No roots given on command line" | [root1;root2] -> Printf.eprintf "Roots '%s' and '%s' given on command line" @@ -665,7 +670,7 @@ None -> let dirString = Fspath.toString Os.unisonDir in let profiles_exist = (Files.ls dirString "*.prf")<>[] in - let clroots_given = (Globals.rawRoots() <> []) in + let clroots_given = !rawRoots <> [] in let n = if profiles_exist && not(clroots_given) then begin (* Unison has been used before: at least one profile exists. Modified: branches/2.32/src/uigtk2.ml =================================================================== --- branches/2.32/src/uigtk2.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/uigtk2.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -2019,6 +2019,19 @@ (********************************************************************* Restart button *********************************************************************) + let loadProfile p = + debug (fun()-> Util.msg "Loading profile %s..." p); + Uicommon.initPrefs p displayWaitMessage getFirstRoot getSecondRoot + termInteract; + displayNewProfileLabel p; + setMainWindowColumnHeaders() + in + + let reloadProfile () = + match !Prefs.profileName with + None -> () + | Some(n) -> loadProfile n in + let detectCmdName = "Restart" in let detectCmd () = getLock detectUpdatesAndReconcile; @@ -2031,7 +2044,7 @@ (actionBar#insert_button ~text:detectCmdName ~icon:((GMisc.image ~stock:`REFRESH ())#coerce) ~tooltip:"Check for updates" - ~callback: detectCmd ()); + ~callback: (fun () -> reloadProfile(); detectCmd ()) ()); (********************************************************************* Buttons for <--, M, -->, Skip @@ -2274,19 +2287,6 @@ Synchronization menu *********************************************************************) - let loadProfile p = - debug (fun()-> Util.msg "Loading profile %s..." p); - Uicommon.initPrefs p displayWaitMessage getFirstRoot getSecondRoot - termInteract; - displayNewProfileLabel p; - setMainWindowColumnHeaders() - in - - let reloadProfile () = - match !Prefs.profileName with - None -> () - | Some(n) -> loadProfile n in - grAdd grGo (fileMenu#add_image_item ~key:GdkKeysyms._g ~image:(GMisc.image ~stock:`EXECUTE ~icon_size:`MENU () :> GObj.widget) Modified: branches/2.32/src/uitext.ml =================================================================== --- branches/2.32/src/uitext.ml 2009-07-19 20:07:54 UTC (rev 378) +++ branches/2.32/src/uitext.ml 2009-07-21 13:06:29 UTC (rev 379) @@ -738,14 +738,17 @@ synchronizeUntilDone () end -let start _ = +let start interface = + if interface <> Uicommon.Text then + Util.msg "This Unison binary only provides the text GUI...\n"; begin try (* Just to make sure something is there... *) setWarnPrinterForInitialization(); Uicommon.uiInit (fun s -> Util.msg "%s\n%s\n" Uicommon.shortUsageMsg s; exit 1) (fun s -> Util.msg "%s" Uicommon.shortUsageMsg; exit 1) - (fun () -> if not (Prefs.read silent) + (fun () -> if Prefs.read silent then Prefs.set Trace.terse true; + if not (Prefs.read silent) then Util.msg "%s\n" (Uicommon.contactingServerMsg())) (fun () -> Some "default") (fun () -> Util.msg "%s" Uicommon.shortUsageMsg; exit 1) From vouillon at seas.upenn.edu Tue Jul 21 09:10:32 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Tue, 21 Jul 2009 09:10:32 -0400 Subject: [Unison-hackers] [unison-svn] r380 - in branches/2.27/src: . ubase Message-ID: <200907211310.n6LDAXHm024504@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-21 09:10:32 -0400 (Tue, 21 Jul 2009) New Revision: 380 Modified: branches/2.27/src/RECENTNEWS branches/2.27/src/mkProjectInfo.ml branches/2.27/src/os.ml branches/2.27/src/ubase/prefs.ml branches/2.27/src/ubase/trace.ml branches/2.27/src/ubase/util.ml branches/2.27/src/ubase/util.mli branches/2.27/src/uitext.ml Log: Backport to stable release: * Truncate temporary filenames to remain under system limits. * Fix include directive failure when the line ends by CRLF (the CR was not removed) * Ignore errors when writing to the log file * Do not print the "Connected" message when the preference "silent" is set. * Print a warning when running "unison -ui graphic" with a text-only build of Unison Modified: branches/2.27/src/RECENTNEWS =================================================================== --- branches/2.27/src/RECENTNEWS 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/RECENTNEWS 2009-07-21 13:10:32 UTC (rev 380) @@ -1,3 +1,15 @@ +CHANGES FROM VERSION 2.27.157 + +Backport to stable release: +* Truncate temporary filenames to remain under system limits. +* Fix include directive failure when the line ends by CRLF + (the CR was not removed) +* Ignore errors when writing to the log file +* Do not print the "Connected" message when the preference "silent" is set. +* Print a warning when running "unison -ui graphic" with a text-only + build of Unison + +------------------------------- CHANGES FROM VERSION 2.27.156 * Tweak Modified: branches/2.27/src/mkProjectInfo.ml =================================================================== --- branches/2.27/src/mkProjectInfo.ml 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/mkProjectInfo.ml 2009-07-21 13:10:32 UTC (rev 380) @@ -84,3 +84,4 @@ + Modified: branches/2.27/src/os.ml =================================================================== --- branches/2.27/src/os.ml 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/os.ml 2009-07-21 13:10:32 UTC (rev 380) @@ -285,6 +285,14 @@ (* TEMPORARY FILES *) (*****************************************************************************) +(* Truncate a filename to at most [l] bytes, making sure of not + truncating an UTF-8 character *) +let rec truncate_filename s l = + if l >= 0 && Char.code s.[l] land 0xC0 = 0x80 then + truncate_filename s (l - 1) + else + String.sub s 0 l + (* Generates an unused fspath for a temporary file. *) let freshPath fspath path prefix suffix = let rec f i = @@ -292,9 +300,19 @@ if i=0 then suffix else Printf.sprintf "..%03d.%s" i suffix in let tempPath = - Path.addPrefixToFinalName - (Path.addSuffixToFinalName path s) - prefix + match Path.deconstructRev path with + None -> + assert false + | Some (name, parentPath) -> + let name = Name.toString name in + let len = String.length name in + let maxlen = 64 in + let name = + if len <= maxlen then name else + (truncate_filename name maxlen ^ + Digest.to_hex (Digest.string name)) + in + Path.child parentPath (Name.fromString (prefix ^ name ^ s)) in if exists fspath tempPath then f (i + 1) else tempPath in f 0 Modified: branches/2.27/src/ubase/prefs.ml =================================================================== --- branches/2.27/src/ubase/prefs.ml 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/ubase/prefs.ml 2009-07-21 13:10:32 UTC (rev 380) @@ -254,6 +254,7 @@ match lines with [] -> res | theLine :: rest -> + let theLine = Util.removeTrailingCR theLine in let l = Util.trimWhitespace theLine in if l = "" || l.[0]='#' then loop rest (lineNum+1) res Modified: branches/2.27/src/ubase/trace.ml =================================================================== --- branches/2.27/src/ubase/trace.ml 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/ubase/trace.ml 2009-07-21 13:10:32 UTC (rev 380) @@ -136,8 +136,10 @@ | `FormatStdout -> Format.printf "%s " s); if Prefs.read logging then begin let ch = getLogch() in - output_string ch s; - flush ch + begin try + output_string ch s; + flush ch + with Sys_error _ -> () end end (* ---------------------------------------------------------------------- *) Modified: branches/2.27/src/ubase/util.ml =================================================================== --- branches/2.27/src/ubase/util.ml 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/ubase/util.ml 2009-07-21 13:10:32 UTC (rev 380) @@ -372,6 +372,11 @@ let concatmap sep f l = String.concat sep (Safelist.map f l) +let removeTrailingCR s = + let l = String.length s in + if l = 0 || s.[l - 1] <> '\r' then s else + String.sub s 0 (l - 1) + let rec trimWhitespace s = let l = String.length s in if l=0 then s Modified: branches/2.27/src/ubase/util.mli =================================================================== --- branches/2.27/src/ubase/util.mli 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/ubase/util.mli 2009-07-21 13:10:32 UTC (rev 380) @@ -53,6 +53,7 @@ val replacesubstring : string -> string -> string -> string (* IN,FROM,TO *) val replacesubstrings : string -> (string * string) list -> string val concatmap : string -> ('a -> string) -> 'a list -> string +val removeTrailingCR : string -> string val trimWhitespace : string -> string val splitIntoWords : string -> char -> string list val splitIntoWordsByString : string -> string -> string list Modified: branches/2.27/src/uitext.ml =================================================================== --- branches/2.27/src/uitext.ml 2009-07-21 13:06:29 UTC (rev 379) +++ branches/2.27/src/uitext.ml 2009-07-21 13:10:32 UTC (rev 380) @@ -609,14 +609,17 @@ synchronizeUntilDone () end -let start _ = +let start interface = + if interface <> Uicommon.Text then + Util.msg "This Unison binary only provides the text GUI...\n"; begin try (* Just to make sure something is there... *) setWarnPrinterForInitialization(); Uicommon.uiInit (fun s -> Util.msg "%s\n%s\n" Uicommon.shortUsageMsg s; exit 1) (fun s -> Util.msg "%s" Uicommon.shortUsageMsg; exit 1) - (fun () -> if not (Prefs.read silent) + (fun () -> if Prefs.read silent then Prefs.set Trace.terse true; + if not (Prefs.read silent) then Util.msg "%s\n" (Uicommon.contactingServerMsg())) (fun () -> Some "default") (fun () -> Util.msg "%s" Uicommon.shortUsageMsg; exit 1) From bcpierce at cis.upenn.edu Tue Jul 21 15:17:21 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Tue, 21 Jul 2009 15:17:21 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090721113949.GA8439@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> Message-ID: <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> > First thing, I think you can remove the dependency on unison-blob.o > from target macexecutable in Makefile.OCaml. At the moment, the Caml > files are compiled twice! Replace the line: > > macexecutable: $(NAME)-blob.o > > by just > > macexecutable: > OK, done. > Then, the patch had zero chance of working: the problem seems to > happen at an earlier stage, when the Caml code is linked, not when the > GUI is built. Can you try this, then: > >> make clean >> export ZERO_LINK=NO >> make Same failure. :-( > > If this still does not work, we have to investigate a bit more. The > compilation process fails at the final step when linking everything > together. The reason is that the two symbols below are not found: > >> Undefined symbols: >> "_caml_apply2", referenced from: >> _caml_callback2_exn in libasmrun.a(i386.o) >> "_caml_apply3", referenced from: >> _caml_callback3_exn in libasmrun.a(i386.o) > > These symbols should come from file unison-blob.o . You can check > they are indeed defined there with the following command: > >> nm unison-blob.o | grep caml_apply2 > 0000000000005000 T caml_apply2 > 0000000000003ef0 T caml_apply21 > 0000000000003b70 T caml_apply23 > 00000000000037c0 T caml_apply24 Output is a little different from yours: ~/current/unison/trunk/src> nm unison-blob.o | grep caml_apply2 000024b0 t _caml_apply2 But it looks like the one that the loader can't find is defined, at least. > If the symbols are not defined, we need to find out at which point > they disappear. You need to change this rule: > > $(NAME)-blob.o: $(CAMLOBJS) $(COBJS) > @echo Linking $@ > $(CAMLC) -output-obj -verbose $(CAMLFLAGS) ... > $(LD) -r -o $@ u-b.o $(COBJS) > $(RM) u-b.o > > into: > > $(NAME)-blob.o: $(CAMLOBJS) $(COBJS) > @echo Linking $@ > $(CAMLC) -dstartup -output-obj -verbose $ > (CAMLFLAGS) ... > $(LD) -r -o $@ u-b.o $(COBJS) > > (Add a "-dstartup" option to ocamlopt and remove the "rm" command.) > > Then, if you recompile, you should get two files u-b.o.startup.s and > u-b.o in the build directory. Then, again, you can use "nm u-b.o" to > find out whether caml_apply2 is defined in u-b.o. In the assembly > file, there should be some lines that look like this: > > [...] > .text > .align 16 > .globl caml_apply2 > caml_apply2: > subq $8, %rsp > [...] > > Tell me the last point where you could find caml_apply2 defined (the > corresponding output could be useful too). > > Now, if the symbols are actually defined in unison-blob.o, this may be > a problem with the order in which the files are given to gcc for > linking. So, in the following command (that should be a single line), > you can try to move unison-blob.o before -lasmrun. (Under Linux, I > have to put it before all the -lxxx, but this may different under > Mac OS X.) > >> /Developer/usr/bin/gcc-4.0 -arch i386 -isysroot /Developer/SDKs/ >> MacOSX10.5.sdk -L/Users/bcpierce/current/unison/trunk/src/uimacnew/ >> build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew/ >> build/Default -F/Users/bcpierce/current/unison/trunk/src/uimacnew - >> filelist /Users/bcpierce/current/unison/trunk/src/uimacnew/build/ >> uimacnew.build/Default/uimac.build/Objects-normal/i386/ >> Unison.LinkFileList -mmacosx-version-min=10.5 -L/usr/local/lib/ >> ocaml - >> lunix -lthreadsnat -lstr -lbigarray -lasmrun -framework Cocoa - >> framework Security -framework Growl -framework ExceptionHandling / >> Users/bcpierce/current/unison/trunk/src/uimacnew/../unison-blob.o - >> o / >> Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ >> Unison.app/Contents/MacOS/Unison Moving it earlier doesn't seem to help, unfortunately. ~/current/unison/trunk/src> /Developer/usr/bin/gcc-4.0 -arch i386 - isysroot /Developer/SDKs/MacOSX10.5.sdk -L/Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default -F/Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default -F/Users/bcpierce/current/ unison/trunk/src/uimacnew -filelist /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal/i386/Unison.LinkFileList -mmacosx-version-min=10.5 -L/usr/local/ lib/ocaml /Users/bcpierce/current/unison/trunk/src/uimacnew/../unison- blob.o -lunix -lthreadsnat -lstr -lbigarray -lasmrun -framework Cocoa - framework Security -framework Growl -framework ExceptionHandling -o / Users/bcpierce/current/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/MacOS/Unison Undefined symbols: "_caml_apply2", referenced from: _caml_callback2_exn in libasmrun.a(i386.o) "_caml_apply3", referenced from: _caml_callback3_exn in libasmrun.a(i386.o) ld: symbol(s) not found collect2: ld returned 1 exit status ~/current/unison/trunk/src> /Developer/usr/bin/gcc-4.0 -arch i386 - isysroot /Developer/SDKs/MacOSX10.5.sdk -L/Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default -F/Users/bcpierce/current/ unison/trunk/src/uimacnew/build/Default -F/Users/bcpierce/current/ unison/trunk/src/uimacnew /Users/bcpierce/current/unison/trunk/src/ uimacnew/../unison-blob.o -filelist /Users/bcpierce/current/unison/ trunk/src/uimacnew/build/uimacnew.build/Default/uimac.build/Objects- normal/i386/Unison.LinkFileList -mmacosx-version-min=10.5 -L/usr/local/ lib/ocaml -lunix -lthreadsnat -lstr -lbigarray -lasmrun -framework Cocoa -framework Security -framework Growl -framework ExceptionHandling -o /Users/bcpierce/current/unison/trunk/src/ uimacnew/build/Default/Unison.app/Contents/MacOS/Unison Undefined symbols: "_caml_apply2", referenced from: _caml_callback2_exn in libasmrun.a(i386.o) "_caml_apply3", referenced from: _caml_callback3_exn in libasmrun.a(i386.o) ld: symbol(s) not found collect2: ld returned 1 exit status Any more thoughts? - B From Jerome.Vouillon at pps.jussieu.fr Fri Jul 24 03:26:32 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Fri, 24 Jul 2009 09:26:32 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> Message-ID: <20090724072632.GA8786@pps.jussieu.fr> On Tue, Jul 21, 2009 at 03:17:21PM -0400, Benjamin Pierce wrote: > >> Undefined symbols: > >> "_caml_apply2", referenced from: > >> _caml_callback2_exn in libasmrun.a(i386.o) > >> "_caml_apply3", referenced from: > >> _caml_callback3_exn in libasmrun.a(i386.o) > > > > These symbols should come from file unison-blob.o . You can check > > they are indeed defined there with the following command: > > > >> nm unison-blob.o | grep caml_apply2 > > 0000000000005000 T caml_apply2 > > 0000000000003ef0 T caml_apply21 > > 0000000000003b70 T caml_apply23 > > 00000000000037c0 T caml_apply24 > > Output is a little different from yours: > > ~/current/unison/trunk/src> nm unison-blob.o | grep caml_apply2 > 000024b0 t _caml_apply2 The symbol is local (small t). That's why it is not used for linking. Now, we need to understand why. Is it also local in u-b.o? How is it defined in the assembly file? -- Jerome From bcpierce at cis.upenn.edu Fri Jul 24 17:21:02 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Fri, 24 Jul 2009 17:21:02 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090724072632.GA8786@pps.jussieu.fr> References: <4A5C9D12.80609@strank.info> <20090715152428.GC12895@pps.jussieu.fr> <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> <20090724072632.GA8786@pps.jussieu.fr> Message-ID: <75DF1304-9905-4EB8-A2C5-1C891C71E45A@cis.upenn.edu> OK, now nm u-b.o | grep apply2 yields 000024b0 t _caml_apply2 and the corresponding bit of u-b.o-startup.s looks like this: .text .align 4 .private_extern _caml_apply2 _caml_apply2: subl $12, %esp I'll append the whole file, in case that's useful. - B -------------- next part -------------- A non-text attachment was scrubbed... Name: u-b.o.startup.s Type: application/octet-stream Size: 92210 bytes Desc: not available Url : http://lists.seas.upenn.edu/pipermail/unison-hackers/attachments/20090724/51d50216/u-b.o.startup.bin -------------- next part -------------- On Jul 24, 2009, at 3:26 AM, Jerome Vouillon wrote: > On Tue, Jul 21, 2009 at 03:17:21PM -0400, Benjamin Pierce wrote: >>>> Undefined symbols: >>>> "_caml_apply2", referenced from: >>>> _caml_callback2_exn in libasmrun.a(i386.o) >>>> "_caml_apply3", referenced from: >>>> _caml_callback3_exn in libasmrun.a(i386.o) >>> >>> These symbols should come from file unison-blob.o . You can check >>> they are indeed defined there with the following command: >>> >>>> nm unison-blob.o | grep caml_apply2 >>> 0000000000005000 T caml_apply2 >>> 0000000000003ef0 T caml_apply21 >>> 0000000000003b70 T caml_apply23 >>> 00000000000037c0 T caml_apply24 >> >> Output is a little different from yours: >> >> ~/current/unison/trunk/src> nm unison-blob.o | grep caml_apply2 >> 000024b0 t _caml_apply2 > > The symbol is local (small t). That's why it is not used for linking. > Now, we need to understand why. Is it also local in u-b.o? How is it > defined in the assembly file? > > -- Jerome > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From Jerome.Vouillon at pps.jussieu.fr Sat Jul 25 03:22:21 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Sat, 25 Jul 2009 09:22:21 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <75DF1304-9905-4EB8-A2C5-1C891C71E45A@cis.upenn.edu> References: <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> <20090724072632.GA8786@pps.jussieu.fr> <75DF1304-9905-4EB8-A2C5-1C891C71E45A@cis.upenn.edu> Message-ID: <20090725072221.GA30016@pps.jussieu.fr> On Fri, Jul 24, 2009 at 05:21:02PM -0400, Benjamin Pierce wrote: > .text > .align 4 > .private_extern _caml_apply2 > _caml_apply2: > subl $12, %esp It looks like a bug in Ocaml 3.11.1: the fix to Ocaml bug #4690 breaks Unison. (http://caml.inria.fr/mantis/view.php?id=4690) Could you try to add the options "-cclib -keep_private_externs" and "-keep_private_externs" as follows in Makefile.Ocaml: $(NAME)-blob.o: $(CAMLOBJS) $(COBJS) @echo Linking $@ $(CAMLC) -output-obj -verbose -cclib -keep_private_externs ... $(LD) -r -keep_private_externs -o $@ u-b.o $(COBJS) $(RM) u-b.o This option is supposed to prevent the private external symbols to turn from global to static. -- Jerome From bcpierce at cis.upenn.edu Sat Jul 25 08:32:29 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Sat, 25 Jul 2009 08:32:29 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090725072221.GA30016@pps.jussieu.fr> References: <25ec8ca60907150839x64b9a185q43af76ba8be06a71@mail.gmail.com> <4A5E0045.8070301@strank.info> <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> <20090724072632.GA8786@pps.jussieu.fr> <75DF1304-9905-4EB8-A2C5-1C891C71E45A@cis.upenn.edu> <20090725072221.GA30016@pps.jussieu.fr> Message-ID: Nope, looks like still the same behavior... - B On Jul 25, 2009, at 3:22 AM, Jerome Vouillon wrote: > On Fri, Jul 24, 2009 at 05:21:02PM -0400, Benjamin Pierce wrote: >> .text >> .align 4 >> .private_extern _caml_apply2 >> _caml_apply2: >> subl $12, %esp > > It looks like a bug in Ocaml 3.11.1: the fix to Ocaml bug #4690 breaks > Unison. (http://caml.inria.fr/mantis/view.php?id=4690) > > Could you try to add the options "-cclib -keep_private_externs" and > "-keep_private_externs" as follows in Makefile.Ocaml: > > $(NAME)-blob.o: $(CAMLOBJS) $(COBJS) > @echo Linking $@ > $(CAMLC) -output-obj -verbose -cclib - > keep_private_externs ... > $(LD) -r -keep_private_externs -o $@ u-b.o $(COBJS) > $(RM) u-b.o > > This option is supposed to prevent the private external symbols to > turn from global to static. > > -- Jerome > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers From bcpierce at cis.upenn.edu Sun Jul 26 20:24:14 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Sun, 26 Jul 2009 20:24:14 -0400 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: <20090621130753.GA12070@pps.jussieu.fr> References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> Message-ID: <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> Hi Jerome, [Going back and cleaning emails that accumulated while I was out of town a few weeks ago...] The new behaviors seem reasonable to me. We should change the documentation to say where we're dropping atomicity. (Not that people read it, but still... :-) > - With this patch, errors deep inside a directory are not reported to > the user. Unison should report them all while still allowing to > propagate the directory. I guess this can be handled by adding an optional error annotation to directories in the result of update detection? > - Overwriting (or deleting) a directory with deep errors will fail > during propagation. We should either forbid the user from > attempting to overwrite such a directory, or relax the checks in > function Update.checkNoUpdates. (Or implement partial deletion.) Although we've already got a lot of switches, I wonder if we should add one more to control this. But I think the default should be the more convenient and slightly less safe way. Partial deletion seems confusing. Best, - Benjamin On Jun 21, 2009, at 9:07 AM, Jerome Vouillon wrote: > Hi Benjamin, > > On Mon, Jun 15, 2009 at 08:11:05AM -0400, Benjamin Pierce wrote: >> This is a longstanding issue. It's not a bug -- the behavior is not >> only "correct" but deeply built into the spec's definition of >> conflict. Of course, in practice it's often irritating, and by >> hindsight we should have designed it differently! But at this point >> it will take some careful thought to make it work differently, even >> as >> an option. (If anybody is up for giving it careful thought and >> creating a patch, I'd be glad to consider adding it.) > > I believe the following patch (against the developer version) does the > right thing (*). Then, there are some user interface issues: > - With this patch, errors deep inside a directory are not reported to > the user. Unison should report them all while still allowing to > propagate the directory. > - Overwriting (or deleting) a directory with deep errors will fail > during propagation. We should either forbid the user from > attempting to overwrite such a directory, or relax the checks in > function Update.checkNoUpdates. (Or implement partial deletion.) > > I will not have time to work further on this this week, though. > > (*) We have a change of behavior when one replica contains a directory > with a deep error at some location and the other does not contain a > directory there. Here are the different cases to consider: > 1) Propagating the directory. > a) The directory is not in the archive. > If the other side is unchanged, Unison will propagate everything > in the directory but the locations with an error and will update > the archives accordingly. The spec without the atomicity rule > allows this. (Note that, in this case, the change in function > Update.updateArchiveRec does nothing as the archives contain > NoArchive at the location of the error.) > If the other side is changed, the user has to force the > synchronization of the directory. Unison will propagate the > directory and update the archives the same way. We are outside > the scope of the spec, but I think Unison behaves reasonnably. > (b) The directory is in the archives. > In this case, the other side must have changed. So, the user > has to force the synchronization of the directory and we are > outside the scope of the spec. > The locations with errors are going to be removed from the > archives (change in Update.checkNoUpdatesRec). It is not clear > whether this is the right thing to do. One could argue both > ways. One may want to keep the previous archive contents as the > synchronization of these locations was not performed. On the > other hand, the user has chosen to propagate back the directory. > Clearing the archive is a way of taking this into account. > Also, this is easier to implement: this is exactly what we need > for propagation in case (1.b) and in Update.checkNoUpdatesRec in > case (2). > 2) Propagating the contents of the other replica. > Unison will not do anything by default, which is correct. > Forcing the deletion of the directory will either fail if the > errors are still there, or succeed if the locations corresponding > to an error are now empty (thanks to the change in function > Update.checkNoUpdatesRec). The spec without the atomicity rule > allows to remove every unchanged part from the directory. So, > what is done here is correct when we are under the scope of the > spec. > > -- Jerome > From bcpierce at cis.upenn.edu Sun Jul 26 21:07:09 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Sun, 26 Jul 2009 21:07:09 -0400 Subject: [Unison-hackers] Update detection optimization In-Reply-To: <20090716202834.GA24608@pps.jussieu.fr> References: <200907161933.n6GJXFYB000383@yaws.seas.upenn.edu> <20090716202834.GA24608@pps.jussieu.fr> Message-ID: <8BEFD8B2-8E79-4B34-86D5-7C40D756AA50@cis.upenn.edu> > ... > Finally, this is with xferbycopying disabled, otherwise Unison takes > 70% of its time filling the hash tables :-(. Should we reconsider this preference? (Did any of your recent changes improve the performance at all?) - B From Jerome.Vouillon at pps.jussieu.fr Mon Jul 27 08:57:39 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 27 Jul 2009 14:57:39 +0200 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> Message-ID: <20090727125739.GA18352@pps.jussieu.fr> Hi Benjamin, > >- With this patch, errors deep inside a directory are not reported to > > the user. Unison should report them all while still allowing to > > propagate the directory. > > I guess this can be handled by adding an optional error annotation > to directories in the result of update detection? This can be handled during reconciliation. I have extended the type [Common.replicas] to hold a list of errors for each replica. The [propagateErrors] function can now collect all errors in a directory instead of returing a single [Problem]. But this is mainly a UI issue. For the text UI, I use a difference arrow "--?->" to indicate a partial synchronization (feel free to change it if you have a better idea). The "show details" key will list all update detection errors. For the GTK UI, I use an orange arrow and their is a new "Details" button on the tool bar to get the list of errors. For both UIs, the number of partially transferred directories is also reported after transport. The Mac OS UI does not allow partial synchronization yet. > >- Overwriting (or deleting) a directory with deep errors will fail > > during propagation. We should either forbid the user from > > attempting to overwrite such a directory, or relax the checks in > > function Update.checkNoUpdates. (Or implement partial deletion.) > > Although we've already got a lot of switches, I wonder if we should > add one more to control this. But I think the default should be the > more convenient and slightly less safe way. Partial deletion seems > confusing. At the moment, I have not addressed this: deleting a directory with deep errors will fail during propagation. Maybe this is good enough? Unison will fail late, but the user still has a clear explanation of what went wrong. -- J?r?me From bcpierce at cis.upenn.edu Mon Jul 27 09:08:56 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 27 Jul 2009 09:08:56 -0400 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: <20090727125739.GA18352@pps.jussieu.fr> References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> <20090727125739.GA18352@pps.jussieu.fr> Message-ID: > But this is mainly a UI issue. For the text UI, I use a difference > arrow "--?->" to indicate a partial synchronization (feel free to > change it if you have a better idea). The "show details" key will > list all update detection errors. For the GTK UI, I use an orange > arrow and their is a new "Details" button on the tool bar to get the > list of errors. For both UIs, the number of partially transferred > directories is also reported after transport. The Mac OS UI does not > allow partial synchronization yet. --?-> and the orange arrow both seem a little too subtle -- I don't think most people will notice. What about err-> for the text UI? >>> - Overwriting (or deleting) a directory with deep errors will fail >>> during propagation. We should either forbid the user from >>> attempting to overwrite such a directory, or relax the checks in >>> function Update.checkNoUpdates. (Or implement partial deletion.) >> >> Although we've already got a lot of switches, I wonder if we should >> add one more to control this. But I think the default should be the >> more convenient and slightly less safe way. Partial deletion seems >> confusing. > > At the moment, I have not addressed this: deleting a directory with > deep errors will fail during propagation. Maybe this is good enough? > Unison will fail late, but the user still has a clear explanation of > what went wrong. Yes, this is probably OK for the moment. Deletion is pretty fast, so making people redo it from scratch is not a big deal. - B From Jerome.Vouillon at pps.jussieu.fr Mon Jul 27 09:42:07 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 27 Jul 2009 15:42:07 +0200 Subject: [Unison-hackers] Update detection optimization In-Reply-To: <8BEFD8B2-8E79-4B34-86D5-7C40D756AA50@cis.upenn.edu> References: <200907161933.n6GJXFYB000383@yaws.seas.upenn.edu> <20090716202834.GA24608@pps.jussieu.fr> <8BEFD8B2-8E79-4B34-86D5-7C40D756AA50@cis.upenn.edu> Message-ID: <20090727134207.GB18352@pps.jussieu.fr> On Sun, Jul 26, 2009 at 09:07:09PM -0400, Benjamin Pierce wrote: > > ... > > Finally, this is with xferbycopying disabled, otherwise Unison takes > > 70% of its time filling the hash tables :-(. > > Should we reconsider this preference? (Did any of your recent changes > improve the performance at all?) I think we should keep it on by default. My home directory is probably not a typical replica. I have large maildir immutable directories. For these directories, Unison does nothing but calling Xferhint.insertEntry. Thus, it is not surprising that it spends so much time there. Also, Xferhing.insertEntry is now more than twice as fast. (I have kept only one of the two hash tables, and I use a faster hash function.) On my home directory, Unison still spends about 50% of its time during update detection on filling the hash table, but update detection now takes less that one second, which is fast enough for me. For a long time, I had xferbycopying disabled, and it is now enabled. -- Jerome From Jerome.Vouillon at pps.jussieu.fr Mon Jul 27 10:07:34 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 27 Jul 2009 16:07:34 +0200 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> <20090727125739.GA18352@pps.jussieu.fr> Message-ID: <20090727140734.GC18352@pps.jussieu.fr> On Mon, Jul 27, 2009 at 09:08:56AM -0400, Benjamin Pierce wrote: > >But this is mainly a UI issue. For the text UI, I use a difference > >arrow "--?->" to indicate a partial synchronization (feel free to > >change it if you have a better idea). The "show details" key will > >list all update detection errors. For the GTK UI, I use an orange > >arrow and their is a new "Details" button on the tool bar to get the > >list of errors. For both UIs, the number of partially transferred > >directories is also reported after transport. The Mac OS UI does not > >allow partial synchronization yet. > > --?-> and the orange arrow both seem a little too subtle -- I don't > think most people will notice. Indeed, this is a little subtle. But is that so important? The next time the user will run Unison, he will get explicit errors, as the directory structure will have been transferred. What may happen is that the user wrongly believes that the replicas are fully synchronizated after transport. Maybe we should make it more visible when this is not the case. For instance, we could pop a summary window in the GTK UI. > What about err-> for the text UI? As you like. -- J?r?me From bcpierce at cis.upenn.edu Mon Jul 27 10:10:45 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 27 Jul 2009 10:10:45 -0400 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: <20090727140734.GC18352@pps.jussieu.fr> References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> <20090727125739.GA18352@pps.jussieu.fr> <20090727140734.GC18352@pps.jussieu.fr> Message-ID: >> --?-> and the orange arrow both seem a little too subtle -- I don't >> think most people will notice. > > Indeed, this is a little subtle. But is that so important? The next > time the user will run Unison, he will get explicit errors, as the > directory structure will have been transferred. > > What may happen is that the user wrongly believes that the replicas > are fully synchronizated after transport. Maybe we should make it > more visible when this is not the case. For instance, we could pop a > summary window in the GTK UI. This is a good idea. For the text UI, I guess the summary message at the end of the sync is enough. - B From Jerome.Vouillon at pps.jussieu.fr Mon Jul 27 10:14:24 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Mon, 27 Jul 2009 16:14:24 +0200 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: References: <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> <20090724072632.GA8786@pps.jussieu.fr> <75DF1304-9905-4EB8-A2C5-1C891C71E45A@cis.upenn.edu> <20090725072221.GA30016@pps.jussieu.fr> Message-ID: <20090727141423.GD18352@pps.jussieu.fr> On Sat, Jul 25, 2009 at 08:32:29AM -0400, Benjamin Pierce wrote: > Nope, looks like still the same behavior... I have submitted an Ocaml bug report. I don't know what else we can do. -- Jerome From bcpierce at cis.upenn.edu Mon Jul 27 10:19:24 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 27 Jul 2009 10:19:24 -0400 Subject: [Unison-hackers] Compiling under Mac OS X In-Reply-To: <20090727141423.GD18352@pps.jussieu.fr> References: <20090720104435.GA17390@pps.jussieu.fr> <07284F46-E19C-40B1-AA75-278286E71466@cis.upenn.edu> <20090720151648.GA21753@pps.jussieu.fr> <36970D55-CD22-49B7-9E20-95D4CBDA644C@cis.upenn.edu> <20090721113949.GA8439@pps.jussieu.fr> <172C1AEE-708A-4184-B0B0-4CFB5EB7D1B8@cis.upenn.edu> <20090724072632.GA8786@pps.jussieu.fr> <75DF1304-9905-4EB8-A2C5-1C891C71E45A@cis.upenn.edu> <20090725072221.GA30016@pps.jussieu.fr> <20090727141423.GD18352@pps.jussieu.fr> Message-ID: > I have submitted an Ocaml bug report. I don't know what else > we can do. OK. We can get along on old OCaml versions for the moment... - B From bostonvaulter at gmail.com Mon Jul 27 17:27:39 2009 From: bostonvaulter at gmail.com (Jason Axelson) Date: Mon, 27 Jul 2009 11:27:39 -1000 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> <20090727125739.GA18352@pps.jussieu.fr> <20090727140734.GC18352@pps.jussieu.fr> Message-ID: <21810b630907271427x38a26fd8g7e66943e7561507f@mail.gmail.com> On Mon, Jul 27, 2009 at 4:10 AM, Benjamin Pierce wrote: >>> --?-> and the orange arrow both seem a little too subtle -- I don't >>> think most people will notice. >> >> Indeed, this is a little subtle. ?But is that so important? ?The next >> time the user will run Unison, he will get explicit errors, as the >> directory structure will have been transferred. >> >> What may happen is that the user wrongly believes that the replicas >> are fully synchronizated after transport. ?Maybe we should make it >> more visible when this is not the case. ?For instance, we could pop a >> summary window in the GTK UI. > > This is a good idea. ?For the text UI, I guess the summary message at > the end of the sync is enough. Will the exit status be non-zero also? Jason From bcpierce at cis.upenn.edu Mon Jul 27 18:13:13 2009 From: bcpierce at cis.upenn.edu (Benjamin Pierce) Date: Mon, 27 Jul 2009 18:13:13 -0400 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: <21810b630907271427x38a26fd8g7e66943e7561507f@mail.gmail.com> References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> <20090727125739.GA18352@pps.jussieu.fr> <20090727140734.GC18352@pps.jussieu.fr> <21810b630907271427x38a26fd8g7e66943e7561507f@mail.gmail.com> Message-ID: <8A3B969D-9348-4FF5-AE52-3C8D929CF084@cis.upenn.edu> Seems like it should be... - B On Jul 27, 2009, at 5:27 PM, Jason Axelson wrote: > On Mon, Jul 27, 2009 at 4:10 AM, Benjamin Pierce > wrote: >>>> --?-> and the orange arrow both seem a little too subtle -- I don't >>>> think most people will notice. >>> >>> Indeed, this is a little subtle. But is that so important? The >>> next >>> time the user will run Unison, he will get explicit errors, as the >>> directory structure will have been transferred. >>> >>> What may happen is that the user wrongly believes that the replicas >>> are fully synchronizated after transport. Maybe we should make it >>> more visible when this is not the case. For instance, we could >>> pop a >>> summary window in the GTK UI. >> >> This is a good idea. For the text UI, I guess the summary message at >> the end of the sync is enough. > > Will the exit status be non-zero also? > > Jason > _______________________________________________ > Unison-hackers mailing list > Unison-hackers at lists.seas.upenn.edu > http://lists.seas.upenn.edu/mailman/listinfo/unison-hackers > From vouillon at seas.upenn.edu Wed Jul 29 10:34:18 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Wed, 29 Jul 2009 10:34:18 -0400 Subject: [Unison-hackers] [unison-svn] r381 - in trunk/src: . system system/generic system/win Message-ID: <200907291434.n6TEYIU4017103@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-29 10:34:18 -0400 (Wed, 29 Jul 2009) New Revision: 381 Modified: trunk/src/.depend trunk/src/RECENTNEWS trunk/src/fileinfo.ml trunk/src/fs.ml trunk/src/fs.mli trunk/src/mkProjectInfo.ml trunk/src/props.ml trunk/src/remote.ml trunk/src/system/generic/system_impl.ml trunk/src/system/system_generic.ml trunk/src/system/system_intf.ml trunk/src/system/system_win.ml trunk/src/system/system_win_stubs.c trunk/src/system/win/system_impl.ml trunk/src/transfer.ml trunk/src/uicommon.ml trunk/src/uigtk2.ml trunk/src/update.ml Log: * Disabled the new directory fast check optimization under Windows, as Windows does not update the directory modification time when a directory contents changes on a FAT filesystem. * Use inode numbers in fast check mode when using the Windows Unicode API or Cygwin * Do not print the "Connected [...]" message when both replicas are local Modified: trunk/src/.depend =================================================================== --- trunk/src/.depend 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/.depend 2009-07-29 14:34:18 UTC (rev 381) @@ -23,7 +23,7 @@ path.cmi: pred.cmi name.cmi pred.cmi: props.cmi: uutil.cmi ubase/prefs.cmi path.cmi osx.cmi fspath.cmi -recon.cmi: path.cmi common.cmi +recon.cmi: props.cmi path.cmi common.cmi remote.cmi: ubase/prefs.cmi lwt/lwt.cmi fspath.cmi common.cmi clroot.cmi \ bytearray.cmi sortri.cmi: common.cmi @@ -44,8 +44,7 @@ update.cmi: uutil.cmi tree.cmi props.cmi path.cmi osx.cmi os.cmi name.cmi \ lwt/lwt.cmi fspath.cmi fileinfo.cmi common.cmi uutil.cmi: -xferhint.cmi: props.cmi ubase/prefs.cmi path.cmi osx.cmi os.cmi fspath.cmi \ - fileinfo.cmi +xferhint.cmi: ubase/prefs.cmi path.cmi os.cmi fspath.cmi abort.cmo: uutil.cmi ubase/util.cmi ubase/trace.cmi ubase/prefs.cmi abort.cmi abort.cmx: uutil.cmx ubase/util.cmx ubase/trace.cmx ubase/prefs.cmx abort.cmi bytearray.cmo: bytearray.cmi @@ -94,8 +93,8 @@ fileutil.cmx: fileutil.cmi fingerprint.cmo: uutil.cmi ubase/util.cmi fspath.cmi fs.cmi fingerprint.cmi fingerprint.cmx: uutil.cmx ubase/util.cmx fspath.cmx fs.cmx fingerprint.cmi -fs.cmo: ubase/util.cmi fspath.cmi fs.cmi -fs.cmx: ubase/util.cmx fspath.cmx fs.cmi +fs.cmo: fspath.cmi fs.cmi +fs.cmx: fspath.cmx fs.cmi fspath.cmo: uutil.cmi ubase/util.cmi system.cmi ubase/rx.cmi path.cmi \ name.cmi fileutil.cmi fspath.cmi fspath.cmx: uutil.cmx ubase/util.cmx system.cmx ubase/rx.cmx path.cmx \ Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/RECENTNEWS 2009-07-29 14:34:18 UTC (rev 381) @@ -1,5 +1,15 @@ CHANGES FROM VERSION 2.37.1 +* Disabled the new directory fast check optimization under Windows, as + Windows does not update the directory modification time when a + directory contents changes on a FAT filesystem. +* Use inode numbers in fast check mode when using the Windows Unicode + API or Cygwin +* Do not print the "Connected [...]" message when both replicas are local + +------------------------------- +CHANGES FROM VERSION 2.37.1 + * Bumped version number: incompatible protocol changes * Create parent directories (with correct permissions) during Modified: trunk/src/fileinfo.ml =================================================================== --- trunk/src/fileinfo.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/fileinfo.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -149,7 +149,7 @@ fastcheck expects ctime to be preserved by renaming. Thus, we should probably not use any stamp under Windows. *) -let pretendLocalOSIsWin32 = +let ignoreInodeNumbers = Prefs.createBool "ignoreinodenumbers" false "!Use creation times for detecting updates" ("When set to true, this preference makes Unison not take advantage \ @@ -159,15 +159,13 @@ can be useful for synchronizing VFAT filesystems (which do not \ support inode numbers) mounted on Unix systems. \ The {\\tt fastcheck} option should also be set to true.") -let _ = Prefs.alias pretendLocalOSIsWin32 "pretendwin" +let _ = Prefs.alias ignoreInodeNumbers "pretendwin" let stamp info = (* Was "CtimeStamp info.ctime", but this is bogus: Windows ctimes are not reliable. *) - if Prefs.read pretendLocalOSIsWin32 then CtimeStamp 0.0 else - match Util.osType with - `Unix -> InodeStamp info.inode - | `Win32 -> CtimeStamp 0.0 + if Prefs.read ignoreInodeNumbers then CtimeStamp 0.0 else + if Fs.hasInodeNumbers () then InodeStamp info.inode else CtimeStamp 0.0 let ressStamp info = Osx.stamp info.osX Modified: trunk/src/fs.ml =================================================================== --- trunk/src/fs.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/fs.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -74,7 +74,7 @@ close_in ic; d -let canSetTime f = - System.canSetTime (Util.osType <> `Win32) (Fspath.toString f) +let canSetTime f = System.canSetTime (Fspath.toString f) +let hasInodeNumbers () = System.hasInodeNumbers () let setUnicodeEncoding = System.setUnicodeEncoding Modified: trunk/src/fs.mli =================================================================== --- trunk/src/fs.mli 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/fs.mli 2009-07-29 14:34:18 UTC (rev 381) @@ -6,6 +6,5 @@ include System_intf.Core with type fspath = Fspath.t val digestFile : Fspath.t -> string -val canSetTime : Fspath.t -> bool val setUnicodeEncoding : bool -> unit Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/mkProjectInfo.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -97,3 +97,4 @@ + Modified: trunk/src/props.ml =================================================================== --- trunk/src/props.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/props.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -227,7 +227,7 @@ (Fspath.toPrintString (Fspath.concat fspath path)) (syncedPartsToString (fp, mask)) (syncedPartsToString (fp', mask)) - (mask land (lnot (fp lxor fp'))))) + ((Prefs.read permMask) land (lnot (fp lxor fp'))))) let init someHostIsRunningWindows = let mask = if someHostIsRunningWindows then wind_mask else unix_mask in Modified: trunk/src/remote.ml =================================================================== --- trunk/src/remote.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/remote.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -34,10 +34,20 @@ (fun maj min -> (maj = 3 && min >= 11) || maj > 3) (* - Flow-control mechanism (only active under windows). + Flow-control mechanism (only active under Windows). Only one side is allowed to send messages at any given time. Once it has finished sending messages, a special message is sent meaning that the destination is now allowed to send messages. + + Threads behave in a very controlled way: they only perform possibly + blocking I/Os through the remote module, and never call + Lwt_unix.yield. This mean that when one side gives up its right to + write, we know that no longer how much we wait, it would not have + any thing to write. This ensures that there will be no deadlock. + A more robust protocol would be to give up write permission + whenever idle (not just after having sent at least one message). + But then, there is the risk that the two sides exchange spurious + messages. *) let needFlowControl = windowsHack let readOrWrite = needFlowControl && not recent_ocaml Modified: trunk/src/system/generic/system_impl.ml =================================================================== --- trunk/src/system/generic/system_impl.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/system/generic/system_impl.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -19,13 +19,5 @@ module Fs = struct include System_generic - let canSetTime win f = - not win || - try - Unix.access f [Unix.W_OK]; - true - with - Unix.Unix_error _ -> false - let setUnicodeEncoding _ = () end Modified: trunk/src/system/system_generic.ml =================================================================== --- trunk/src/system/system_generic.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/system/system_generic.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -71,3 +71,19 @@ let close_process_in = Unix.close_process_in let close_process_out = Unix.close_process_out let close_process_full = Unix.close_process_full + +(****) + +let isNotWindows = Sys.os_type <> "Win32" + +let canSetTime f = + isNotWindows || + try + Unix.access f [Unix.W_OK]; + true + with + Unix.Unix_error _ -> false + +(* Note that Cygwin provides some kind of inode numbers, but we only + have access to the lower 32 bits on 32bit systems... *) +let hasInodeNumbers () = isNotWindows Modified: trunk/src/system/system_intf.ml =================================================================== --- trunk/src/system/system_intf.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/system/system_intf.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -43,6 +43,12 @@ val open_in_bin : fspath -> in_channel val file_exists : fspath -> bool +(****) + + +val canSetTime : fspath -> bool +val hasInodeNumbers : unit -> bool + end module type Full = sig Modified: trunk/src/system/system_win.ml =================================================================== --- trunk/src/system/system_win.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/system/system_win.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -279,3 +279,12 @@ (Process_full(inchan, outchan, errchan)) in close_in inchan; close_out outchan; close_in errchan; snd(Unix.waitpid [] pid) + +(****) + +(* The new implementation of utimes does not have the limitation of + the standard one *) +let canSetTime f = true + +(* We provide some kind of inode numbers *) +let hasInodeNumbers () = true Modified: trunk/src/system/system_win_stubs.c =================================================================== --- trunk/src/system/system_win_stubs.c 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/system/system_win_stubs.c 2009-07-29 14:34:18 UTC (rev 381) @@ -281,8 +281,11 @@ v = caml_alloc (12, 0); Store_field (v, 0, Val_int (info.dwVolumeSerialNumber)); + /* The ocaml code truncates inode numbers to 31 bits. We hash the + low and high parts in order to lose as little information as + possible. */ Store_field - (v, 1, Val_int (MAKEDWORDLONG(info.nFileIndexLow,info.nFileIndexHigh))); + (v, 1, Val_int (MAKEDWORDLONG(info.nFileIndexLow,info.nFileIndexHigh)+155825701*((DWORDLONG)info.nFileIndexHigh))); Store_field (v, 2, Val_int (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 1: 0)); @@ -292,7 +295,7 @@ if (!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) mode |= 0000222; Store_field (v, 3, Val_int(mode)); - Store_field (v, 4, Val_int (1)); + Store_field (v, 4, Val_int (info.nNumberOfLinks)); Store_field (v, 5, Val_int (0)); Store_field (v, 6, Val_int (0)); Store_field (v, 7, Val_int (0)); Modified: trunk/src/system/win/system_impl.ml =================================================================== --- trunk/src/system/win/system_impl.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/system/win/system_impl.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -18,9 +18,6 @@ module System = System_win module Fs = struct - (* The new implementation of utimes does not have the limitation of - the standard one *) - let canSetTime win f = true let unicode = ref false @@ -60,4 +57,7 @@ let getcwd v = c1 W.getcwd G.getcwd v let chdir v = c1 W.chdir G.chdir v let readlink v = c1 W.readlink G.readlink v + + let canSetTime v = c1 W.canSetTime G.canSetTime v + let hasInodeNumbers v = c1 W.hasInodeNumbers G.hasInodeNumbers v end Modified: trunk/src/transfer.ml =================================================================== --- trunk/src/transfer.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/transfer.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -320,6 +320,8 @@ let weakLen = 31. This would save almost 3 bytes per block, but one need to be able to recover from an rsync error. + (We would have to take into account that our weak checksum is + only 31 bits.) *) (* Block size *) let computeBlockSize l = truncate (max 700. (min (sqrt l) 131072.)) Modified: trunk/src/uicommon.ml =================================================================== --- trunk/src/uicommon.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/uicommon.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -582,7 +582,9 @@ Update.storeRootsName (); - if not (Prefs.read contactquietly || Prefs.read Trace.terse) then + if + numRemote > 0 && not (Prefs.read contactquietly || Prefs.read Trace.terse) + then Util.msg "Connected [%s]\n" (Util.replacesubstring (Update.getRootsName()) ", " " -> "); Modified: trunk/src/uigtk2.ml =================================================================== --- trunk/src/uigtk2.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/uigtk2.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -1652,7 +1652,7 @@ let redisplay i = let (r1, action, r2, status, path) = columnsOf i in - mainWindow#freeze (); + (*mainWindow#freeze ();*) mainWindow#set_cell ~text:r1 i 0; displayArrow i i action; mainWindow#set_cell ~text:r2 i 2; @@ -1662,7 +1662,7 @@ mainWindow#set_cell ~text:(transcodeFilename path ^ " [failed: click on this line for details]") i 4; - mainWindow#thaw (); + (*mainWindow#thaw ();*) if !current = Some i then updateDetails (); updateButtons () in Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-21 13:10:32 UTC (rev 380) +++ trunk/src/update.ml 2009-07-29 14:34:18 UTC (rev 381) @@ -1150,6 +1150,11 @@ Props.dirMarkedUnchanged archDesc fastCheckInfos.dirStamp inode && Props.same_time info.Fileinfo.desc archDesc + && + (* Check the date is meaningful: the root directory of a FAT + filesystem does not have modification time, so the time returned + by [stat] is usually way in the past. *) + Props.time archDesc >= 631152000. (* Jan 1, 1990 *) (* Check whether a file's permissions have not changed *) let isPropUnchanged info archiveDesc = @@ -1551,7 +1556,10 @@ showStatus here; let fastCheckInfos = { fastCheck = useFastChecking (); - dirFastCheck = useFastChecking (); + (* Directory optimization is disabled under Windows, + as Windows does not update directory modification times + on FAT filesystems. *) + dirFastCheck = useFastChecking () && Util.osType = `Unix; dirStamp = dirStamp } in let (arch, ui) = From Jerome.Vouillon at pps.jussieu.fr Wed Jul 29 11:01:42 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Wed, 29 Jul 2009 17:01:42 +0200 Subject: [Unison-hackers] [unison-users] Unison aborts all the synchronization after a permission issue In-Reply-To: <21810b630907271427x38a26fd8g7e66943e7561507f@mail.gmail.com> References: <46D5E75E-627A-4052-87E0-068A44972845@cis.upenn.edu> <20090621130753.GA12070@pps.jussieu.fr> <23B46767-891B-4184-A294-D7EF3AA11B6C@cis.upenn.edu> <20090727125739.GA18352@pps.jussieu.fr> <20090727140734.GC18352@pps.jussieu.fr> <21810b630907271427x38a26fd8g7e66943e7561507f@mail.gmail.com> Message-ID: <20090729150142.GB580@pps.jussieu.fr> On Mon, Jul 27, 2009 at 11:27:39AM -1000, Jason Axelson wrote: > On Mon, Jul 27, 2009 at 4:10 AM, Benjamin Pierce wrote: > >>> --?-> and the orange arrow both seem a little too subtle -- I don't > >>> think most people will notice. > >> > >> Indeed, this is a little subtle. ?But is that so important? ?The next > >> time the user will run Unison, he will get explicit errors, as the > >> directory structure will have been transferred. > >> > >> What may happen is that the user wrongly believes that the replicas > >> are fully synchronizated after transport. ?Maybe we should make it > >> more visible when this is not the case. ?For instance, we could pop a > >> summary window in the GTK UI. > > > > This is a good idea. ?For the text UI, I guess the summary message at > > the end of the sync is enough. > > Will the exit status be non-zero also? The exit status is 1: some items were skipped, but no failure occurred. -- Jerome From vouillon at seas.upenn.edu Thu Jul 30 12:58:35 2009 From: vouillon at seas.upenn.edu (vouillon@seas.upenn.edu) Date: Thu, 30 Jul 2009 12:58:35 -0400 Subject: [Unison-hackers] [unison-svn] r382 - in trunk/src: . system ubase Message-ID: <200907301658.n6UGwZdt015125@yaws.seas.upenn.edu> Author: vouillon Date: 2009-07-30 12:58:35 -0400 (Thu, 30 Jul 2009) New Revision: 382 Modified: trunk/src/RECENTNEWS trunk/src/mkProjectInfo.ml trunk/src/system/system_generic.ml trunk/src/system/system_intf.ml trunk/src/system/system_win.ml trunk/src/system/system_win_stubs.c trunk/src/ubase/prefs.ml trunk/src/uitext.ml trunk/src/unicode.ml trunk/src/update.ml Log: * Windows text UI: now put the console into UTF-8 output mode. This is the right thing to do when in Unicode mode, and is no worse than what we had previously otherwise (the console use some esoteric encoding by default). This only works when using a Unicode font instead of the default raster font. * Windows text UI: put the terminal into raw mode * Incorrect paths ("path" directive) now result in an error update item rather than a fatal error. * Ignore any BOM (byte-order mark) character at the beginning of profile files (this character is produced by many tools under Windows) Modified: trunk/src/RECENTNEWS =================================================================== --- trunk/src/RECENTNEWS 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/RECENTNEWS 2009-07-30 16:58:35 UTC (rev 382) @@ -1,3 +1,18 @@ +CHANGES FROM VERSION 2.37.5 + +* Windows text UI: now put the console into UTF-8 output mode. This + is the right thing to do when in Unicode mode, and is no worse than + what we had previously otherwise (the console use some esoteric + encoding by default). This only works when using a Unicode font + instead of the default raster font. +* Windows text UI: put the terminal into raw mode +* Incorrect paths ("path" directive) now result in an error update + item rather than a fatal error. +* Ignore any BOM (byte-order mark) character at the beginning of + profile files (this character is produced by many tools under + Windows) + +------------------------------- CHANGES FROM VERSION 2.37.1 * Disabled the new directory fast check optimization under Windows, as Modified: trunk/src/mkProjectInfo.ml =================================================================== --- trunk/src/mkProjectInfo.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/mkProjectInfo.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -65,7 +65,7 @@ Str.matched_group 1 str;; let extract_int re str = int_of_string (extract_str re str);; -let revisionString = "$Rev: 378$";; +let revisionString = "$Rev: 382$";; let pointVersion = if String.length revisionString > 5 then Scanf.sscanf revisionString "$Rev: %d " (fun x -> x) - pointVersionOrigin else (* Determining the pointVersionOrigin in bzr is kind of tricky: @@ -98,3 +98,4 @@ + Modified: trunk/src/system/system_generic.ml =================================================================== --- trunk/src/system/system_generic.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/system/system_generic.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -87,3 +87,23 @@ (* Note that Cygwin provides some kind of inode numbers, but we only have access to the lower 32 bits on 32bit systems... *) let hasInodeNumbers () = isNotWindows + +(****) + +type terminalStateFunctions = + { defaultTerminal : unit -> unit; rawTerminal : unit -> unit; + startReading : unit -> unit; stopReading : unit -> unit } + +let terminalStateFunctions () = + let oldState = Unix.tcgetattr Unix.stdin in + { defaultTerminal = + (fun () -> Unix.tcsetattr Unix.stdin Unix.TCSANOW oldState); + rawTerminal = + (fun () -> + let newState = + { oldState with Unix.c_icanon = false; Unix.c_echo = false; + Unix.c_vmin = 1 } + in + Unix.tcsetattr Unix.stdin Unix.TCSANOW newState); + startReading = (fun () -> ()); + stopReading = (fun () -> ()) } Modified: trunk/src/system/system_intf.ml =================================================================== --- trunk/src/system/system_intf.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/system/system_intf.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -85,4 +85,9 @@ val close_process_full : in_channel * out_channel * in_channel -> Unix.process_status +type terminalStateFunctions = + { defaultTerminal : unit -> unit; rawTerminal : unit -> unit; + startReading : unit -> unit; stopReading : unit -> unit } +val terminalStateFunctions : unit -> terminalStateFunctions + end Modified: trunk/src/system/system_win.ml =================================================================== --- trunk/src/system/system_win.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/system/system_win.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -287,4 +287,33 @@ let canSetTime f = true (* We provide some kind of inode numbers *) +(* However, these inode numbers are not usable on FAT filesystems, as + renaming a file "b" over a file "a" does not change the inode + number of "a". *) let hasInodeNumbers () = true + +(****) + +external getConsoleMode : unit -> int = "win_get_console_mode" +external setConsoleMode : int -> unit = "win_set_console_mode" +external getConsoleOutputCP : unit -> int = "win_get_console_output_cp" +external setConsoleOutputCP : int -> unit = "win_set_console_output_cp" + +type terminalStateFunctions = + { defaultTerminal : unit -> unit; rawTerminal : unit -> unit; + startReading : unit -> unit; stopReading : unit -> unit } + +let terminalStateFunctions () = + let oldstate = getConsoleMode () in + let oldcp = getConsoleOutputCP () in + (* Ctrl-C does not interrupt a call to ReadFile when + ENABLE_LINE_INPUT is not set, so we handle Ctr-C + as a character when reading from the console. + We still want Ctrl-C to generate an exception when not reading + from the console in order to be able to interrupt Unison at any + time. *) + { defaultTerminal = (fun () -> setConsoleMode oldstate; + setConsoleOutputCP oldcp); + rawTerminal = (fun () -> setConsoleMode 0x19; setConsoleOutputCP 65001); + startReading = (fun () -> setConsoleMode 0x18); + stopReading = (fun () -> setConsoleMode 0x19) } Modified: trunk/src/system/system_win_stubs.c =================================================================== --- trunk/src/system/system_win_stubs.c 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/system/system_win_stubs.c 2009-07-30 16:58:35 UTC (rev 382) @@ -511,3 +511,64 @@ return w_create_process_native(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); } + +/****/ + +static HANDLE conin = INVALID_HANDLE_VALUE; + +static void init_conin () +{ + if (conin == INVALID_HANDLE_VALUE) { + conin = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, 0); + if (conin == INVALID_HANDLE_VALUE) { + win32_maperr (GetLastError ()); + uerror("init_conin", Nothing); + } + } +} + +CAMLprim value win_get_console_mode (value unit) +{ + DWORD mode; + BOOL res; + + init_conin (); + + res = GetConsoleMode (conin, &mode); + if (res == 0) { + win32_maperr (GetLastError ()); + uerror("get_console_mode", Nothing); + } + + return (Val_int (mode)); +} + +CAMLprim value win_set_console_mode (value mode) +{ + BOOL res; + + init_conin (); + + res = SetConsoleMode (conin, Int_val(mode)); + if (res == 0) { + win32_maperr (GetLastError ()); + uerror("set_console_mode", Nothing); + } + return (Val_unit); +} + +CAMLprim value win_get_console_output_cp (value unit) { + return (Val_int (GetConsoleOutputCP ())); +} + +CAMLprim value win_set_console_output_cp (value cp) { + BOOL res; + res = SetConsoleOutputCP (Int_val (cp)); + if (res == 0) { + win32_maperr (GetLastError ()); + uerror("set_console_cp", Nothing); + } + return (Val_unit); +} Modified: trunk/src/ubase/prefs.ml =================================================================== --- trunk/src/ubase/prefs.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/ubase/prefs.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -271,10 +271,20 @@ try System.open_in_bin (profilePathname filename) with Sys_error _ -> raise(Util.Fatal(Printf.sprintf "Preference file %s not found" filename)) in + let bom = "\xef\xbb\xbf" in (* BOM: UTF-8 byte-order mark *) let rec loop lines = match (try Some(input_line chan) with End_of_file -> None) with None -> close_in chan; parseLines filename lines - | Some(theLine) -> loop (theLine::lines) in + | Some(theLine) -> + let theLine = + (* A lot of Windows tools start a UTF-8 encoded file by a + byte-order mark. We skip it. *) + if lines = [] && Util.startswith theLine bom then + String.sub theLine 3 (String.length theLine - 3) + else + theLine + in + loop (theLine::lines) in loop [] (* Takes a list of strings in reverse order and yields a list of "parsed lines" Modified: trunk/src/uitext.ml =================================================================== --- trunk/src/uitext.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/uitext.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -25,12 +25,7 @@ let dumbtty = Prefs.createBool "dumbtty" - (match Util.osType with - `Unix -> - (try (System.getenv "EMACS" <> "") with - Not_found -> false) - | _ -> - true) + (try System.getenv "EMACS" <> "" with Not_found -> false) "!do not change terminal settings in text UI" ("When set to \\verb|true|, this flag makes the text mode user " ^ "interface avoid trying to change any of the terminal settings. " @@ -54,42 +49,41 @@ let cbreakMode = ref None +(* FIX: this may also work with Cygwin, but someone needs to try it... *) +let supportSignals = Util.osType = `Unix (*|| Util.isCygwin*) + let rawTerminal () = match !cbreakMode with - None -> () - | Some state -> - let newstate = - { state with Unix.c_icanon = false; Unix.c_echo = false; - Unix.c_vmin = 1 } - in - Unix.tcsetattr Unix.stdin Unix.TCSANOW newstate + None -> () + | Some funs -> funs.System.rawTerminal () let defaultTerminal () = match !cbreakMode with - None -> () - | Some state -> - Unix.tcsetattr Unix.stdin Unix.TCSANOW state - + None -> () + | Some funs -> funs.System.defaultTerminal () + let restoreTerminal() = - if Util.osType = `Unix && not (Prefs.read dumbtty) then + if supportSignals && not (Prefs.read dumbtty) then Sys.set_signal Sys.sigcont Sys.Signal_default; defaultTerminal (); cbreakMode := None let setupTerminal() = - if Util.osType = `Unix && not (Prefs.read dumbtty) then + if not (Prefs.read dumbtty) then try - cbreakMode := Some (Unix.tcgetattr Unix.stdin); + cbreakMode := Some (System.terminalStateFunctions ()); let suspend _ = defaultTerminal (); Sys.set_signal Sys.sigtstp Sys.Signal_default; Unix.kill (Unix.getpid ()) Sys.sigtstp in let resume _ = - Sys.set_signal Sys.sigtstp (Sys.Signal_handle suspend); + if supportSignals then + Sys.set_signal Sys.sigtstp (Sys.Signal_handle suspend); rawTerminal () in - Sys.set_signal Sys.sigcont (Sys.Signal_handle resume); + if supportSignals then + Sys.set_signal Sys.sigcont (Sys.Signal_handle resume); resume () with Unix.Unix_error _ -> restoreTerminal () @@ -109,14 +103,27 @@ if not (Prefs.read Globals.batch) then alwaysDisplay message let getInput () = - if !cbreakMode = None then - let l = input_line stdin in - if l="" then "" else String.sub l 0 1 - else - let c = input_char stdin in - let c = if c='\n' then "" else String.make 1 c in - display c; - c + match !cbreakMode with + None -> + let l = input_line stdin in + if l="" then "" else String.sub l 0 1 + | Some funs -> + let input_char () = + (* We cannot used buffered I/Os under Windows, as character + '\r' is not passed through (probably due to the code that + turns \r\n into \n) *) + let s = String.create 1 in + let n = Unix.read Unix.stdin s 0 1 in + if n = 0 then raise End_of_file; + if s.[0] = '\003' then raise Sys.Break; + s.[0] + in + funs.System.startReading (); + let c = input_char () in + funs.System.stopReading (); + let c = if c='\n' || c = '\r' then "" else String.make 1 c in + display c; + c let newLine () = if !cbreakMode <> None then display "\n" Modified: trunk/src/unicode.ml =================================================================== --- trunk/src/unicode.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/unicode.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -934,7 +934,11 @@ try let s' = norm s 0 l s' 0 in order s'; s' with Invalid -> - s + (* We need a comparison function which is coherent (transitive) + also with non-unicode strings. The optimization below assumes + a case-insensitive comparison on ASCII characters, thus we + translate the string to lowercase *) + String.lowercase s (****) Modified: trunk/src/update.ml =================================================================== --- trunk/src/update.ml 2009-07-29 14:34:18 UTC (rev 381) +++ trunk/src/update.ml 2009-07-30 16:58:35 UTC (rev 382) @@ -1598,24 +1598,30 @@ in match status with | `BadEnc -> - raise (Util.Transient - (Format.sprintf - "The filename %s in path %s is not encoded in Unicode" - (Name.toString name) (Path.toString fullpath))) + let error = + Format.sprintf + "The filename %s in path %s is not encoded in Unicode" + (Name.toString name) (Path.toString fullpath) + in + (archive, Error error, translatePathLocal fspath fullpath, []) | `BadName -> - raise (Util.Transient - (Format.sprintf - "The filename %s in path %s is not allowed under Windows" - (Name.toString name) (Path.toString fullpath))) + let error = + Format.sprintf + "The filename %s in path %s is not allowed under Windows" + (Name.toString name) (Path.toString fullpath) + in + (archive, Error error, translatePathLocal fspath fullpath, []) | `Dup -> - raise (Util.Transient - (Format.sprintf - "The path %s is ambiguous at filename %s (i.e., the name \ - of this path is the same, modulo capitalization, as \ - another path in a case-sensitive filesystem, and you are \ - synchronizing this filesystem with a case-insensitive \ - filesystem." - (Path.toString fullpath) (Name.toString name))) + let error = + Format.sprintf + "The path %s is ambiguous at filename %s (i.e., the name \ + of this path is the same, modulo capitalization, as \ + another path in a case-sensitive filesystem, and you are \ + synchronizing this filesystem with a case-insensitive \ + filesystem." + (Path.toString fullpath) (Name.toString name) + in + (archive, Error error, translatePathLocal fspath fullpath, []) | `Ok -> match archive with ArchiveDir (desc, children) -> From petersj at in.tum.de Fri Jul 31 11:35:14 2009 From: petersj at in.tum.de (Janosch Peters) Date: Fri, 31 Jul 2009 15:35:14 +0000 (UTC) Subject: [Unison-hackers] Undefined Symbols Message-ID: Hi list, I get undefined symbols if I compile with UISTYLE=gtk2. I have gtk2 @2.16.3_0+no_x11+quartz installed. Is this supposed to work or do I need the x11 variant? The output I get is the following: Undefined symbols: "_fcntl$UNIX2003", referenced from: _caml_sys_open in libasmrun.a(sys.o) _unix_set_nonblock in libunix.a(fcntl.o) _unix_set_nonblock in libunix.a(fcntl.o) _unix_clear_nonblock in libunix.a(fcntl.o) _unix_clear_nonblock in libunix.a(fcntl.o) _unix_set_close_on_exec in libunix.a(fcntl.o) _unix_set_close_on_exec in libunix.a(fcntl.o) _unix_clear_close_on_exec in libunix.a(fcntl.o) _unix_clear_close_on_exec in libunix.a(fcntl.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) _unix_lockf in libunix.a(lockf.o) "_tcdrain$UNIX2003", referenced from: _unix_tcdrain in libunix.a(termios.o) "_pthread_cond_init$UNIX2003", referenced from: _caml_threadstatus_new in libthreadsnat.a(posix_n.o) _caml_condition_new in libthreadsnat.a(posix_n.o) "_open$UNIX2003", referenced from: _caml_sys_open in libasmrun.a(sys.o) _unix_open in libunix.a(open.o) "_write$UNIX2003", referenced from: _unix_write in libunix.a(write.o) _unix_single_write in libunix.a(write.o) _do_write in libasmrun.a(io.o) _caml_ba_map_file in libbigarray.a(mmap_unix.o) "_waitpid$UNIX2003", referenced from: _unix_waitpid in libunix.a(wait.o) "_strerror$UNIX2003", referenced from: _caml_sys_error in libasmrun.a(sys.o) _caml_pthread_check in libthreadsnat.a(posix_n.o) _unix_error_message in libunix.a(errmsg.o) "_sigsuspend$UNIX2003", referenced from: _unix_sigsuspend in libunix.a(signals.o) "_kill$UNIX2003", referenced from: _unix_kill in libunix.a(kill.o) "_fchmod$UNIX2003", referenced from: _unix_fchmod in libunix.a(fchmod.o) "_getrlimit$UNIX2003", referenced from: _segv_handler in libasmrun.a(signals_asm.o) "_close$UNIX2003", referenced from: _caml_close_channel in libasmrun.a(io.o) _caml_ml_close_channel in libasmrun.a(io.o) _caml_sys_close in libasmrun.a(sys.o) _unix_close in libunix.a(close.o) _alloc_sockaddr in libunix.a(socketaddr.o) "_pthread_sigmask$UNIX2003", referenced from: _caml_thread_tick in libthreadsnat.a(posix_n.o) _caml_thread_sigmask in libthreadsnat.a(posix_n.o) "_strtod$UNIX2003", referenced from: _caml_float_of_substring in libasmrun.a(floats.o) _caml_float_of_string in libasmrun.a(floats.o) "_read$UNIX2003", referenced from: _caml_do_read in libasmrun.a(io.o) _unix_read in libunix.a(read.o) "_wait$UNIX2003", referenced from: _unix_wait in libunix.a(wait.o) "_sleep$UNIX2003", referenced from: _unix_sleep in libunix.a(sleep.o) "_select$UNIX2003", referenced from: _caml_thread_tick in libthreadsnat.a(posix_n.o) _unix_select in libunix.a(select.o) "_fputs$UNIX2003", referenced from: _caml_fatal_error in libasmrun.a(misc.o) _caml_parse_engine in libasmrun.a(parsing.o) "_sigaltstack$UNIX2003", referenced from: _caml_init_signals in libasmrun.a(signals_asm.o) "_sigwait$UNIX2003", referenced from: _caml_wait_signal in libthreadsnat.a(posix_n.o) "_chmod$UNIX2003", referenced from: _unix_chmod in libunix.a(chmod.o) "_system$UNIX2003", referenced from: _caml_sys_system_command in libasmrun.a(sys.o) "_mktime$UNIX2003", referenced from: _unix_mktime in libunix.a(gmtime.o) ld: symbol(s) not found collect2: ld returned 1 exit status ** BUILD FAILED ** The following build commands failed: uimac: Ld /Users/jp/Code/unison/trunk/src/uimacnew/build/Default/ Unison.app/Contents/MacOS/Unison normal i386 (1 failure) From Jerome.Vouillon at pps.jussieu.fr Fri Jul 31 15:12:54 2009 From: Jerome.Vouillon at pps.jussieu.fr (Jerome Vouillon) Date: Fri, 31 Jul 2009 21:12:54 +0200 Subject: [Unison-hackers] Undefined Symbols In-Reply-To: References: Message-ID: <20090731191254.GA11884@pps.jussieu.fr> Hi, On Fri, Jul 31, 2009 at 03:35:14PM +0000, Janosch Peters wrote: > I get undefined symbols if I compile with UISTYLE=gtk2. I have gtk2 > @2.16.3_0+no_x11+quartz installed. Is this supposed to work or do I > need the x11 variant? The output I get is the following: [...] > Ld /Users/jp/Code/unison/trunk/src/uimacnew/build/Default/ > Unison.app/Contents/MacOS/Unison normal i386 I don't know whether the GTK UI works under Mac O X. But what you are attempting to build here is the native UI. Are you really running the following command: make UISTYLE=gtk2 -- Jerome