ld_prime
of Xcode 15 produces duplicate symbols when linking a static library containing Objective-C++ object in case using the flags -ObjC
and -Wl,force_load
.
// foo.h
#pragma once
int Inc(int i);
// foo.mm
#include "foo.h"
#include <Foundation/Foundation.h>
@interface Foo : NSObject
@end
@implementation Foo
@end
int Inc(int i) {
return i + 1;
};
// main.cpp
#include "foo.h"
int main(int argc, const char * argv[]) {
return Inc(0);
}
❯ clang++ -c foo.mm
❯ ar rcs libfoo.a foo.o
❯ clang++ -framework Foundation libfoo.a -x c++ main.cpp -Wl,-force_load,libfoo.a -ObjC
duplicate symbol '__Z3Inci' in:
libfoo.a[2](foo.o)
libfoo.a[2](foo.o)
duplicate symbol '_OBJC_CLASS_$_Foo' in:
libfoo.a[2](foo.o)
libfoo.a[2](foo.o)
duplicate symbol '_OBJC_METACLASS_$_Foo' in:
libfoo.a[2](foo.o)
libfoo.a[2](foo.o)
ld: 3 duplicate symbols
clang: error: linker command failed with exit code 1 (use -v to see invocation)```
You’re telling the linker to load libfoo.a
twice, first via the libfoo.a
argument to the clang++
compiler driver and again via the -force_load
argument you pass directly to the link. Because you want to include Objective-C stuff even if it’s unreferenced, it makes sense to remove the first of these. That fixes the link step and the resulting binary still has class Foo
in it:
% nm a.out
00000001000080b8 S _OBJC_CLASS_$_Foo
U _OBJC_CLASS_$_NSObject
0000000100008090 S _OBJC_METACLASS_$_Foo
U _OBJC_METACLASS_$_NSObject
0000000100008048 s __OBJC_CLASS_RO_$_Foo
0000000100008000 s __OBJC_METACLASS_RO_$_Foo
0000000100003f90 T __Z3Inci
0000000100000000 T __mh_execute_header
U __objc_empty_cache
0000000100003f60 T _main
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"