Build Errors SDK 3.0.4 compared to SDK 2.4.9 with loadResource

It seems like the SDK from 3.0.1 forward tries to enforce resource over riding ?? That is a resource must be defined in the main path as well as the 'Configure Path' such as round.resourcePath = $(base.resourcePath);resource-round


I have a watch face project that builds and works for a range of devices that work using Connect IQ 1.3 and above.

Whenever I try to compile a project that has resources defined only in a configure path I get an 'Undefined Symbol' error. This error goes away if I load the resources into the main resource path so that they are now overloaded rather than defined in the sub-path only.

This is OK except with it comes to JSON data since that is not supported in earlier versions of IQ.

The code I have has some features only supported in Connect IQ 2.3+ devices. This code reads a JSON data file and this code is excluded in the build of IQ 1 devices using jungle file notation. The jsonData resources are only in the path for the IQ2+ devices. THe build works fine for SDK 2.4.9 however the complier generates an error on the line that loads the json resouces for IQ2.3+ devices.

The application then runs for all IQ1 and IQ2+ devices despite the build error.

Will the build errors cause any problems once the application is published ? It doesn't feel right publishing an application that is actually reporting errors but still works ?


  • well you're missing some essential info as you didn't post your complete jungle, but I'm assuming it's the autobuild that is failing.

    adding this to your jungle should fix it:
    base.sourcePath = $(fr235.sourcePath)
    base.resourcePath = $(fr235.resourcePath)
    base.excludedAnnotations = $(fr235.excludedAnnotations)

  • Thanks for the reply! The only line I have in my jungle file is the 'excludeAnnotations' line to exclude the IQ2 code. Adding in the other lines just creates circular references.

    The problem seems to be that the jsondata resource is defined in the resource path for the Fenix 5 device. Therefore the resource is not defined for a FR235. (all OK!) When the build process runs it gives an error that the resource is undefined. (not OK!) The application still runs for both a FR235 and a F5 despite the errors! My concern is about what happens if I publish an application with build errors ?
    Thanks
  • When you enable the Project > Build Automatically option in Eclipse, every time you save a file, the IDE will try to build your project using a generic device. If I've successfully recreated your build configuration, the build error that you're seeing is coming up when building for that device. If you just turn off the option to build automatically, you shouldn't see that build error ever again because you are required to specify a device when building at all other times.

    So, to answer your original question, you are fine. If the code compiles and runs under each configuration you want to support, then you have nothing to worry about.

    If you want the code to compile for the generic device, you could add the --Eno-invalid-symbol flag to the ConnectIQ compile options. This will tell the compiler to treat invalid symbol errors as warnings. This will allow the build to proceed, but then you need to take appropriate steps to ensure that an undefined symbol is never referenced at runtime.
  • Looking at your solution, you have a mix of runtime and compile time checks to access this json data. This isn't ideal because you have the overhead associated with the runtime checks and the maintenance costs associated with the compile time checks.

    To do the checks at runtime, you should consider using has checks, similar to what you're doing with the version check. The has check is better as it accurately identifies whether a symbol is available or not and it suppresses the undefined symbol warning for the symbol you are checking. This solution might look like:

    function onUpdate(dc) {
    var value = myFunction("myValue1");
    }

    function myFunction(key) {
    if (Rez has :JsonData && Rez.JsonData has :dictRes) {
    var myJson = WatchUi.loadResource(Rez.JsonData.dictRes);
    return myJson[key].toString();
    }
    else {
    return "no JSON";
    }
    }


    If you want to go the compile time route, you just need to tell the system that the default device does (or doesn't) support json data so that it will compile out the code that references it. Since excludeAnnotations aren't inherited, you are free to do this without screwing up other devices. This is basically what peterdedecker tried to get you to do above, but he ran you into a circular dependency between base.{source,resource}Path and fr235.{source,resource}Path. You can do things like that, but it can be brittle.

    # monkey.jungle
    project.manifest = manifest.xml

    # the default device does not support json data
    base.excludeAnnotations = has_json_data

    # these devices do not support json data
    fr235.excludeAnnotations = $(fr235.excludeAnnotations);has_json_data

    # these devices do support json data
    fenix5.excludeAnnotations = $(fenix5.excludeAnnotations);no_json_data


    and then the code might look something like this...

    function onUpdate(dc) {
    var value = myFunction("myValue1");
    }

    (:has_json_data) function myFunction(key) {
    var myJson = WatchUi.loadResource(Rez.JsonData.dictRes);
    return myJson[key].toString();
    }

    (:no_json_data) function myFunction(key) {
    return "no JSONdata";
    }


    If you really wanted to have different code paths, and you didn't need myFunction, you would write something like this:

    (:has_json_data) function onUpdate(dc) {
    var value = myFunction("myValue1");
    }

    (:has_json_data) function myFunction(key) {
    var myJson = WatchUi.loadResource(Rez.JsonData.dictRes);
    return myJson[key].toString();
    }

    (:no_json_data) function onUpdate(dc) {
    // doesn't call myFunction at all
    }
  • Travis, thank you for taking the time to explain this! This is a sensational tip that allows me to tidy up some code I was never happy with. Thanks!

    The fact that the IDE is building for a generic device is why I would normally get errors that myFunction(key) has a duplicate definition. If you just build for the devices you are supporting that works perfectly!