bytedeco / javacpp

The missing bridge between Java and native C++
Other
4.49k stars 583 forks source link

Fix building with clang 15 on OSX #609 #610

Closed wabscale closed 2 years ago

wabscale commented 2 years ago

The problem is explained in the issue, but to reiterate:

Newer versions of apple's clang will error if there is an undefined reference to TARGETOS*. The solution to this is to include the TargetConditionals.h file ahead of any references. The problem originates here:

https://github.com/bytedeco/javacpp/blob/f77f8d77f3724128bc26440d930b786892c58312/src/main/java/org/bytedeco/javacpp/tools/Generator.java#L313-L318

The TargetConditionals.h is only included if both __APPLE__ and __OBJC__ are definied. If you use a brew installed llvm (currently version 15), the __APPLE__ will be defined but __OBJC__ is not.

What I have done is made it so that TargetConditionals.h is always included on apple, and the Foundation/Foundation.h is only included when __OBJC__ is defined. The result is this:

#ifdef __ANDROID__
    #include <android/log.h>
#elif defined(__APPLE__)
    #include <TargetConditionals.h>
#endif

#if defined(__OBJC__) 
    #include <Foundation/Foundation.h>
#endif

I've tested this on OSX 12.6, clang 15 (installed via brew install llvm).

saudet commented 2 years ago

Thanks for the fix! To make sure we don't break anything, we probably want more something like this though:

--- a/src/main/java/org/bytedeco/javacpp/tools/Generator.java
+++ b/src/main/java/org/bytedeco/javacpp/tools/Generator.java
@@ -315,6 +315,8 @@ public class Generator {
         out.println("#elif defined(__APPLE__) && defined(__OBJC__)");
         out.println("    #include <TargetConditionals.h>");
         out.println("    #include <Foundation/Foundation.h>");
+        out.println("#elif defined(__APPLE__)");
+        out.println("    #include <TargetConditionals.h>");
         out.println("#endif");
         out.println();
         out.println("#ifdef __linux__");
wabscale commented 2 years ago

Great, I've overwritten the commit with what you have requested.