2

Today I decided I wanted to code up a Screen Saver using Xcode for my mac and wanted to do most of the heavy lifting in C++. From my previous experience mixing C++ and Objective-C++, you just need to change the extension of the .m source files to .mm when you want to incorporate some C++ in there.

I am running into an annoying issue, however. If I make an Xcode Screen Saver project and do nothing but rename the initial TestScreenSaverView.m file to TestScreenSaverView.mm, the Screen Saver goes from compiling and linking fine to compiling and having trouble linking. Note that other than changing the extension of the files, I have not added any new code. Here is the log output:

Showing Recent Issues
Check dependencies

Write auxiliary files

write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver.hmap
write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-generated-files.hmap
write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-all-target-headers.hmap
write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-own-target-headers.hmap
write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-project-headers.hmap
write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-all-non-framework-target-headers.hmap
/bin/mkdir -p /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64
write-file /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaver.LinkFileList

Create product structure

/bin/mkdir -p /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/TestScreensaver.saver/Contents
/bin/mkdir -p /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/TestScreensaver.saver/Contents/MacOS

ProcessInfoPlistFile /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/TestScreensaver.saver/Contents/Info.plist TestScreensaver/Info.plist
    cd /Users/cjh/Documents/code/swift/TestScreensaver
    builtin-infoPlistUtility /Users/cjh/Documents/code/swift/TestScreensaver/TestScreensaver/Info.plist -expandbuildsettings -platform macosx -o /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/TestScreensaver.saver/Contents/Info.plist

CompileC /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaverView.o TestScreensaver/TestScreensaverView.mm normal x86_64 objective-c++ com.apple.compilers.llvm.clang.1_0.compiler
    cd /Users/cjh/Documents/code/swift/TestScreensaver
    export LANG=en_US.US-ASCII
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c++ -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu++14 -stdlib=libc++ -fobjc-arc -fobjc-weak -fmodules -gmodules -fmodules-cache-path=/Users/cjh/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/cjh/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wimplicit-retain-self -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wdeprecated-implementations -Wno-c++11-extensions -DDEBUG=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -Winvalid-offsetof -mmacosx-version-min=10.13 -g -fvisibility-inlines-hidden -Wno-sign-conversion -Winfinite-recursion -Wmove -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wrange-loop-analysis -Wunguarded-availability -index-store-path /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Index/DataStore -iquote /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-generated-files.hmap -I/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-own-target-headers.hmap -I/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-all-target-headers.hmap -iquote /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/TestScreensaver-project-headers.hmap -I/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/include -I/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/DerivedSources/x86_64 -I/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/DerivedSources -F/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug -MMD -MT dependencies -MF /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaverView.d --serialize-diagnostics /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaverView.dia -c /Users/cjh/Documents/code/swift/TestScreensaver/TestScreensaver/TestScreensaverView.mm -o /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaverView.o

Ld /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/TestScreensaver.saver/Contents/MacOS/TestScreensaver normal x86_64
    cd /Users/cjh/Documents/code/swift/TestScreensaver
    export MACOSX_DEPLOYMENT_TARGET=10.13
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -bundle -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -L/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug -F/Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug -filelist /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaver.LinkFileList -mmacosx-version-min=10.13 -Xlinker -object_path_lto -Xlinker /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaver_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -stdlib=libc++ -fobjc-arc -fobjc-link-runtime -ObjC -lc++ -Xlinker -dependency_info -Xlinker /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Intermediates.noindex/TestScreensaver.build/Debug/TestScreensaver.build/Objects-normal/x86_64/TestScreensaver_dependency_info.dat -o /Users/cjh/Library/Developer/Xcode/DerivedData/TestScreensaver-dufowvmnhdeakfekvozrelyhhccq/Build/Products/Debug/TestScreensaver.saver/Contents/MacOS/TestScreensaver

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_ScreenSaverView", referenced from:
      _OBJC_CLASS_$_TestScreensaverView in TestScreensaverView.o
  "_OBJC_METACLASS_$_ScreenSaverView", referenced from:
      _OBJC_METACLASS_$_TestScreensaverView in TestScreensaverView.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)



Activity Log Complete    6/4/18, 2:06 PM

Not really sure what the issue is because I have never had issues before. Does anyone have a clue what might be the problem?

For completeness, below is the code that the project initializes with:

TestScreensaverView.h

//
//  TestScreensaverView.h
//  TestScreensaver
//
//  Created by C. Howard on 6/4/18.
//  Copyright © 2018 C. Howard. All rights reserved.
//

#import <ScreenSaver/ScreenSaver.h>

@interface TestScreensaverView : ScreenSaverView

@end

TestScreensaverView.mm (originally TestScreensaverView.m)

//
//  TestScreensaverView.m
//  TestScreensaver
//
//  Created by C. Howard on 6/4/18.
//  Copyright © 2018 C. Howard. All rights reserved.
//

#import "TestScreensaverView.h"

@implementation TestScreensaverView

- (instancetype)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
    self = [super initWithFrame:frame isPreview:isPreview];
    if (self) {
        [self setAnimationTimeInterval:1/30.0];
    }
    return self;
}

- (void)startAnimation
{
    [super startAnimation];
}

- (void)stopAnimation
{
    [super stopAnimation];
}

- (void)drawRect:(NSRect)rect
{
    [super drawRect:rect];
}

- (void)animateOneFrame
{
    return;
}

- (BOOL)hasConfigureSheet
{
    return NO;
}

- (NSWindow*)configureSheet
{
    return nil;
}

@end
spektr
  • 777
  • 5
  • 14

1 Answers1

0

