Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
lord funk
Feb 16, 2004

Hell yeah:

Only registered members can see post attachments!

Adbot
ADBOT LOVES YOU

Star War Sex Parrot
Oct 2, 2003

What am I looking at? IntelliSense?

Kallikrates
Jul 7, 2002
Pro Lurker

Star War Sex Parrot posted:

What am I looking at? IntelliSense?

Code completion selected NSString instead of NSStream.

Toady
Jan 12, 2009

Kallikrates posted:

Code completion selected NSString instead of NSStream.

That's been in Xcode for a while. However, I recently learned you have to press enter rather than tab for code completion to learn your choice. Based on the release notes, it looks like the code completion ships with default data that already returns common items first.

wolffenstein
Aug 2, 2002
 
Pork Pro

Star War Sex Parrot posted:

Wait what? Your Mini is bricked?
The iOS beta expired yesterday. When a beta expires, it locks the devices and renders it unusable until either a new beta or gold master is installed.

Lesson: don't install betas on production or personal-use devices.

Glimm
Jul 27, 2005

Time is only gonna pass you by

Toady posted:

That's been in Xcode for a while. However, I recently learned you have to press enter rather than tab for code completion to learn your choice. Based on the release notes, it looks like the code completion ships with default data that returns common items first.

Really? This is why even after months of training XCode it wants me to use NSLoadedClasses instead of NSLog?

I thought it was just Apple telling me to use the god damned debugger.

Star War Sex Parrot
Oct 2, 2003

wolffenstein posted:

The iOS beta expired yesterday. When a beta expires, it locks the devices and renders it unusable until either a new beta or gold master is installed.
You can always DFU-update back to the currently released version.

This is also presumably why they quickly released a beta 5 on Saturday that turned out to be the GM.

lord funk
Feb 16, 2004

Star War Sex Parrot posted:

What am I looking at? IntelliSense?

Code completion has been terrible for me since they first announced that code completion was better.

Toady posted:

That's been in Xcode for a while. However, I recently learned you have to press enter rather than tab for code completion to learn your choice. Based on the release notes, it looks like the code completion ships with default data that already returns common items first.

Thaaaat explains a lot. I always tabbed through.

dizzywhip
Dec 23, 2005

Is anyone else having trouble with the unused variables warning since upgrading Xcode? Any globally-declared variables I have in header files now give me an unused variable warning even if I'm using them elsewhere.

I guess this happens because I'm declaring them with the static keyword, like this:

code:
static NSString* SomeNotification = @"SomeNotification";
I'm not really an expert in plain C, so I'm not 100% sure on how declaring that as static is supposed to work. I know this is C 101 territory, but the way it's working seems to contradict what I've read. In this context it seems that it's supposed to make the variable visible only within that file. Since it's declared in a header file, it makes sense that it would be flagged as being unused, since it can only be used in that file and there's no code in there to use it. However, it's definitely not hidden from other files because I've been using these variables elsewhere for a long time.

If I take the static keyword off, I get duplicate-symbol linker errors, which I guess makes sense because the header file is being included in multiple places.

The only way I've found to get this to compile without warnings is to declare it with extern instead of static, then define it again in an implementation file. Is that really the only way to create a global string constant like this? It's annoying to have to maintain each one in two places, but in my case it would also require a ton of refactoring and extra code in certain areas.

I can also just disable the warnings I suppose, but I actually find them useful when they're caused by real problems.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Gordon Cole posted:

The only way I've found to get this to compile without warnings is to declare it with extern instead of static, then define it again in an implementation file.

This is correct.

Feel free to put a const after the * if you like.

LP0 ON FIRE
Jan 25, 2006

beep boop


I'm using build phases in a Cocos2D project to run a sed script to find and replace in a ton of tmx files. This runs before the sources compile. I've used sed before with success, but not a replace that has a ton of carriage returns in it.

Huge edit: I mentioned a bunch of reasons why I thought it didn't work, but I reduced it to searching for strings where it's wildcard has carriage returns in it.

In this example I'm trying to do a find and replace it with "test":

code:
sed -i '' 's{<tileset firstgid="1((.|\n|\r)*)<layer name="background" width="223" height="75">{test{g' Resources/maps_sideScrolling/ruinsItemCave2.tmx;
Eventually I'll want to replace the string with all the text from another text file and change the source file to all tmx files in Resources/maps_sideScrolling/

