RAM
RAM

Reputation: 2759

Include objective-c++ source files in a c++ project

I have a C++ project which uses CMake as its build system. While porting it to macOS I needed to integrate a couple of Objective-C++ files, but unfortunately all I'm getting is build errors. It also doesn't help that I'm far from an expert in Objective-C++.

To arrive where I am right now, I've started off by updating the project definition of the pure C++ project to include both C++ and Objective-C++:

project(projectFOO LANGUAGES CXX OBJCXX)

Afterwards I've passed all the '.mm' Objective-C++ source files an their headers right into calls to add_library.

However, when I rebuild the cmake project I get as result a wall of compiler errors with few error messages looking like this:

(...)
In file included from /Users/ram/development/Foo/source/MyNSImage.mm:1:
/Users/ram/development/Foo/include/MyNSImage.h:22:5: error: unknown type name 'CGContextRef'
(...)
/Users/ram/development/Foo/source/MyNSImage.mm:7:81: error: use of undeclared identifier 'nil'
(...)

After reviewing the compiler commands executed by the build I've noticed that it's calling /usr/bin/c++ while passing both -x objective-c++ -g and -std=gnu++11.

Afterwards I could reproduce the same error by creating a library that only includes the Objective-C++ files, whose CMake definition is something as follows:

cmake_minimum_required(VERSION 3.16)    # Introduces support for OBJC and OBJCXX.  See https://cmake.org/cmake/help/v3.16/release/3.16.html

project(projectFOO LANGUAGES CXX OBJCXX)

# (..omit C++ code..)

if(APPLE)
    # separate library created just to build the Objective-C++ code
    add_library(foo_mac
            include/MyNSImage.h
            source/MyNSImage.mm
            )

    target_include_directories(foo_mac
            PUBLIC
            include
            )
endif()

# (..omit more C++ code..)

# here's the C++ library
add_library(foo
        ${foo_INCLUDES}
        ${foo_HEADERS}
)

if(APPLE)
    # when building on macOS, also link the Objective-C++ lib.
    target_link_libraries(foo foo_mac)
endif()

After refreshing the CMake project with -DCMAKE_VERBOSE_MAKEFILE and rebuilding it, here's the compiler command for foo_mac:

(...)
cd /Users/ram/development/Foo/cmake-build-debug/Foo && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -I/Users/ram/development/Foo/include -x objective-c++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -fPIC -std=gnu++11 -o CMakeFiles/foo_mac.dir/source/MyNSImage.mm.o -c /Users/ram/development/Foo/source/MyNSImage.mm

(...)

Does anyone have any idea about what I might be doing wrong?

Upvotes: 1

Views: 825

Answers (1)

RAM
RAM

Reputation: 2759

It turned out that the root cause was a missing #import which in the original Objective-C++ module was being sneaked in with a precompiled header passed globally with a -include=${header} compiler definition.

Upvotes: 1

Related Questions