Sunday, 25 September 2011

Autoresizing Masks in the Cocoa Framework

I've been struggling a bit to get my head around exactly how the different UIViewAutoresizing values work together. This post is an examination of trying out various combinations and documenting the effects.

The first thing to do is set up two views, one within the other. Then, the autoresizingMask of the inner view is set and the frame of the outer view changed.

This is what the two views look like before any resizing:


Below are the results of changing the size of the outer view's frame, using various values for the inner view's autoresizingMask property.

UIViewAutoresizingNone:
This causes the inner view's frame to remain unchanged.


UIViewAutoresizingFlexibleTopMargin:
This causes only the y coordinate of the inner view's frame to change.


UIViewAutoresizingFlexibleBottomMargin:
This causes the inner view's frame to remain unchanged.


UIViewAutoresizingFlexibleLeftMargin:
This causes only the x coordinate of the inner view's frame to change.


UIViewAutoresizingFlexibleRightMargin:
This causes the inner view's frame to remain unchanged.


UIViewAutoresizingFlexibleWidth:
This causes only the width of the inner view's frame to change.


UIViewAutoresizingFlexibleHeight:
This causes only the height of the inner view's frame to change.


UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight:
This causes the y coordinate and height of the inner view's frame to change.


UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth:
This causes the x coordinate and width of the inner view's frame to change.

Saturday, 17 September 2011

MacPorts & Mono

Problem updating MacPorts and have Mono installed? Read on...

I was setting up my Mac Book Pro so that I could work on the RapidFTR project and I ran into some trouble. The instructions for installing and running RapidFTR on OSX specify that MacPorts should be installed. Having downloaded the installer for version 2.0.1, I ran the sudo port selfupdate command as suggested; here began my trouble:


---> Updating MacPorts base sources using rsync
MacPorts base version 2.0.1 installed,
MacPorts base version 2.0.3 downloaded.
---> MacPorts base is outdated, installing new version 2.0.3
Installing new MacPorts release in /opt/local as root:admin; permissions 0755; Tcl-Package in /Library/Tcl

Error: /opt/local/bin/port: port selfupdate failed: Error installing new MacPorts base: shell command failed (see log for details)


This wasn't particularly helpful, though there was a vague statement about some log file (nothing so helpful as where this file might be located though!). Having no idea where to look for the log, I looked in /var/log. This contained a bunch of log files, though none of them looked specific to MacPorts. OK, I thought, perhaps it puts them in system.log.

Turns out it doesn't.

My next idea was to look in install.log, as an update is a kind of installation, right?

Turns out it doesn't put it in here either.

However, what I DID see in here was the output from running the original 2.0.1 installer package. It turns out that this had also tried to perform an update and it too had failed (not that it reported this when I ran it, mind). Amongst its output there was a suggestion of running the selfupdate command with the -d flag to get more specific output. Running this command produced the following output (only the key part is included):


In file included from entryobj.c:36:
/Library/Frameworks/Mono.framework/Versions/2.10.3/include/sqlite3.h:252: warning: ISO C90 does not support ‘long long’
/Library/Frameworks/Mono.framework/Versions/2.10.3/include/sqlite3.h:253: warning: ISO C90 does not support ‘long long’
/usr/bin/cc -dynamiclib -g -O2 -W -Wall -pedantic -I/Library/Frameworks/Mono.framework/Versions/2.10.3/include -Wl,-single_module registry.o util.o entry.o entryobj.o ../cregistry/cregistry.a -o registry.dylib -L/System/Library/Frameworks/Tcl.framework/Versions/8.5 -ltclstub8.5 -L/Library/Frameworks/Mono.framework/Versions/2.10.3/lib -lsqlite3
ld: warning: ignoring file /Library/Frameworks/Mono.framework/Versions/2.10.3/lib/libsqlite3.dylib, file was built for unsupported file format which is not the architecture being linked (x86_64)
Undefined symbols for architecture x86_64:
"_sqlite3_errmsg", referenced from:
_set_sqlite_result in util.o
_reg_sqlite_error in cregistry.a(registry.o)
_reg_detach in cregistry.a(registry.o)
_reg_close in cregistry.a(registry.o)
_reg_attach in cregistry.a(registry.o)
_reg_open in cregistry.a(registry.o)
"_sqlite3_mprintf", referenced from:
_set_object in util.o
_set_entry in util.o
_get_object in util.o
_reg_sqlite_error in cregistry.a(registry.o)
_reg_detach in cregistry.a(registry.o)
_reg_attach in cregistry.a(registry.o)
_reg_open in cregistry.a(registry.o)
...