I've tested searching for strings without carriage returns in it's wildcard area, so I know having returns is the problem.

LP0 ON FIRE fucked around with this message at 22:15 on Jan 29, 2013

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Gordon Cole posted:

In this context it seems that it's supposed to make the variable visible only within that file. Since it's declared in a header file, it makes sense that it would be flagged as being unused, since it can only be used in that file and there's no code in there to use it. However, it's definitely not hidden from other files because I've been using these variables elsewhere for a long time.
Each translation unit has its own copy of the variable, which is is hidden from all of the other translation units (not other files).

One way to avoid having to declare each variable twice is the following:

In foo.h:
code:
#ifdef BUILDING_FOO_M
#define FOO_H_EXTERN(var, value) var = value;
#else
#define FOO_H_EXTERN(var, value) extern var;
#endif

FOO_H_EXTERN(NSString *FooNotification, @"FooNotification")

#undef FOO_H_EXTERN
In foo.m:
code:
#define BUILDING_FOO_M
#import "foo.h"
This is obviously only worth it if you're exporting a bunch of symbols.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Gordon Cole posted:

Is anyone else having trouble with the unused variables warning since upgrading Xcode? Any globally-declared variables I have in header files now give me an unused variable warning even if I'm using them elsewhere.

I guess this happens because I'm declaring them with the static keyword, like this:

If it's static, it's not being used elsewhere; every translation unit gets its own variable.

That warning is about global variables that you declared but never used, and it has a very important special-case exception: global constants. I'm guessing that's really what you want, right? You've got this key string that you want to use in a bunch of places, and you don't want to have to write it over and over again and maybe typo it a few times. That's perfectly reasonable, but the problem is that the compiler doesn't know that's what you're trying to do, because you didn't actually make the variable constant. Just slap the const qualifier on it — in this case, it has to go after the pointer, like this:

code:
NSString * const SomeNotification = @"SomeNotification";

dizzywhip
Dec 23, 2005

rjmccall posted:

If it's static, it's not being used elsewhere; every translation unit gets its own variable.

That warning is about global variables that you declared but never used, and it has a very important special-case exception: global constants. I'm guessing that's really what you want, right? You've got this key string that you want to use in a bunch of places, and you don't want to have to write it over and over again and maybe typo it a few times. That's perfectly reasonable, but the problem is that the compiler doesn't know that's what you're trying to do, because you didn't actually make the variable constant. Just slap the const qualifier on it — in this case, it has to go after the pointer, like this:

code:
NSString * const SomeNotification = @"SomeNotification";

That's exactly what I'm trying to do, and that makes perfect sense. Using const fixes the warning. Thanks everyone for the advice.

eschaton
Mar 7, 2007

Don't you just hate when you wind up in a store with people who are in a socioeconomic class that is pretty obviously about two levels lower than your own?

Gordon Cole posted:

code:

static NSString* SomeNotification = @"SomeNotification";

Since it's declared in a header file

...

The only way I've found to get this to compile without warnings is to declare it with extern instead of static, then define it again in an implementation file. Is that really the only way to create a global string constant like this?

Ultimately this boils down to understanding C's compilation model, which Objective-C and C++ both adopt as well. Each source file is seen independently by the compiler, as a stream of bytes, with the contents of included/imported headers pasted literally into that stream at the point of inclusion/import; the compiler knows nothing about file Bar.m when compiling Foo.m. This differs greatly from Java and its clone C#, where an import is semantic and the compiler is allowed to have insight into other compilation units.

This results in the need, in C-based languages, to understand and embrace the distinction between declaration and definition.

This is what you need to do to crate a global constant string variable in Objective-C given this compilation model. The full declaration in your header file should look something like this

code:

MY_EXPORT NSString * const MyNotification;

