6

I cannot get this macro to compile the correct code.

Here is the code: enter image description here

Here are the build settings (I'm doing a Release build): enter image description here Note that the GCC documentation says -Dname will define as 1, so I omitted the "=1" for Release: enter image description here

Here is the compile log showing that the definition (in yellow) was passed along on the command line: enter image description here

Here is my output log showing that the code is compiled as if ADD_CAMERA_FEATURE is not defined: enter image description here

If I put #define ADD_CAMERA_FEATURE 1 in the source, the #ifdef works as expected, but I also get a warning that I am redefining an existing macro. So XCode knows that the macro should exist from the build scheme settings, but still does not include the #ifdef branch of code.

Other details:

  1. XCode 5.1
  2. OS X 10.9.2
  3. iOS 7.1

My objective here is to have a target for building iOS 7 version of the app and a target for building a pre-iOS 7 version of the app, both from the same source. I have to support older devices that cannot be upgraded to iOS 7 for a while longer. Perhaps there is a better way to go about this. Any suggestions about how to accomplish this would be appreciated.

Chuck Krutsinger
  • 2,830
  • 4
  • 28
  • 50
  • 1
    Did you clean your project? – bbarnhart Mar 12 '14 at 18:31
  • Just tried a clean and build. Same result. – Chuck Krutsinger Mar 12 '14 at 22:11
  • The compile log shows that you are doing a release build. Please try the same thing doing a debug build. Does it work properly there? (I ask because I can't reproduce the problem here.) – matt Mar 12 '14 at 22:28
  • I can't reproduce the problem for a release build or a debug build. It works as expected (except that I'm using NSLog, not DDLogInfo; hey you might try that just in case) – matt Mar 12 '14 at 22:35
  • Are you defining this for the project or target? Keep in mind that target defines **replace** project defines. That is, if you define A=1 in your project and B=1 in your target, unless you're careful A=1 won't be applied. – Steven Fisher Mar 12 '14 at 22:58
  • @matt: I changed to NSLog as suggested and removed all reference to DEBUG macro as that is not the focus. I need the ADD_CAMERA_FEATURE flag to work. It still doesn't. The whole post has been updated withe the latest results. – Chuck Krutsinger Mar 12 '14 at 22:59
  • @StevenFisher: The post has been edited to clarify that the define in the scheme settings is not being recognized by the #ifdef. If I put a #define for that in the source, the #ifdef does work as expected. However, I don't want that in the source because I want to be able to build 2 targets, one with the feature and one without the feature, both from the same source. Is there a better way to do this? – Chuck Krutsinger Mar 12 '14 at 23:02
  • Could you try one more thing? Could you make a _new_ project and just do the preprocessor macro definitions in the build settings and put the `ifdef` stuff in your `application:didFinishLaunchingWithOptions:`? I just want you to demonstrate to yourself that this should work - that there is something peculiar about the project where it _doesn't_ work. – matt Mar 12 '14 at 23:03
  • Did you change the name of this project? It is weird how your CompileC line has put into something called "HANDIPatientWf iOS 7" when your project seems to be called just plain "HANDIPatientWf". I'm wondering whether something hasn't gotten out of whack here. – matt Mar 12 '14 at 23:10
  • Also please note that clean and build is not really enough. You should be doing the extensive cleaning that I describe here: http://stackoverflow.com/questions/5714372/how-to-empty-caches-and-clean-all-targets-xcode-4/6247073#6247073 – matt Mar 12 '14 at 23:17
  • @matt "HANDIPatientWf iOS 7" is the name of the target. The project is named "HANDIPatientWf" and has to run on older devices that can't support iOS 7, so "HANDIPatientWf iOS 7" is a copy of the original target specifically for adding the new features that require iOS 7. – Chuck Krutsinger Mar 12 '14 at 23:22
  • @matt I just now built a simple project and placing the ADD_CAMERA_FEATURE into the scheme setting worked exactly as expected. Which still leaves me at a loss as to why the project above doesn't work as expected. I need to find a way to have 2 different targets for iOS 7 and for older devices. – Chuck Krutsinger Mar 12 '14 at 23:24
  • Well, I just expanded my little project to do what you've just described - I have two targets, two schemes, and in one target there is `ADD_CAMERA_FEATURE` and in the other there is not, and when I build and run under each scheme, _that_ works correctly. There is nothing wrong with your approach. I would almost wonder whether your schemes are misaligned to the targets, except that the build log and the duplicate macro warning suggests they are not. – matt Mar 13 '14 at 00:53
  • 1
    **Scheme** settings? Are you sure about that? Maybe you mean configuration, target or project? – Steven Fisher Mar 13 '14 at 01:43
  • @StevenFisher Not sure. The settings are the build settings for the target. The same name that shows up for the target also shows up under the list of schemes when you open the manage schemes dialog. So I'm not sure of the correct terminology, but the screen shots of the settings I'm describing are in the post. – Chuck Krutsinger Mar 13 '14 at 03:00
  • @StevenFisher the scheme determines which target will be built – matt Mar 13 '14 at 05:18
  • @ChuckKrutsinger is it possible there is an #undef somewhere that we don't see? – matt Mar 13 '14 at 12:02
  • @matt There is no use of undef anywhere in the workspace. – Chuck Krutsinger Mar 13 '14 at 14:25
  • 1
    @ChuckKrutsinger Could you run that file through the preprocessor? I can see from the syntax coloring in the first screen shot that it thinks it's going to run the first NSLog. The preprocessor should confirm that for us. – matt Mar 13 '14 at 15:39
  • @matt Just found the problem. See the answer I just posted. – Chuck Krutsinger Mar 13 '14 at 15:43
  • Good work! I was about to suggest that the file you were editing (showing in the screen shot) was apparently not the code you were running, but I couldn't imagine how on earth that could be. – matt Mar 13 '14 at 15:48
  • Preprocessor defines from the scheme do not affect the build configuration. They affect only the scheme pre/post processing. – Steven Fisher Mar 13 '14 at 19:43
  • @matt: Scheme affects which target is built, and which configuration. It does not affect that configuration, so adding preprocessor defines to the scheme doesn't make sense. – Steven Fisher Mar 17 '14 at 16:43

1 Answers1

5

Found the problem. It has to do with targets and dependencies. I created a new target to compile the source file and added the preprocessor definition to that target. That compiled object then got linked into a static library being used as a framework. So I also created a new target for the static library. Unfortunately, I overlooked that the static library target was still depending on the original compile step that did not include the preprocessor definition. As a result, even though I was building the object file correctly, the new object file was not the one being linked into the project at runtime. So under Build Phases for the static library, I needed to change the target dependency to the correct object file and everything began to work. Thanks @matt and @StevenFisher for pointing me toward the right settings.

enter image description here

Chuck Krutsinger
  • 2,830
  • 4
  • 28
  • 50