<!--Bunch of other _sqlite* symbols-->
...
"_sqlite3_changes", referenced from:
_reg_entry_delete in cregistry.a(entry.o)
_reg_entry_deactivate in cregistry.a(entry.o)
_reg_entry_activate in cregistry.a(entry.o)
_reg_entry_unmap in cregistry.a(entry.o)
"_sqlite3_column_text", referenced from:
_reg_entry_files in cregistry.a(entry.o)
_reg_entry_imagefiles in cregistry.a(entry.o)
_reg_entry_propget in cregistry.a(entry.o)
"_sqlite3_value_text", referenced from:
_sql_regexp in cregistry.a(sql.o)
"_sqlite3_result_int", referenced from:
_sql_regexp in cregistry.a(sql.o)
"_sqlite3_result_error", referenced from:
_sql_regexp in cregistry.a(sql.o)
"_sqlite3_create_function", referenced from:
_init_db in cregistry.a(sql.o)
"_sqlite3_create_collation", referenced from:
_init_db in cregistry.a(sql.o)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make[2]: *** [registry.dylib] Error 1
make[1]: *** [all] Error 1
make: *** [all] Error 1
shell command "cd /opt/local/var/macports/sources/rsync.macports.org/release/tarballs/base && CC=/usr/bin/cc ./configure --prefix=/opt/local --with-tclpackage=/Library/Tcl --with-install-user=root --with-install-group=admin --with-directory-mode=0755 --enable-readline && make && make install" returned error 2
DEBUG: Error installing new MacPorts base: shell command failed (see log for details)
while executing
"macports::selfupdate [array get global_options] base_updated"
Error: /opt/local/bin/port: port selfupdate failed: Error installing new MacPorts base: shell command failed (see log for details)


This seemed to suggest that it might be something to do with the Mono installation I had…With this extra information in hand, I was finally able to perform a search that turned up a useful result (in fact it was the only result). Buried within this set of email threads was the key message:


> It appears the problem is MacPorts is grabbig SQLite from
>
> /Library/Frameworks/Mono.framework/Versions/2.10.3/include/sqlite3.h
>
> Obviously, part of the problem is that the version of SQlite being
> found/used is from the Mono SDK (installed from go-mono.com),
> installed at /Library/Frameworks/Mono.framework.

You nailed it: that's precisely the issue.

>
> The odd thing: As far as I can tell, MacPorts should be using the
> frameworks in /opt/local/Library/Frameworks:
> (from the configure script output:)
> checking for Frameworks installation directory...
> /opt/local/Library/Frameworks
>
> What do I need to do to get 'port selfupdate' to ignore the Mono framework
> in
> /Library/Frameworks
> And use the one(s) in
> /opt/local/Library/Frameworks?

In this instance, when MacPorts is checking that directory it is for
creating it and not using it. MacPorts will use the SQLite from:
/usr/include/sqlite3.h
or applicable Xcode SDKs.

As a workaround, I'd recommend you move the mono framework temporarily out
of /Library/Frameworks, selfupdate MacPorts, and then put your Mono
framework back.


So I tried doing this (sudo mv /Library/Frameworks/Mono.framework/ ), et voilĂ , retrying the MacPort selfupdate worked!