Initializer element is not a compile-time constant with version 2.0.5 & XCode 9.2

1,085 views
Skip to first unread message

Marcus Smith

unread,
Jan 31, 2018, 9:13:51 AM1/31/18
to j2objc-discuss
Hi,

We have a number of Java libraries which we convert into objective-c and include in our product as PODS. I am in the process of upgrading from J2Objc 1.2 to 2.0.5 but have run into some compiler issues. The error we are seeing is:

"Initializer element is not a compile-time constant"

and it relates to the meta-data, for instance one of the PrettyTime classes is generated like this:

+ (const J2ObjcClassInfo *)__metadata {

  static const J2ObjcMethodInfo methods[] = {

    { "init", "Day", NULL, 0x1, NULL, NULL },

    { "getResourceKeyPrefix", NULL, "Ljava.lang.String;", 0x4, NULL, NULL },

  };

  static const J2ObjcClassInfo _OrgOcpsoftPrettytimeUnitsDay = { 2, "Day", "org.ocpsoft.prettytime.units", NULL, 0x1, 2, methods, 0, NULL, 0, NULL, 0, NULL, NULL, NULL };

  return &_OrgOcpsoftPrettytimeUnitsDay;

}


The error occurs twice because of the static const, we also get warnings such as 


Incompatible pointer to integer conversion initializing 'ptr_idx' (aka 'short') with an expression of type 'void *'


Incompatible pointer to integer conversion initializing 'uint16_t' (aka 'unsigned short') with an expression of type 'void *'


Incompatible pointer types initializing 'SEL' with an expression of type 'char 


These are for _init and the next 2 NULL entries.


J2ObjC is also included as a POD (it has been since we started using it back in 2014).


Do I need to update my compiler settings? Any help would be greatly appreciated.


Regards,


Marcus Smith

Tom Ball

unread,
Feb 1, 2018, 11:39:17 AM2/1/18
to j2objc-...@googlegroups.com
How are you building PrettyTime, specifically what j2objc and compiler flags are used? If compilation is being done in Xcode, can errors and warnings in the build log be expanded to see what flags were set?

The warnings we can avoid by enhancing how metadata is specified, adding casts and @selector directives where necessary. We avoided doing that initially because developers had freaked about the size of all that additional text in their generated files, even though the structs themselves are generally small (that's why a JVM classfile-like structure was used). The complaints have died down and the Xcode team has set new default warnings, so it's time to define them more accurately.

I'm confused about the "not a compile-time constant" error, though: do you see what could possibly not be constant? Metadata is purposefully all done in C structs composed of constants: C strings, ints, and pointers to other static constant structs all defined right before their reference. You may have found a bug in LLVM in Xcode 9.2, as we should be generating ANSI C11-compatible code, and there is no newer spec. I hope not, as it's much easier to tweak what code is generated than getting a compiler bug fixed (though the LLVM team is very responsive).

--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tom Ball

unread,
Feb 1, 2018, 11:45:08 AM2/1/18
to j2objc-...@googlegroups.com
FYI, if your libraries don't use reflection (other than dynamic class loading), you can translate them without metadata using the --strip-reflection flag. Several of Google's j2objc-using apps do this globally to reduce app size. It's easy to check by searching source for any "import java.lang.reflect" references, and if any classes needing reflection support slip through, a com.google.j2objc.ReflectionStrippedError is thrown when those methods are invoked. 

I still want to fix the error and warnings you reported, but stripping reflection would unblock you until a fix is released.

Marcus Smith

unread,
Feb 2, 2018, 10:34:32 AM2/2/18
to j2objc-discuss
Hi Tom,

Thanks for the reply. The following shows the gradle task I use to translate the PrettyTime library:

task translateJava(type:Exec) {

    inputs.files configurations.runtime.allDependencies.dependencyProject.sourceSets.main.allJava.inject(sourceSets.main.allJava) { acc, val -> acc.plus(val) }


    // the classpath is built from the runtime dependencies for the sourcesets ...

    executable "${J2OBJC_HOME_LATEST}/j2objc"

    args '--doc-comments'

    args '--nullability'

    args '-d', file('src/gen/objc').path

    args '-sourcepath', (sourceSets.main.allJava.srcDirs + configurations.runtime.allDependencies.dependencyProject.sourceSets.main.allJava.srcDirs.flatten()).join(':')

    args '-classpath', sourceSets.main.runtimeClasspath.collect { it.absolutePath }.join(':')

    args inputs.files

}


The nullability flag I added in recently. We do all our translations via gradle, we always have done and the scripts haven't changed for a while now. 

I will check to see if PrettyTime is using reflection, and try with the appropriate flag set so we can continue with the upgrade (I've moved onto something else for the moment so will move back to this shortly) I as well cannot see anything that would be considered not constant. I will update on the progress as I would expect the other libraries we use to also fail the build.

Regards,

Marcus
Reply all
Reply to author
Forward
0 new messages