cc1obj: error: type '<built-in>' does not have a known size
(void)
, a typo that should have been (void *)
.mach_absolute_time
is the finest-grained timer in the system. Here's a little utility to time a block:
#import <mach/mach_time.h> // for mach_absolute_time() and friends CGFloat BWTimeBlock (void (^block)(void)) { mach_timebase_info_data_t info; if (mach_timebase_info (&info) != KERN_SUCCESS) return -1; uint64_t start = mach_absolute_time (); block (); uint64_t end = mach_absolute_time (); uint64_t elapsed = end - start; uint64_t nanos = elapsed * info.numer / info.denom; return (CGFloat)nanos / NSEC_PER_SEC; } // BWTimeBlockAnd you would use it like:
NSString *thing1 = @"hi"; NSString *thing2 = @"hello there"; time = BWTimeBlock(^{ for (int i = 0; i < LOOPAGE; i++) { [thing1 isEqualTo: thing2]; } }); printf ("equalTo time: %f\n", time);
@executable_path/../blah
. Sometimes you get a library from someone else (or something generated by a gigantic configure script) and need to change the install name. The install_name_tool
will do that for you. Say I had a library, libbork.dylib, that will end up being placed side-by-side with the executable of a cocoa app, this is how I would fix it:
% install_name_tool -id @executable_path/libbork.dylib ./libbork.dylib
In Interface Builder 2: If you hold down the control key while resizing, though, the contents obey their spring configurations and will resize accordingly. Makes the process a whole lot easier.
In Interface Builder 3: If you hold down command while resizing, the contents obey their spring configurations and will resize accordingly. (This avoids the annoying process of resizing each widget within the windows afterwards.) Holding option while resizing will display the pixel values of the padding. Holding command-option while dragging displays both.
(muchos thankos to Quinn Taylor at the BYU CocoaHeads for the IB3 update)
% gcc -E -dM -x c /dev/null
(thanks to xmath on #macdev for this one)
% otool -L /path/to/application.app/Contents/MacOS/application
The problem is, if I include the usefulStuff.c
in my plugin and my test harness, there are two copies of the static variables, and the test harness can't control the plugin. If I don't include usefulStuff.c
in the plugin I get link errors. If I don't declare as weak linked the functions I use, I'll get errors when the final program loads the plugin. Sucks to be me.
Here's one way of doing it (which is kinda hacky, but after spending a day inside of the ld man page, and other pain, the fact it works is good enough for me for right now).
In the source file for the plugin that uses stuff from usefulStuff:
Declare the function to be weak:
extern void BWDebugLog (int blah, char *blah) __attribute__((weak_import));(you can also do this in your header files. In this case, I didn't want to touch the header)
Before you use the function, make sure it's not NULL
. Note there's no trailing ()
after the function name.
if (BWDebugLog != NULL) { BWDebugLog (23, "stuff"); }In the Xcode project for the plugin
Add the flags -flat_namespace
and -undefined dynamic_lookup
to the "Other Linker Flags" (a.k.a. OTHER_LDFLAGS
). The flat namespace lets the symbols be found in the test harness when the plugin is loaded. The undefined dynamic_lookup means to suppress warnings about undefined symbols. This could conceivably mask errors, but it's no worse than ZeroLink.
In the Xcode project for the test harness
Add usefulStuff.c
, and turn on the "Preserve Private External Symbols" checkbox (a.k.a -keep_private_externs
). That turns the symbol BWDebugLog
(and others) into exported symbols that'll be visible to the plugin. Otherwise the plugin will never get past that != NULL
check earlier.
Once all that's done, my plugin loads into the test harness and can get controlled. It can be loaded into the Real App without undefined symbol errors.
2009-06-01 12:49:29.447 otest[70099:203] *** NSTask: Task create for path '/blah/blah/blah' failed: 8, "Exec format error". Terminating temporary process.
You can force otest to run a particular architecture with the arch command:
% arch -arch i386 /Developer/Tools/otest build/Debug/Snoogle.octest
BWNagType.h:23: `BWConcreteType' defined as wrong kind of tag
In this particular case, I had a type I had declared with:
@class BWConcreteType;
and later on I had decided to turn it into an enum:
typedef enum BWConcreteType { ... } BWConcreteType;
without removing the previous @class
declaration. So be on the look out for conflicting types for the same symbol.