Sysprogs forums › Forums › VisualGDB › VisualGDB and Android (.mk) static libraries not linking
- This topic has 2 replies, 3 voices, and was last updated 10 years, 3 months ago by Illya.
-
AuthorPosts
-
September 11, 2014 at 09:59 #905AnonymousParticipant
VisualGDB Evalution expires in 9 days. Help here would be greatly appreciated and a strong recommendation to by a full license.
This is about my experience of building an Android GoogleTest static library, a program with functionality that requires testing, and an Android UnitTest program to carry out the task of testing on the Android OS. This is much a record of my attempt to produce the above as it is to gain help or make others aware of problems in what should be a simple exercise. I wanted to build the programs for Android using Visual Studio 2013. I installed and set up the pre-requisites:
Android SDK
Android NDK
Environment variables for the above SDK and NDK
VisualGDBI downloaded GoogleTest, unzipped it and put it someplace which I could access from Visual Studio easily. It comes as a set of source files with examples and build projects for various operating systems, but not for Android. An example is given in a readme, but it got me only so far. The code for this exercise is simple enough, the problem I believe lies with creating the correct Android .mk files. I wanted the following setup to perform a test on one math function:
GoogleTest static library
SimpleMath executable
UnitTestSimpleMath executableIn a Visual Studio solution I had three projects; one for each of the above. To prove that the GoogleTest set up above worked, I first did this exercise for Windows. The code built and linked against the GoogleTest static library, forming an executable which ran in a console window. All things at this stage worked as hoped and expected.
GoogleTestWindowsRan
Ok, so now to do the same thing for Android. I created another solution, with three VisualGDB Android projects this time. I have not used VisualGDB before and so did not realise for a while that while there is a VisualGDB properties dialogue (which edits the .mk files) the editing of the standard project properties does not have any effect on how the Android code is built. Hence I could not build the following code because various include files could not be found. Once I realised this, I concentrated on the editing of just the .mk files. The code for this exercise is as follows.
For the SimpleMath executable I had the following:
Main.cpp: #include
#include "SimpleMath.h"
int main( int argc, char **argv ) {
double stopDeadCodeStripping = cubic( 10.0 );
printf( "The cubic of 10 is %fn", stopDeadCodeStripping );
return 0;
}For SimpleMath.c:
include "SimpleMath.h" double cubic( double d ) { return d * d * d; }
For UnitTestSimpleMath, the project just has one file, UnitTestSimpleMath.cpp:
#include
#include"SimpleMath.c"
#include
TEST( testMath, myCubicTest ) {
EXPECT_EQ( 1000, cubic( 10 ));
}
int main( int argc, char **argv ) {
printf( "Running main() from UnitTestSimpleMath.cpp. Cubic of 10 is %fn", cubic( 10 ) );
printf( "Running tests...n" );
::testing::InitGoogleTest( &argc, argv );
return RUN_ALL_TESTS();
}So, the only important settings when building Android projects are contained within the Android.mk and Application.mk files. These can be editing directly or by using the VisualGDB project properties. For the GoogleTest project the .mk files are as follows.
For Android.mk:
#VisualGDBAndroid: AutoUpdateSourcesInNextLine LOCAL_CPP_EXTENSION := .cc .cpp LOCAL_SRC_FILES := src/gtest-all.cc LOCAL_C_INCLUDES := jni/include LOCAL_EXPORT_C_INCLUDES := jni/include LOCAL_STATIC_LIBRARIES := LOCAL_SHARED_LIBRARIES := LOCAL_LDLIBS := LOCAL_CFLAGS := LOCAL_CPPFLAGS := LOCAL_LDFLAGS := COMMON_SRC_FILES := include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := GoogleTest-shared #VisualGDBAndroid: AutoUpdateSourcesInNextLine LOCAL_CPP_EXTENSION := .cc .cpp LOCAL_SRC_FILES := D:/Dev/gtest-1.7.0/src/gtest-all.cc LOCAL_C_INCLUDES := D:/Dev/MyFirstAndroidGoogleTest/GoogleTest/jni/include LOCAL_EXPORT_C_INCLUDES := D:/Dev/gtest-1.7.0/include LOCAL_EXPORT_C_INCLUDES += D:/Dev/gtest-1.7.0 LOCAL_STATIC_LIBRARIES := LOCAL_SHARED_LIBRARIES := LOCAL_LDLIBS := LOCAL_CFLAGS := LOCAL_CPPFLAGS := LOCAL_LDFLAGS := COMMON_SRC_FILES := include $(BUILD_SHARED_LIBRARY)
As you can see, there are two approaches that I used to prove the GoogleTest libraries could be built. The first involved specifying directly that the files required could be found in the directory where I installed the GoogleTest code. The other references code copied to the source and includes directories in the project’s jni directory.
For Application.mk:
# Generated by VisualGDB APP_MODULES := GoogleTest-static GoogleTest-shared APP_ABI := all APP_STL := gnustl_shared
This project builds and forms a shared library (.so) and a static library (.a), of 689KB and 2581KB respectively.
For the SimpleMath executable project the .mk files are the following:
For Android.mk:
# Generated by VisualGDB LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := SimpleMath #VisualGDBAndroid: AutoUpdateSourcesInNextLine LOCAL_SRC_FILES := main.c SimpleMath.c LOCAL_C_INCLUDES := LOCAL_EXPORT_C_INCLUDES := SimpleMath.h LOCAL_STATIC_LIBRARIES := LOCAL_SHARED_LIBRARIES := LOCAL_LDLIBS := LOCAL_CFLAGS := LOCAL_CPPFLAGS := LOCAL_LDFLAGS := COMMON_SRC_FILES := $(LOCAL_SRC_FILES) include $(BUILD_EXECUTABLE)
For Application.mk:
# Generated by VisualGDB APP_MODULES := APP_ABI := all
For the UnitTestSimpleMath executable project, the .mk files are the following:
For Android.mk:
# Generated by VisualGDB LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := GoogleTest-static LOCAL_SRC_FILES := ../../GoogleTest/obj/local/armeabi/libGoogleTest-static.a LOCAL_EXPORT_C_INCLUDES := D:/Dev/gtest-1.7.0/include D:/Dev/gtest-1.7.0 include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) GTEST_DIR := D:/Dev/gtest-1.7.0 LOCAL_MODULE := UnitTestSimpleMath #VisualGDBAndroid: AutoUpdateSourcesInNextLine LOCAL_SRC_FILES := UnitTestSimpleMath.cpp LOCAL_C_INCLUDES := ../SimpleMath/jni D:/Dev/gtest-1.7.0/include D:/Dev/gtest-1.7.0 LOCAL_SHARED_LIBRARIES := LOCAL_STATIC_LIBRARIES := GoogleTest-static LOCAL_STATIC_LIBRARIES += SimpleMath-static LOCAL_LDLIBS := LOCAL_CFLAGS := LOCAL_CPPFLAGS := LOCAL_LDFLAGS := LOCAL_LDFLAGS := COMMON_SRC_FILES := $(LOCAL_SRC_FILES) include $(BUILD_EXECUTABLE) $(call import-module,third_party/googletest)
For Application.mk:
# Generated by VisualGDB APP_ABI := all APP_STL := gnustl_shared APP_OPTIM := debug
The problem I have been having is that, while the GoogleTest and SimpleMath code builds fine, building the UnitTestSimpleMath project fails. This is because it is unable to find references to GoogleTest functions, giving errors such as: UnitTestSimpleMath.cpp:14: error: undefined reference to ‘testing::InitGoogleTest(int*, char**)’. After much Google searching, the .mk files above have formed into what they are now, but something is still missing to complete the build.
I can add the following to the UnitTestSimpleMathTest’s .mk file: LOCAL_SRC_FILES += D:/Dev/gtest-1.7.0/src/gtest-all.cc. The project will then build and run on the Android OS. However, this should not be necessary. It voids the reason to have a GoogleTest static library, with the code contained nicely separated elsewhere, and not dragged in to this project. Also, in the many edits of the .mk files and NO errors reported as to why and what is happening, I discovered that removing or just entering bogus library names made no difference to the build outcome:
LOCAL_STATIC_LIBRARIES := GooxxxxxgleTest-static LOCAL_STATIC_LIBRARIES += SimxxxxpleMath-static
They appear to do nothing, yet every example of how to build an Android program and link in a static library has this LOCAL_STATIC_LIBRARIES entry. Also consider the following lines:
include $(CLEAR_VARS) LOCAL_MODULE := GoogleTest-static LOCAL_SRC_FILES := ../../GoogleTest/obj/local/armeabi/libGoogleTest-static.a LOCAL_EXPORT_C_INCLUDES := D:/Dev/gtest-1.7.0/include D:/Dev/gtest-1.7.0 include $(PREBUILT_STATIC_LIBRARY)
These can be removed from the same .mk file without any errors or information, or changing the outcome of the build, apart from just not building. Though I have had a learning curve with using VisualGDB, and with the general concept of building an Android static linked program, I believe that the problem simply lies with the .mk file itself.
September 11, 2014 at 10:09 #3377IllyaParticipantThough I believe the problem is likely to be with usage of the .mk file there is a possibility that VisualGDB is not handling the .mk file correctly. I would like this either confirmed or otherwise.
September 16, 2014 at 03:17 #3376ketParticipantHi,
Getting the linking syntax correct in Android makefiles can be tricky as different path syntax is expected for different variables. Some variable values only work with relative paths or paths relative to LOCAL_PATH. VisualGDB only passes the makefiles along to make, so the problem must lie within the makefiles.
VisualGDB handles the library dependencies of projects inside the same solution automatically if you set project dependencies. With the logic VisualGDB uses for its library dependencies each library project is built separately when VS builds them, the projects dependent on other library projects do not rebuild them.
Have you tried looking at our Android library tutorial for help? -
AuthorPosts
- You must be logged in to reply to this topic.