Day 46/100 100 Days of Code

Day 46/100 100 Days of Code

Rebuild Back Better

Mixing Objective-C and C++ was quite the adventure. I didn't expect it to be that hard. The problem was that the compiler couldn't locate After a lot of experimentation, I ended up finding the solution on Stack Overflow.

It is not possible to mix C++ and Objective-C like C++ and C. A lot more steps are needed to make it work and these steps will be used to find the game's assets and nothing else.

Objective-C Code

First, I created a macos.h file to create a class that will hold the location of the assets in the .app container.

# macos.h
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

@interface MacBuild : NSObject

    @property (assign) NSBundle *standardBundle;
    @property (assign) NSString *findFontMenuTitle;
    void InitialiseProperties();
@end

Then, I defined the content of the MacBuild object.

# macos.mm
#import "macos.h"

@implementation MacBuild
-    (void) InitialiseProperties{
        self.standardBundle = [NSBundle mainBundle];
        self.findFontMenuTitle = [_standardBundle pathForResource:@"/fonts/ArianVioleta-dz2K" ofType:@"ttf"];
    }
@end

I also made a wrapper .mm file to make the code compatible with c.

# macoswrapper.mm
extern "C"
{
    #import "macos.h"
}

extern "C" MacBuild  *MacBuilder()
{
    MacBuild *macbuild = [[MacBuild alloc] init];
    return macbuild;
}

extern "C" void DestroyMacBuilder(MacBuild *macbuild)
{
    [macbuild dealloc];
}

The code still needs to be tested

Building the Objective-C logic as a separate library

I followed the guide from the stack overflow post to build the library for the Mac build.

# Build MacOs Build file
# Read More: 
# https://stackoverflow.com/questions/76486081/mix-c-and-objective-c-code-using-cmake-and-get-c-executable
add_library(macosbuild MODULE
    ./src/macoswrapper.mm
)

target_sources(macosbuild
  PRIVATE
    ./src/macos.h
    ./src/macos.mm
)

target_link_libraries(macosbuild
    PRIVATE "-framework Cocoa"
    PRIVATE "-framework Foundation"
    PRIVATE "-framework AppKit"
)

# Set the language for the library to Objective-C++
set_target_properties(macosbuild PROPERTIES
    LINKER_LANGUAGE "CXX"
    XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
    XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES YES
    XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES
)

Dynamic linking with the dlfcn library

Instead of including a header file, the guide used the dlfcn library to include the library in the project.

macBuildHandler = dlopen("./builds/lib/libmacosbuild.so", RTLD_LOCAL);

if (!macBuildHandler)
{
    std::cout << "Failed to open mac build library ";
    std::cout << std::strerror(errno) << std::endl;;
    return false; 
}

Like all files, always close the library when we are done.

dlclose(macBuildHandler);

I still need to follow the next steps of the guide to complete the implementation of the Objective-C library and make the application mac compatible.