Taymindis/backcurl

C++11 Compilation fails on Ubuntu 18.04 (cmake 3.10.2)

moddx opened this issue · 9 comments

moddx commented

error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options

Compilation fails with above message. The master CMakeLists.txt file does not enable c++11 support correcty for cmake 3.10.x. The following check fails:

if(NOT ${CMAKE_VERSION} LESS 3.2)
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
else()

Apparently cmake sees cmake 3.10.x as lower than 3.2.0.
This behavior can befixed by comparing against version 3.1.0 (which is the minimum version for the CMAKE_CXX_STANDARD flag afaik, but don't quote me on that).

HI moddx,

I've fixed the build script , you may try to clone latest source to rebuild

However, If you are using on linux system only, You can use this build Build backcurl core lib only

moddx commented

Thanks, it's working fine now!
I have trouble including the library into an android project though.

I am using cmake and tried to add it to my CMakeLists.txt, but to no avail. Previously I included other libraries with single headers just fine.
Maybe it is also possible to include just the .so and .a files, but I am not entirely sure how.

Is there a goto way of including this library in an android project.
I would like to use this library in a multi-platform context and run it on both android and ios.

moddx commented

Thanks for helping out!
This is a simplified version of my CMakeLists.txt.
To make it easier one could also just assume that backcurl gets called directly via native-lib and omit the other two libraries. I included them here just to show you what I mean.

cmake_minimum_required(VERSION 3.4.1)

# My JNI interface
add_library( 
    # Sets the name of the library.
	native-lib

	# Sets the library as a shared library.
	SHARED

	# Provides a relative path to your source file(s).
	src/main/cpp/native-lib.cpp
)

# My actual library (multiple headers and impl. files)
add_library(
    # Name
    my-library
    # Shared or Static
    SHARED
    # source files (relative)
    src/main/cpp/mylibrary/something.h
    src/main/cpp/mylibrary/somethingElse.cpp
    src/main/cpp/mylibrary/somethingElse.h
)

# A third-party library needed by my library. (uses only a single header)
add_library(
    # Name
    json
    # Shared or Static
    SHARED
    # source files (relative)
    src/main/cpp/json.hpp
)
set_target_properties(json PROPERTIES LINKER_LANGUAGE CXX)

# Could I add BackCurl this way? Which files do I include?
# add_library(
# 	 # Name
#	 backcurl
#	 # ..
# )

find_library( 
	# Sets the name of the path variable.
	log-lib

	# Specifies the name of the NDK library that
	# you want CMake to locate.
	log
)

target_link_libraries(my-library json)
# target_link_libraries(my-library json backcurl)

target_link_libraries( 
	# Specifies the target library.
	native-lib

	# link my library
	my-library

	# Links the target library to the log library
	# included in the NDK.
	${log-lib}
)

Hi Moddx,

I will suggested you to use Android.mk

Step 1 :
To build Android: goto

cd backcurl-android/
./build

you will see the backcurl android lib located at cd backcurl-android/obj/local/{APP_ABI}/

Step 2:
locate libcurl library which located at curl-android-ios/prebuilt-with-ssl/android/

step 3:
Prepare Android.mk and link the lib with it. For example

LOCAL_PATH := $(call my-dir)

#cURL prebuilt
include $(CLEAR_VARS)
LOCAL_MODULE := curl-prebuilt
LOCAL_SRC_FILES := \
  ../../../curl-android-ios/prebuilt-with-ssl/android/$(TARGET_ARCH_ABI)/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
################################################################################

#BackCurl prebuilt
include $(CLEAR_VARS)
LOCAL_MODULE := backcurl-prebuilt
LOCAL_SRC_FILES := \
  ../../../backcurl-android/obj/local/$(TARGET_ARCH_ABI)/libbackcurl.a
include $(PREBUILT_STATIC_LIBRARY)
################################################################################

include $(CLEAR_VARS)

LOCAL_MODULE := main

LOCAL_C_INCLUDES := \
		$(LOCAL_PATH)/../../../curl-android-ios/prebuilt-with-ssl/android/include \
		$(LOCAL_PATH)/../../../backcurl-core/header \
		$(LOCAL_PATH)/../../../yourheaders

#SDK_ROOT points to folder with SDL and oxygine-framework
LOCAL_SRC_FILES := ../../../../../..//SDL/src/main/android/SDL_android_main.c

# LOCAL_SRC_FILES += ../../../src/example.cpp ../../../src/main.cpp 
# LOCAL_CFLAGS := -std=c++11

FILE_LIST := $(wildcard $(LOCAL_PATH)/../../../src/*.cpp)
LOCAL_SRC_FILES += $(FILE_LIST:$(LOCAL_PATH)/%=%)

LOCAL_SRC_FILES += ../../../src/fb_plugin/android/AndroidFacebook.cpp \
					../../../src/fb_plugin/facebook.cpp \
					../../../src/cpp_bridge/cpp_bridging.cpp \
					../../../src/cpp_bridge/android/android_bridge.cpp \
					../../../src/utils/Helper.cpp \
					../../../src/utils/SceneActor.cpp \
					../../../src/nanovg.c

# LOCAL_STATIC_LIBRARIES := oxygine-flow_static oxygine-framework_static oxygine-sound_static curl-prebuilt backcurl-prebuilt
LOCAL_STATIC_LIBRARIES := oxygine-framework_static oxygine-sound_static curl-prebuilt backcurl-prebuilt
LOCAL_SHARED_LIBRARIES := SDL2

include $(BUILD_SHARED_LIBRARY)


#import from NDK_MODULE_PATH defined in build.cmd
$(call import-module, oxygine-framework)
# $(call import-module, oxygine-flow)
$(call import-module, oxygine-sound)

Alternatively,

Just add the source located at backcurl-core/src/BackCurl.cpp and header file located at
backcurl-core/header/BackCurl.h into your android project. Make sure locate libcurl library which located at curl-android-ios/prebuilt-with-ssl/android/ with your project.

moddx commented

Hey @cindlee, thank you for your detailed instructions. I would like to keep Android.mk out of my project as much as possible, since I want to support both android and ios. Your instruction however made many things clear to me and also showed me that I was missing the prebuilt submodules (I did not explicitly pull/update those).
Thanks to your help, I mirrored your instructions to cmake and got it very close to working.

I add BackCurl as static library and point it to its header file.

add_library(
    backcurl
    STATIC
    src/main/cpp/backcurl/backcurl-core/src/BackCurl.cpp
)
include_directories(src/main/cpp/backcurl/backcurl-core/header)

Then I add the prebuilt curl library, and specify the location of the include files and the prebuilt .a files:

add_library(
    curl
    STATIC
    IMPORTED
)
set_target_properties(
    curl
    PROPERTIES IMPORTED_LOCATION
    /home/matt/dev/androidcpp/app/src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/${ANDROID_ABI}/libcurl.a
)
include_directories(src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/include)

Lastly I link those two together:

target_link_libraries(backcurl curl)

When trying to use backcurl however, I get the following linker error(s):

[1/1] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so
FAILED: : ...CROPPED... libbackcurl.a ../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a ...CROPPED...:

../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(version.o):function curl_version: error: undefined reference to 'zlibVersion'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(version.o):function curl_version_info: error: undefined reference to 'zlibVersion'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function Curl_unencode_deflate_write: error: undefined reference to 'inflateInit_'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function inflate_stream: error: undefined reference to 'inflate'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function inflate_stream: error: undefined reference to 'inflateEnd'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function inflate_stream: error: undefined reference to 'inflateInit2_'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function inflate_stream: error: undefined reference to 'inflateEnd'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function inflate_stream: error: undefined reference to 'inflateEnd'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function inflate_stream: error: undefined reference to 'inflateEnd'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function Curl_unencode_gzip_write: error: undefined reference to 'zlibVersion'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function Curl_unencode_gzip_write: error: undefined reference to 'inflateInit2_'
../../../../src/main/cpp/backcurl/curl-android-ios/prebuilt-with-ssl/android/armeabi-v7a/libcurl.a(content_encoding.o):function Curl_unencode_gzip_write: error: undefined reference to 'inflateInit2_'

To me this looks like the prebuilt curl library is missing some zlib stuff from/for openssl? How do I link those? Do I need to? I see nothing of the like in your Android.mk script.

You missing of lz (zlib), try to link lz and it’s header.

I will suggest you defined link_directories which include the curl library path. Do not use add_library for curl as it already built

moddx commented

Thank you I think it is working now.

The missing part was as simple as adding 'z' to the target_link_libraries directive, since zlib is already provided by the ndk. Like so:

target_link_libraries(backcurl curl z)

PS: The documentation on link_directories states:

Note that this command is rarely necessary. Library locations returned by find_package() and find_library() are absolute paths. Pass these absolute library file paths directly to the target_link_libraries() command. CMake will ensure the linker finds them.

Thus the recommended way to include prebuilt libs is using add_library, set_target_properties, include_directories and lastly target_link_libraries, as stated in the official instructions on configuring cmake.

Thank you all for all your help and support!

Congratz, Enjoy your backcurl!

It helps me done a lot of non blocking calling on multiplayer game.