where MY_EXPORT is a macro for extern or extern "C" depending on whether you're compiling for (Objective-) C or C++. See the various frameworks' *Defines.h headers for how to do this. (The C++ distinction is needed to ensure a different symbol isn't generated for anything to which name mangling is applied, like functions.)

The definition of your global constant string in your implementation file should look something like this

code:

NSString * const MyNotification = @"MyNotification";

since this is where the "real value" of the variable is set.

The presence and placement of const is also important: It tells the compiler, when it can only see the declaration (because it's compiling another file that imports your header), that the pointer value stored in that global variable is forever-unchanging. That lets the compiler generate better code, as it doesn't have to assume after every call to something external to the compilation unit it's working on that the value could have changed.

dizzywhip
Dec 23, 2005

Thanks for the insight. I've had a vague idea about how this kind of stuff works but I've never taken the time to sit down and learn it, so this is very helpful. Based on what rjmccall explained, using the const keyword means that there's no need to have a separate declaration and definition though, right? I suppose what happens is that the separate compilation units each receive their own declaration and definition by importing the header file, but that since it's declared as a constant, it realizes that they all point to the same thing so it doesn't complain. Is that right?

Doc Block
Apr 15, 2003
Fun Shoe
Not quite. Each implementation file that references the header that declares your constant gets its own declaration, but if you have multiple (public) definitions then the linker will complain.

The key is the "extern" keyword in the declaration. This lets the compiler know that the actual definition is somewhere else. The "const" keyword just tells the compiler that the value doesn't change.

The compilation model for C/C++/Objective-C is that each implementation file is compiled separately and then linked together at the end. But before an implementation file gets compiled, it gets sent through the preprocessor, which sees stuff like #import <UIKit/UIKit.h> and replaces it with the actual contents of UIKit.h. Once the preprocessor is done, its output gets sent to the compiler. The compiler itself never sees those preprocessor directives, and never knows what's in any of the other compilation units.

So when you have something like
code:
extern NSString * const FooConstant;
in the header file, it's just telling the compiler that FooConstant is defined in another compilation module (i.e. another implementation file) and not to worry if it can't find the definition in the current implementation file. It will be up to the linker to reconcile all this with the definition.

In one of your implementation files you've got to define FooConstant, like
code:
NSString * const FooConstant = @"Whatever";
And once all the implementation files have been compiled the linker links them all together, and in the process reconciles all the object files referencing FooConstant with the actual definition of FooConstant.

Doc Block fucked around with this message at 08:39 on Jan 30, 2013

haveblue
Aug 15, 2005



Toilet Rascal
Has anyone else been getting the following error a lot since upgrading to Xcode 4.6? It happens intermittently and I can't figure out what to do to make it go away.


clang: error: unable to execute command: posix_spawn failed: Resource temporarily unavailable
clang: error: clang frontend command failed due to signal (use -v to see invocation)
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: i386-apple-darwin12.2.0
Thread model: posix
clang: note: diagnostic msg: PLEASE submit a bug report to http://developer.apple.com/bugreporter/ and include the crash backtrace, preprocessed source, and associated run script.
clang: error: unable to execute command: posix_spawn failed: Resource temporarily unavailable
clang: note: diagnostic msg: Error generating preprocessed source(s).
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 255

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
I've seen similar errors when I hit my process limit.

haveblue
Aug 15, 2005



Toilet Rascal
Huh. There's a vast number of zombie processes from the project I'm working on hanging around. Any idea what might be holding them? Relaunching Xcode or the simulator app doesn't make them go away.

LP0 ON FIRE
Jan 25, 2006

beep boop
I don't mean to ask a question here again so soon, though my last question is more of a general sed regex question than obj-c, so maybe I'll ask somewhere else.

I'm sort of having a design problem with a game I've been working on for a while and I was wondering if anyone could give some insight. I have an enemy class that I use in Cocos2D. For every instance of an enemy, the class is initialized and added to an array. There's a timer that ticks 60 times a second that checks various things that have to do with the enemies, as well as increasing a number for every one of the enemies to determine how they behave. This is done by calling a method from an instance of an enemy. But since this class holds all the behavioral data for a ton of enemies, it has to check what kind of enemy it is determined by a string. So now in the enemy class method to determine the behavior I have a list of a hundred or so if/else if statements of all the enemy names, along with all their behaviors, and that's just going to grow and grow. I really want to separate this out for every enemy into different files, but I'm not sure what the best approach is. Maybe subclassing it somehow, but it would be really awful to redefine all their objects and primitives. Maybe there's another way I'm not aware of?

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane

LP0 ON FIRE posted:

I don't mean to ask a question here again so soon, though my last question is more of a general sed regex question than obj-c, so maybe I'll ask somewhere else.

I'm sort of having a design problem with a game I've been working on for a while and I was wondering if anyone could give some insight. I have an enemy class that I use in Cocos2D. For every instance of an enemy, the class is initialized and added to an array. There's a timer that ticks 60 times a second that checks various things that have to do with the enemies, as well as increasing a number for every one of the enemies to determine how they behave. This is done by calling a method from an instance of an enemy. But since this class holds all the behavioral data for a ton of enemies, it has to check what kind of enemy it is determined by a string. So now in the enemy class method to determine the behavior I have a list of a hundred or so if/else if statements of all the enemy names, along with all their behaviors, and that's just going to grow and grow. I really want to separate this out for every enemy into different files, but I'm not sure what the best approach is. Maybe subclassing it somehow, but it would be really awful to redefine all their objects and primitives. Maybe there's another way I'm not aware of?

Why isn't each enemy type a subclass of the main enemy class? This is pretty much a textbook example of an occasion to use subclassing, and while it might suck to convert it, it's going to suck more to maintain what you have, no matter how you break it up into different files.

haveblue
Aug 15, 2005



Toilet Rascal

LP0 ON FIRE posted:

But since this class holds all the behavioral data for a ton of enemies, it has to check what kind of enemy it is determined by a string.

This is exactly what subclassing was designed to do, so you don't have to make your own system for it.

quote:

Maybe subclassing it somehow, but it would be really awful to redefine all their objects and primitives.

Less awful than continuing to deal with the existing system, I guarantee. There's probably a way to retain some of the benefits of unified functionality (like making a superclass for them that manages their sprite or what have you) but continuing to write gigantic strings of if-else statements is just going to make your project a bigger mess.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Depending on how complex the behaviour is, you could also pass it in as a block when initializing your enemy.

Something like (untested):

Objective-C code:
@interface MyEnemy : NSObject

-(id)initWithBlock:(void (^)(id param))tickBlock;
-(void)tick:(id)param;

@end

@implementation MyEnemy {
    void (^_tickBlock) (id);
}

-(id)initWithBlock:(void (^)(id param))tickBlock
{
    self = [super init];
    
    if (self) {
        _tickBlock = tickBlock;
    }
    
    return self;
}

-(void)tick:(id)param;
{
    _tickBlock(param);
}

@end


//wherever you call the ticks

MyEnemy *newEnemy = [[MyEnemy alloc] initWithBlock:^void(id param) {
    //do stuff with param
}];
So every time you call -tick: with some param, the block is invoked with that parameter and you can decide what to do. That way, you won't need subclasses, but instead just initialize enemies with different types of blocks.

LP0 ON FIRE
Jan 25, 2006

beep boop
Okay, well I guess that is the only way out of this. I'm just trying to get my head around how this will work out smoothly. But I'll definitely keep on truckin through this and I'm sure I'll feel a lot better in the end. I'll probably ask some questions relating to it later. Thanks.

Carthag posted:

Depending on how complex the behaviour is, you could also pass it in as a block when initializing your enemy.

So every time you call -tick: with some param, the block is invoked with that parameter and you can decide what to do. That way, you won't need subclasses, but instead just initialize enemies with different types of blocks.

I'm really unfamiliar with this, but this sounds really cool and I could probably use it for other things inside the enemy class too.

This is an example of one of an enemy's behavior checkers:

code:
if(_actionCount == 1){ //pause movement
	
	if(_actionMode == 1){
		
		_actionCount = 200;
		
		_senseRadius = 0;
		
		_faceHeroToNotice = NO;
		
		[_movement setString:@"none"];
		
		_origin = CGPointMake(_sprite.position.x,_sprite.position.y); //set new origin for float effect
		
		[self playAction:@"float"];
		
	}else{
		
		_noticedHero = YES;
		
		_faceHeroToNotice = YES;
		
		_senseRadius = 0;
		
		[_movement setString:@"none"];
		
	}
	
}

else if(_actionCount == 20){
	
	[self changeAnimationFramesWithBehaviorString:@"rush"]; //change to rush animation here
	
}

else if(_actionCount == 40){ //charge toward hero
	
	_speed = _speedRush;
	
	[_movement setString:@"horizontal"];
	
}

else if(_actionCount == 140){ //back to normal movement and switch action mode
	
	_actionCount = 999;
	_actionMode = 1;
	
	_noticedHero = NO;
	_speed = _speedMax;
	
	[_movement setString:@"horizontal"];
	
	_senseRadius = _senseRadiusDefault;
	
	[self changeAnimationFramesWithBehaviorString:@"normal"];
	
}

else if(_actionCount == 270){
	
	ect, etc...
Reading about blocks now. :)

LP0 ON FIRE fucked around with this message at 22:29 on Jan 30, 2013

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Doc Block posted:

Not quite. Each implementation file that references the header that declares your constant gets its own declaration, but if you have multiple (public) definitions then the linker will complain.

The key is the "extern" keyword in the declaration. This lets the compiler know that the actual definition is somewhere else. The "const" keyword just tells the compiler that the value doesn't change.

This isn't quite true. In C++ (and ObjC++), const global variables implicitly get internal linkage unless explicitly marked extern. You do not need to define them in some concrete file.

In C (and ObjC), you need to explicitly give your global constants internal linkage by saying static const. Since that works in C++ as well, it's generally accepted as the best idiom for a header-file, compile-time constant.

Your advice of declaring constants in the header and defining them somewhere else is really only designed for things that you really do need to give external linkage to. For most constants, doing that is actively worse than giving them internal linkage: it forces the variable to actually exist and forces uses to actually load from it, whereas otherwise the compiler would be free to materialize the constant in its own way. And generally constants (including string data, even ObjC strings) will be uniqued by the linker, so duplicating them across translation units has no runtime cost.

That said, there can be good reasons to intentionally give external linkage to constant data: if you really rely on the address of the data in some way, or if it's a large pool of data (like an array) that you really want to ensure isn't duplicated between translation units. But otherwise I wouldn't.

This does get complicated in C++ with static const member variables of classes. The problem there is that class members always have external linkage, which means they need to be defined if they're used in a way that relies on their address, which unfortunately is very easy to do in C++ because templated functions generally take their arguments by reference. But this is how it is.

unpurposed
Apr 22, 2008
:dukedog:

Fun Shoe
With this talk of the C compilation chain, can anyone recommend a great overview of what actually happens during a build (i.e, linking, compilation, etc.)?

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



LP0 ON FIRE posted:

I'm really unfamiliar with this, but this sounds really cool and I could probably use it for other things inside the enemy class too.

This is an example of one of an enemy's behavior checkers:

code:
//snip
Reading about blocks now. :)

the hard thing about blocks is mostly just unfamiliar syntax. Once you get used to that, a whole lot of cool poo poo becomes super easy to do.

One thing I would do, btw, is use enums instead of strings for your movement types & behaviour types. Aside from the comparison being simple == equality, you also get compile-time checks so you don't have to worry about misspellings &c.

haveblue
Aug 15, 2005



Toilet Rascal
You can also do case statements, which are a lot more efficient to write and execute than chains of ifs.

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane

gooby on rails posted:

You can also do case statements, which are a lot more efficient to write and execute than chains of ifs.

Still a massive pain in the rear end to maintain compared to proper subclassing. If this is the only thing you're going to have to ever deal with by enemy type, maybe it's not too bad, but I almost guarantee there will be at least one other thing eventually. It is an absolute maintenance nightmare, and I say this having done it before and seeing the results. Yes, you will spend time to make the change, but you're going to save it down the road with almost 100% likelihood. So while a switch statement would be better than if-chains, it's still a fairly bad solution to this specific problem (if I'm understanding the problem correctly).

haveblue
Aug 15, 2005



Toilet Rascal
Oh absolutely, I just meant that to apply to the NSString vs enum argument. Definitely convert the project over to a class hierarchy before anything else.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

gooby on rails posted:

execute than chains of ifs.

FYI: if else blocks will tend to compile into switch statements in LLVM, though I wish I could find the documentation on that (I swear it was on this list.

Doing a switch on an enum also has the added benefit of LLVM yelling at you if you miss a case.

Yodzilla
Apr 29, 2005

Now who looks even dumber?

Beef Witch
Does anyone know of any changes made to the MPMoviePlayerController in iOS 6? In iOS 5 the following code worked perfectly fine for adding an embedded themed player to a scrollview and have it auto play but in iOS 6 absolutely nothing happens:
code:
player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:videoPath]];
player.view.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
//[player.view setBackgroundColor:[UIColor colorWithRed:255/255.0f green:48/255.0f blue:211/255.0f alpha:1.0f]];

player.shouldAutoplay = YES;
[player setControlStyle:MPMovieControlStyleEmbedded];
[scrollView addSubview:player.view];
The commented out background color there is just me testing if the player view is actually added to the scrollview and it definitely is. However no errors are being thrown and just nothing happens. No controls are presented to the user and there's no indication that anything is happening to actually play the movie.

I did find this bug report about viewWillAppear being called on fullscreen but that doesn't seem to apply to my case.

haveblue
Aug 15, 2005



Toilet Rascal

ultramiraculous posted:

Doing a switch on an enum also has the added benefit of LLVM yelling at you if you miss a case.

And the added drawback of LLVM yelling at you if you don't have a case for the meaningless element you put on the end to keep track of the number of meaningful elements.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

gooby on rails posted:

And the added drawback of LLVM yelling at you if you don't have a case for the meaningless element you put on the end to keep track of the number of meaningful elements.

If you really need this, just define a 'last' enumerator, initialize it to the last real enumerator, and make 'count' a constant outside the enum defined to that + 1. Yes, it's slightly more maintenance work, but take it from someone whose code does a *lot* of exhaustive switches, it is worthwhile just to get that warning on your side.

Doh004
Apr 22, 2007

Mmmmm Donuts...
I'm setting up our iOS CI server. Gonna run with TeamCity as that's what we use for our .NET builds. I also want to integrate this into Testflight and push our new builds when we do our test builds. I've found some good documentation on how to do all of this, but I was curious if you guys had any caveats or things I should look out for?

j.peeba
Oct 25, 2010

Almost Human
Nap Ghost
I tried out Codea on the iPad for the first time yesterday. Turns out that it's loads of fun! :)

https://www.youtube.com/watch?v=2iZoAYyCZrc

It feels very similar to Processing except that it, you know, runs on iPad and uses Lua. Using an external keyboard is pretty much a must.

Doh004
Apr 22, 2007

Mmmmm Donuts...

Doh004 posted:

I'm setting up our iOS CI server. Gonna run with TeamCity as that's what we use for our .NET builds. I also want to integrate this into Testflight and push our new builds when we do our test builds. I've found some good documentation on how to do all of this, but I was curious if you guys had any caveats or things I should look out for?

Ran into a hitch. We have a mac mini we'll be using as our build machine. There's an admin account, and "Account B" which is also an admin.

I've got TC up and running under the Account B account. It works great. I want TC to startup when the server boots up, as well as not having to login to the actual account to get TC to run. I'd be fine to do this on Windows, but never done it on a Mac.

I followed these instructions: http://confluence.jetbrains.com/dis...yserveronMacOSX

It even works when I run the command manually. But when I restart the computer, it doesn't get launched and I don't see anything in any of the logs. Has anyone else run into this issue?

ManicJason
Oct 27, 2003

He doesn't really stop the puck, but he scares the hell out of the other team.
You're saying it runs correctly when you run launchctl load /Library/LaunchDaemons/jetbrains.teamcity.server.plist? My first guess would be a file permission issue on that file, but if it runs when you manually start the service with launchctl then I'm at a bit of a loss.

edit: It looks like, if the plist is owned by someone short of root, a user may still be able to start the service by calling launchctl load, but the OS will not be able to run it when it tries to do so as root on a boot. Make sure the .plist is chown root and chmod 755.

ManicJason fucked around with this message at 06:44 on Feb 1, 2013

Adbot
ADBOT LOVES YOU

Doh004
Apr 22, 2007

Mmmmm Donuts...

ManicJason posted:

You're saying it runs correctly when you run launchctl load /Library/LaunchDaemons/jetbrains.teamcity.server.plist? My first guess would be a file permission issue on that file, but if it runs when you manually start the service with launchctl then I'm at a bit of a loss.

edit: It looks like, if the plist is owned by someone short of root, a user may still be able to start the service by calling launchctl load, but the OS will not be able to run it when it tries to do so as root on a boot. Make sure the .plist is chown root and chmod 755.

This was actually the case, good job! Turns out it was owned by "Account B" and in the right group, and it didn't like it until it was owned by root. I still specified the users that TC should run in so I think I should be okay. Thank you :)

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply