gradlew assemble error: can't find referenced class java.lang.invoke.LambdaMetafactory - android-gradle-plugin

I'm experiencing a strange error that only happens when I try to build my project using the gradlew script file.
If I run gradlew assemble Proguard it's complaining in multiple classes (in the same module) with the following warning:
can't find referenced class java.lang.invoke.LambdaMetafactory
Of course I have the following rule inside my module and main project proguard-rules.pro file:
-dontwarn java.lang.invoke.**
-dontwarn **$$Lambda$*
But even with that Proguard it's still complaining about the same warning...
Now the strange part is, if I run a different job, for example assembleRelease, assembleDebug, or assembleQA (A custom job that I make) the process finish without any problem...
I'm getting out of ideas here...

Related

Dependencies between Android native modules (prefab) fail to build

Our Android application consists of 40-some Android Library Modules (ALMs), each of which also builds a C++ shared library with externalNativeBuild and CMake. So far we had the dependencies between these libs set up like this:
The dependent ALM references the dependency ALM with api project(':lib')
The dependent CMake script references the dependency .so with add_library(SHARED IMPORTED lib) and set_target_properties(lib PROPERTIES IMPORTED_LOCATION ...) and a relative path.
Recently we had to upgrade to the latest Android API version. This started off a cascade because now we were getting deprecated warnings in code generated by the navigation-ktx library, but upgrading that requires upgrading Gradle and the Android Gradle plugin. After that I started getting errors like liblib.so, needed by 'project', missing and no known rule to make it.
It looks like the latest Gradle parallelizes build tasks more heavily, and this means the dependent CMake/Ninja builds are being started concurrently with their dependencies, resulting in this error because the dependency is not yet built. I figured out that what we were doing was not entirely supported, but there is a "supported" way to do that now, so I refactored our entire build to use Prefab.
Now I started getting other errors, alternating between:
1.
C++ build system [prefab] failed while executing ...
Usage: prefab [OPTIONS] PACKAGE_PATH...
Error: Invalid value for "PACKAGE_PATH": Directory ... is not readable.
ld: error: undefined symbol ...
I looked into build/intermediates and found that in the 2nd case, the cmake config script was generated incorrectly: instead of add_library(lib::lib SHARED IMPORTED ) it had add_library(lib::lib INTERFACE IMPORTED) like it it was a header only library, and there was no IMPORTED_LOCATION set in the file.
What am I doing wrong and what should I do to unbreak our build?
It looks like the toolchain support for prefab interdependencies within a project is not quite finished. Others are reporting the same kind of errors at https://issuetracker.google.com/issues/265544858:
This appears to be a race condition with generating prefab cmake files.
It says in https://issuetracker.google.com/issues/221231432 that the header-only cmake config is generated to satisfy Android Studio's IDE features (completion, etc.) before the library is actually built.
Treat as-yet-unconfigured modules as if they are Header-only libraries for Android Studio purposes. This works because Android Studio doesn't care about linker flags for the purposes of providing language services.

CMake linking error at runtime from other lib in subdirectory

I am trying to get a project running that is using dynamic openCASCADE libraries.
So first i set up a minimal test project using the following CMake file:
...
include_directories(/home/user/occt/build_r/include/opencascade/)
add_executable(testOCCT
main.cpp
step2stl.cpp
)
find_package(OpenCASCADE REQUIRED NO_DEFAULT_PATH)
set(OCCT_LIBS TKMesh; TKSTEP; TKSTL; TKXSBase; TKernel)
target_link_libraries(testOCCT ${OCCT_LIBS})
This is working as it should.
Now i want to link the same libraries to another library that is used in a larger project.
For the project there are 3 CMake files, one for the project and two subdirectory, one for the executable one for the myLib, which are added by add_subdirectory().
In the CMake file for myLib which is inside one of the subdirectories I've added:
...
include_directories(/home/user/occt/build_r/include/opencascade/)
...
add_library(${MY_LIB_NAME} SHARED ${my_sources})
find_package(OpenCASCADE REQUIRED NO_DEFAULT_PATH)
set(OCCT_LIBS TKMesh; TKSTEP; TKSTL; TKXSBase; TKernel)
target_link_libraries(${MY_LIB_NAME} ${OCCT_LIBS})
so basically the same as in the test project.
However now I get an error (at runtime):
symbol lookup error: myLib.so: undefined symbol: _ZN24BRepMesh_IncrementalMeshC1ERK12TopoDS_Shapedbdb
Ok, so i found the problem myself. The reason it did not work was not because of CMake, but that there was some other version of the libraries installed over the packet manager, which then got loaded instead of the right one.
purging those libs solved the problem.
However what I still don't get is why it loaded the correct library version on the test project and the wrong on the other (both tested on the same machine)

CMake: target_include_directories and #include

I have the following layout. It is basically a certain class, and within its directory there is a subdirectory containing unit tests:
The class being tested is built like this:
add_library(experimental_run PUBLIC ${PROJECT_SOURCE_DIR}/experiments/experimental_run/experimental_run.cpp)
target_link_libraries(experimental_run PUBLIC nlohmann_json::nlohmann_json)
(this is the outermost CMakeLists in the image).
The tests-directory's CMakeLists.txt's contents are as follows:
cmake_minimum_required(VERSION 3.13)
add_executable(test_experimental_run_obj ${CMAKE_CURRENT_SOURCE_DIR}/test_experimental_run.cpp)
target_compile_options(test_experimental_run_obj PUBLIC -pg -g -O2)
target_link_libraries(test_experimental_run_obj PUBLIC experimental_run GTest::GTest GTest::Main)
target_include_directories(
test_experimental_run_obj PUBLIC
${PROJECT_SOURCE_DIR}/experiments/experimental_run/)
Essentially, first I am building the class as a library,
and then try to build the unit tests linking them towards
the library and including the appropriate directory
with target_include_directories and ${PROJECT_SOURCE_DIR}, where the latter
stores the root directory of the project.
Now this looks like I am effectively telling CMake "Feel free to look into the included
directories for anything you find in my #includes." However, my unit-test file
has it in red:
and prompts me to include the files using "../"
Now, why then I bothered to have the target_include_directories in the first place,
if I am to explicitly show the location anyway? Isn't the main idea
to make the whole thing flexible, without code duplication?
What am I missing?
EDIT: now that I went ahead and did include the "../"-prefix, the unit tests fail to compile, since the linked library experimental_run is non-existent. No wonder, since CLion does not seem to recognize it as something it needs to build.
EDIT: I've figured out one thing for now. CMAKE_PROJECT_SOURCE_DIR refers to the directory of where this _very CMakeLists resides, i.e. referring to the project's argument. This way, I can load the outermost library as a CMake project, but however cannot link against it inside the tests still.
(final) UPDATE:
Let's say I found a "workaround" this by adding
set(SOURCES ./test_experimental_run.cpp ../experimental_run.cpp)
set(TARGET test_experimental_run_obj)
into the CMakeLists of the unit-tests directory, and to no surprise it
compiles and works fine. If I remove he second *.cpp file, however,
and add experimental_run to target_link_libraries, I get
[ 50%] Linking CXX executable test_experimental_run_obj
/usr/bin/ld: cannot find -lexperimental_run
collect2: error: ld returned 1 exit status
Essentially the question is how to test the library assuming it is compiled,
and without having to specify its source code inside the unit-testing code.
Appreciate your time, I am yet developing my modus operandi with CMake,
so even shaping the right question is challenging for me right now.

invalid LOC header block project compilation

I'm writing a simple Kotlin project as example of a my library's usage. The code is available on github. When I try to compile it, the compiler show me the following error:
I deleted build folders and .gradle directories, but nothing changes. Any ideas?

How can I get the Frege compiler to see Android API classes when using Gradle?

I am attempting to write an Android app using the Frege language. Unfortunately, I'm not aware of any examples of how to do this.
So, I'm using Gradle as my build system, with the Android Gradle plugin. Then to get the Frege code to be compiled, I'm using a javaexec to call the frege compiler before the Java files get compiled, as suggested in this post.
I was successful in building an Android application with Frege code that gets called by Java code, as shown here.
However, the Frege code can only call standard Java APIs. It can't call any of the Android APIs.
I'd like to be able to call Android APIs from Frege. There is a nice repo here that has Frege wrappers for the Android APIs. Unfortunately, it has no build system or instructions.
I believe I've successfully set up my build.gradle to build the FregeAndroid wrappers along with my project's code. The Frege compiler is indeed attempting to build them.
However, the FregeAndroid code fails to compile, because it can't see the Android API classes. I assume I need to somehow find where the Android API classes are, and then add that to the Frege compiler's classpath, so it can see those classes. Unfortunately, this is where I'm stuck. I'm a newbie at Gradle, and can't figure out how to do this.
Here is my project which I have so far, which fails to build, in the following way:
:compileDebugJavaWithJavac
Frege compiler args: "-inline -d src/frege -make -fp /Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -sp /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src/frege/android/animation/TimeInterpolator.fr"
calling: javac -cp /Users/ppelleti/.gradle/caches/modules-2/files-2.1/org.frege-lang/frege/3.23.401-g7c45277/716990197271fdc15917b4f8d023d63009ba6e39/frege-3.23.401-g7c45277.jar:/Users/ppelleti/Library/Android/sdk/extras/android/m2repository/com/android/support/multidex/1.0.0/multidex-1.0.0.aar:src/frege:/Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -d src/frege -sourcepath /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src -encoding UTF-8 src/frege/frege/android/animation/TimeInterpolator.java
runtime 4.282 wallclock seconds.
Frege compiler args: "-inline -d src/frege -make -fp /Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -sp /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src/frege/android/app/Activity.fr"
Android.app.TaskStackBuilder: build failed because module is not on class path
Android.app.Fragment: build failed because module is not on class path
Android.app.LoaderManager: build failed because module is not on class path
[... omitted a bunch of similar lines ...]
Any ideas would be much appreciated!
It turns out that there were several problems, including problems with both the source path and the classpath. I've updated my repository to fix these problems.
However, ultimately the build fails because there are files missing from the FregeAndroid repo. So to get my example to build, it would be necessary to fix the FregeAndroid wrappers or write new wrappers.