The implementation of Obj-C class ScreenSaverView appears to be missing, as is evident from the error message. I don't see it in the command line to ld there but since you posted a screenshot instead of copy-and-pasting from the log, I can't search for it so maybe I missed it.

Edit Hokay, having myself missed the point and been rather rude to the OP along the way, I have now got to the bottom of this and it's simple enough.

It seems that you need to add the ScreenSaverView framework to your project, which you can do by following the recipe here:

http://docs.onemobilesdk.aol.com/ios-ad-sdk/adding-frameworks-xcode.html

Why this is not needed if your source file builds as .m is unclear. You'd think you would always need it but apparently not. Chalk it up to the spirit of Steve Jobs, just toying with us mere mortals from beyond the grave.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Hi Paul, thanks for taking a look. I have added the full log output to the problem statement now. – spektr Jun 04 '18 at 19:10
  • Well, I wasn't _really_ suggesting that it should be me that looks for it, I thought you might, but, since you ask it's not there. So you need to investigate why whatever source file contains the implementation of `ScreenSaverView.` is being excluded from the link. In fact, it doesn't show up as being compiled, either. Is that file still part of your projecI? The problem is (obviously) nothing to do with changing the extension of `TestScreenSaverView.mm`. – Paul Sanders Jun 04 '18 at 19:18
  • Ah, sorry Paul but thanks for looking. So this project, as I wrote, is the baseline project Xcode generates for the Screen Saver. For some reason when I change the extension from .m to .mm, this error comes up. This file is still in the project and still shows up as part of the Build Phases for my project after changing the extension, so I find it weird that it wouldn't be getting compiled. I want to believe this is some bug in Xcode because I have changed the extensions of files from .m to .mm in the past without any issues in prior versions of Xcode. – spektr Jun 04 '18 at 19:23
  • Well you might look at [this post](https://stackoverflow.com/questions/26427141/what-xcode-build-rules-does), although I really don't believe that's the issue because Xcode is compiling `TestScreenSaver.mm` OK. Try removing `XScreenSaverView.mm` (as I assume it now is) from your project and then add it back in. – Paul Sanders Jun 04 '18 at 19:29
  • Hi Paul, thanks for the link. I actually see I misled you with how I described my problem. When I wrote `XScreenSaverView.mm`, I was treating the X as a placeholder for the name of the project. `TestScreenSaver.mm` is the actual name in my particular case. Additionally, all I have done is create the baseline Screen Saver project and then change the extension of the `TestScreenSaver.m` file so it is `TestScreenSaver.mm` and then try to build the project.. so I don't think the issue could be coming from anywhere else on my end. I will try to remove the file and add it back, though! – spektr Jun 04 '18 at 19:34
  • After removing it and adding it back, still have the same issues :( – spektr Jun 04 '18 at 19:36
  • Updated my answer. – Paul Sanders Jun 04 '18 at 19:45
  • Thanks for your updated answer Paul, I appreciate the time you've taken. Unfortunately the `TestScreenSaver.mm` file is showing the correct type of `Default: Objective-C++ Source`. I am trying to look at the log outputs and see if I can find a meaningful difference when it compiles and links with `TestScreenSaver.m` versus `TestScreenSaver.mm`. Thanks again for your time. – spektr Jun 04 '18 at 19:49
  • I asked you to look at `XScreenSaverView.mm`, not `TestScreenSaverView.mm`. That's the file that's not getting built. Either you mis-typed or you are missing the point here. – Paul Sanders Jun 04 '18 at 19:52
  • Hi Paul, I commented a couple messages ago that when I wrote `XScreenSaverView.mm`, the `X` in the name was a placeholder. The actual file of concern is in fact `TestScreenSaver.mm`. I do not have a file precisely named `XScreenSaverView.mm`, the `X` in my case is `Test`. The only two files in my project are `TestScreenSaverView.h` and `TestScreenSaverView.mm`. I actually updated my problem statement to remove this confusion since I could see I confused you. My apologies. – spektr Jun 04 '18 at 19:55
  • And man I realized I kept writing `TestScreenSaver.mm` above in my comments instead of `TestScreenSaverView.mm`. Sorry for any added confusion from that. – spektr Jun 04 '18 at 19:58
  • So where is the implementation of class `ScreenSaverView`? As I said at the beginning, that is what's missing, as you can clearly see from the error message. I guess you need to post your code. – Paul Sanders Jun 04 '18 at 20:00
  • `ScreenSaverView` is a class that Apple implemented and the call to import it is located in the `TestScreenSaverView.h` when it writes: `#import `. And my code is posted above. That is all of it, just those two files which were auto-generated when I made the project (other than the extension change). I have not added or done anything else. – spektr Jun 04 '18 at 20:04
  • Ah, we could be getting somewhere at last. I didn't realise what it was. Sorry if I have been a bit impolite, let me take a look. – Paul Sanders Jun 04 '18 at 20:18
  • No worries, thank you for taking the time. So I diffed the two log files and looked at the differences in their compile and linking stages. The differences are small and are basically just adding a couple things due to compiling C++ in the `.mm` case versus not in the `.m` case. I tried to see if I could work around it by explicitly adding in the `ScreenSaver.framework` to the project and it appears to compile in the `.mm` case now. As you noted, we weren't getting the objects for Apple's `ScreenSaverView` class and I guess this is a workaround ensures we get it. Still annoyed at this, though. – spektr Jun 04 '18 at 20:28
  • Sussed it, updated my answer. I need to be less self-important. Suggest move comment thread to chat. – Paul Sanders Jun 04 '18 at 20:31
  • Haha I am glad we got to the bottom of this, thank you for your help sir. – spektr Jun 04 '18 at 20:32