tdlib / td

Cross-platform library for building Telegram clients
https://core.telegram.org/tdlib
Boost Software License 1.0
6.96k stars 1.43k forks source link

build for IOS #38

Closed mrH3ktor closed 6 years ago

mrH3ktor commented 6 years ago

How can i build this for IOS?

isopen commented 6 years ago

Did not check. But maybe try libtdjson.

arseny30 commented 6 years ago

It is possible to build libtdjson with cmake and some cmake toolchain for ios. Also you will need zlib and openssl built for ios.

We are planning publish some examples and build scripts soon.

mrH3ktor commented 6 years ago

I have try to build with /CMake/iOS.cmake but i got this error:

CMake Warning at CMakeLists.txt:206 (message): Not found OpenSSL: skip TDLib, tdactor, tdnet, tddb

and have this in log

Could NOT find ccache Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR)

levlam commented 6 years ago

You are on a right track, but "Also you will need zlib and openssl built for ios". We will include instructions on how to build these libraries for iOS in our Swift example, but there are many of them that can be publicly found.

KuroiDOC commented 6 years ago

@mrH3ktor I've managed to build it by first building OpenSSL for iOS (I used this project for a quick try https://github.com/x2on/OpenSSL-for-iPhone) and then manually setting OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY and OPENSSL_INCLUDE_DIR to those.

mrH3ktor commented 6 years ago

Thanks guys. i pass that error and now getting another one. at first i add this line to /CMake/iOS.cmake file: set(OPENSSL_CRYPTO_LIBRARY /Volumes/Project/TDLib/OpenSSL-for-iPhone/lib/libcrypto.a) set(OPENSSL_SSL_LIBRARY /Volumes/Project/TDLib/OpenSSL-for-iPhone/lib/libssl.a) set(OPENSSL_INCLUDE_DIR /Volumes/Project/TDLib/OpenSSL-for-iPhone/include)

then run this command: cmake .. -DCMAKE_TOOLCHAIN_FILE=../CMake/iOS.cmake -DIOS_PLATFORM=SIMULATOR

i got this log: -- Found ccache -- Toolchain using default iOS SDK: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk -- i386x86_64 -- Found ccache -- i386x86_64 -- The CXX compiler identification is AppleClang 9.0.0.9000039 -- The C compiler identification is AppleClang 9.0.0.9000039 -- Check for working CXX compiler: /usr/bin/g++ -- Check for working CXX compiler: /usr/bin/g++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Check for working C compiler: /usr/bin/gcc -- Check for working C compiler: /usr/bin/gcc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Use link time optimizations: -flto=thin -- Found ccache -- Found OpenSSL: /Volumes/Project/TDLib/OpenSSL-for-iPhone/lib/libcrypto.a (found version "1.0.2l") -- Found OpenSSL: /Volumes/Project/TDLib/OpenSSL-for-iPhone/include /Volumes/Project/TDLib/OpenSSL-for-iPhone/lib/libssl.a;/Volumes/Project/TDLib/OpenSSL-for-iPhone/lib/libcrypto.a -- Performing Test HAVE_STD14 -- Performing Test HAVE_STD14 - Success -- Looking for pthread.h -- Looking for pthread.h - found -- Looking for pthread_create -- Looking for pthread_create - found -- Found Threads: TRUE -- Performing Test HAVE_CXX_FLAG_WALL -- Performing Test HAVE_CXX_FLAG_WALL - Success -- Performing Test HAVE_CXX_FLAG_WEXTRA -- Performing Test HAVE_CXX_FLAG_WEXTRA - Success -- Performing Test HAVE_CXX_FLAG_WIMPLICIT_FALLTHROUGH_2 -- Performing Test HAVE_CXX_FLAG_WIMPLICIT_FALLTHROUGH_2 - Failed -- Performing Test HAVE_CXX_FLAG_WPOINTER_ARITH -- Performing Test HAVE_CXX_FLAG_WPOINTER_ARITH - Success -- Performing Test HAVE_CXX_FLAG_WCAST_QUAL -- Performing Test HAVE_CXX_FLAG_WCAST_QUAL - Success -- Performing Test HAVE_CXX_FLAG_WSIGN_COMPARE -- Performing Test HAVE_CXX_FLAG_WSIGN_COMPARE - Success -- Performing Test HAVE_CXX_FLAG_WDUPLICATED_BRANCHES -- Performing Test HAVE_CXX_FLAG_WDUPLICATED_BRANCHES - Failed -- Performing Test HAVE_CXX_FLAG_WDUPLICATED_COND -- Performing Test HAVE_CXX_FLAG_WDUPLICATED_COND - Failed -- Performing Test HAVE_CXX_FLAG_WALLOC_ZERO -- Performing Test HAVE_CXX_FLAG_WALLOC_ZERO - Failed -- Performing Test HAVE_CXX_FLAG_WLOGICAL_OP -- Performing Test HAVE_CXX_FLAG_WLOGICAL_OP - Failed -- Performing Test HAVE_CXX_FLAG_WTAUTOLOGICAL_COMPARE -- Performing Test HAVE_CXX_FLAG_WTAUTOLOGICAL_COMPARE - Success -- Performing Test HAVE_CXX_FLAG_WVLA -- Performing Test HAVE_CXX_FLAG_WVLA - Success -- Performing Test HAVE_CXX_FLAG_WNON_VIRTUAL_DTOR -- Performing Test HAVE_CXX_FLAG_WNON_VIRTUAL_DTOR - Success -- Performing Test HAVE_CXX_FLAG_WUNUSED_PARAMETER -- Performing Test HAVE_CXX_FLAG_WUNUSED_PARAMETER - Success -- Performing Test HAVE_CXX_FLAG_WCONVERSION -- Performing Test HAVE_CXX_FLAG_WCONVERSION - Success -- Performing Test HAVE_CXX_FLAG_WSIGN_CONVERSION -- Performing Test HAVE_CXX_FLAG_WSIGN_CONVERSION - Success -- Performing Test HAVE_CXX_FLAG_WCXX14_COMPAT_PEDANTIC -- Performing Test HAVE_CXX_FLAG_WCXX14_COMPAT_PEDANTIC - Success -- Performing Test HAVE_CXX_FLAG_QUNUSED_ARGUMENTS -- Performing Test HAVE_CXX_FLAG_QUNUSED_ARGUMENTS - Success -- Performing Test HAVE_CXX_FLAG_WODR -- Performing Test HAVE_CXX_FLAG_WODR - Success -- Performing Test HAVE_CXX_FLAG_FLTO_ODR_TYPE_MERGING -- Performing Test HAVE_CXX_FLAG_FLTO_ODR_TYPE_MERGING - Failed -- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk/usr/lib/libz.tbd (found version "1.2.11") -- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk/usr/include /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk/usr/lib/libz.tbd -- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY -- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success -- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY -- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success -- Performing Test COMPILER_HAS_DEPRECATED_ATTR -- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success -- Configuring done -- Generating done -- Build files have been written to: /Volumes/Project/TDLib/td/build

when i try to build i got this error: make[2]: *** No rule to make target../tdutils/generate/auto/mime_type_to_extension.cpp', needed by tdutils/CMakeFiles/tdutils.dir/generate/auto/mime_type_to_extension.cpp.o'. Stop. make[1]: *** [tdutils/CMakeFiles/tdutils.dir/all] Error 2 make: *** [all] Error 2

levlam commented 6 years ago

Some TDLib sources are generated and that can't be done directly when the library is cross-compiled. You need to run ones a native build to generate these sources before running cross-compilation: mkdir build_native cd build_native cmake .. cmake --build . --target prepare_cross_compiling

leoMehlig commented 6 years ago

I use this shell script to build the libraries for iOS:

rm -Rf build
mkdir build
cd build
git clone https://github.com/tdlib/td.git
git clone https://github.com/x2on/OpenSSL-for-iPhone.git
cd OpenSSL-for-iPhone
./build-libssl.sh
cd ..
cd td
mkdir build_nativ
cd build_nativ
cmake -DCMAKE_BUILD_TYPE=Release -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl/ ..
cmake --build .
cd ..
mkdir build_os
cd build_os
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../CMake/iOS.cmake -DIOS_PLATFORM=OS -DIOS_DEPLOYMENT_TARGET=10.0 -DOPENSSL_CRYPTO_LIBRARY=../../OpenSSL-for-iPhone/lib/libcrypto.a -DOPENSSL_SSL_LIBRARY=../../OpenSSL-for-iPhone/lib/libssl.a -DOPENSSL_INCLUDE_DIR=../../OpenSSL-for-iPhone/include ..
cmake --build .
cd ..
mkdir build_sim
cd build_sim
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../CMake/iOS.cmake -DIOS_PLATFORM=SIMULATOR -DIOS_DEPLOYMENT_TARGET=10.0 -DOPENSSL_CRYPTO_LIBRARY=../../OpenSSL-for-iPhone/lib/libcrypto.a -DOPENSSL_SSL_LIBRARY=../../OpenSSL-for-iPhone/lib/libssl.a -DOPENSSL_INCLUDE_DIR=../../OpenSSL-for-iPhone/include ..
cmake --build .
cd ../..
cd build
mkdir tdlibs
cd tdlibs
for lib_path in libtdclient.a sqlite/libtdsqlite.a tdtl/libtdtl.a libtdcore.a tdactor/libtdactor.a tdutils/libtdutils.a libmemprof.a libtdjson_private.a tddb/libtddb.a libtdc.a libtdjson_static.a tdnet/libtdnet.a
do
    lipo -create -output ${lib_path#*/} "../td/build_os/$lib_path" "../td/build_sim/$lib_path"
done
cp ../td/td/telegram/td_json_client.h td_json_client.h
cp -R ../td/build_os/td td
cd  ..
rm -Rf td

This will create a build folder. Just include all .a files in build/tdlibs and in build/OpenSSL-for-iPhone/lib and the attached modualmap in your project. module.modulemap.zip

You might need to tweak some build settings. Feel free to ask!

And if someone has any recommendation on how to optimise the build or the linking time in Xcode! Please!!!

Sanich63 commented 6 years ago

@leoMehlig Thanks for the script and instructions!

But could you help me with the problem of compiling the project when I try to use these libraries directly in the iOS project?

I have successfully created libraries using your shell script, most likely without errors, here is the result of running the script: https://pastebin.com/YCdw2FiD

At the output, I got these files: http://dl4.joxi.net/drive/2018/03/16/0017/3582/1146366/66/3bd9bdb95b.png

I added the folders "OpenSSL-for-iPhone", "tdlibs" and the file "module.modulemap" to the project: http://dl4.joxi.net/drive/2018/03/16/0017/3582/1146366/66/e22a8f4a6f.png

Project location path: /NAV-TDLib-Test/NAV-TDLib-Test.xcodeproj

The hierarchy of paths for the location of files and folders with libraries:

/NAV-TDLib-Test/NAV-TDLib-Test/tdlibs
/NAV-TDLib-Test/NAV-TDLib-Test/OpenSSL-for-iPhone
/NAV-TDLib-Test/NAV-TDLib-Test/module.modulemap

Added all links to libraries and files by editing the required keys in the "Build Settings" project settings in Xcode: 1) "Module Map File" MODULEMAP_FILE = NAV-TDLib-Test/module.modulemap

2) "Header Search Paths" ("/ **" at the end of the path indicate a recursive search)

HEADER_SEARCH_PATHS = 
$(inherited) 
"$(SRCROOT)/NAV-TDLib-Test/tdlibs"/** 
"$(SRCROOT)/NAV-TDLib-Test/OpenSSL-for-iPhone"/** 
"$(PROJECT_DIR)/NAV-TDLib-Test/tdlibs"/** 
"$(PROJECT_DIR)/NAV-TDLib-Test/OpenSSL-for-iPhone"/**

3) "Library Search Paths"

LIBRARY_SEARCH_PATHS = 
$(inherited) 
$(SRCROOT) 
$(PROJECT_DIR) 
$(SRCROOT)/NAV-TDLib-Test/tdlibs 
$(SRCROOT)/NAV-TDLib-Test/OpenSSL-for-iPhone 
$(PROJECT_DIR)/NAV-TDLib-Test/tdlibs 
$(PROJECT_DIR)/NAV-TDLib-Test/OpenSSL-for-iPhone

After this step with the import of all the necessary files, the project is successfully compiled.

And then there are problems when I try to use the C interface of the td_json library. After adding a link to the client file: #include "td_json_client.h", and trying to access it: void * client = td_json_client_create();

I start creating a build of the project for a simulator or a real device, and at the time of compilation and a long "Linking" procedure, a lot of critical compiler errors occur: "Undefined symbols for architecture x86_64" or "Undefined symbols for architecture arm64": http://dl3.joxi.net/drive/2018/03/16/0017/3582/1146366/66/9017eebb81.png https://pastebin.com/UjYKM2wr

Please, tell me, at least in what direction should I go, what would try to fix it.

leoMehlig commented 6 years ago

@Sanich63 Your file structure looks fine. I have not specified the MODULEMAP_FILE, but instead set the Import Path to $(PROJECT_DIR) (recursive). Also have haven't added the header file to my project. Can you check if this fixes something. Also make sure to delete the td source folder.

levlam commented 6 years ago

We have published example of building TDLib for iOS, watchOS and tvOS, which is also an alternative example of building TDLib for macOS.

WingedDoom commented 6 years ago

In the iOS example it is only shown how to build the library using the given scripts. The Swift example provides an .xcodeproj example, suggesting to add a produced libtdjson.dylib into Link binary with libraries phase.

But iOS Swift projects don't support adding pure .dylib files into a project. That way, the project compiles and runs fine, but when I was trying to submit it to the AppStore, I was getting Invalid Segments error during build submission. Now I've figured out that it is because libtdjson.dylib is a "fat" binary containing architectures for both simulator and actual devices. I've removed unneeded architectures using Run Script Build Phase in Xcode with $ARCHS environment variable and lipo, leaving only required architectures in the .dylib. But now I'm getting Invalid Swift Support error email, after I submit the build to the iTunesConnect.

According to this technical note on Apple Developer website (search for Embedded .dylib files section there), this is because I try to embed pure .dylib into an .ipa. It says it is not supported and I should wrap a .dylib into a framework.

But I couldn't find any description of how to do that. Can you please provide a usable Xcode project example or maybe tell in what direction I should go?

leoMehlig commented 6 years ago

For anyone else who is experiencing this issue, you can use my pre build framework (documentation will follow). Just download it from the release page basically.

WingedDoom commented 6 years ago

Maybe it is best to correct the build.sh for iOS, since distributing .dylibs is not supported by iTunesConnect.

Thanks to @leoMehlig very much, the custom build script works great, and the framework is fully suitable for AppStore Distribution. I added it to my workspace and the archive finally got uploaded :)

leoMehlig commented 6 years ago

There is nothing wrong with the build.sh. One should just not use the dylib in iOS, but instead the .a files with a modulemap.

WingedDoom commented 6 years ago

After running build.sh I was only able to find .a's in example/ios/build/ios/[here are sevaral folders like install-iOS, install-iOS-simulator, build-iOS, etc.]. It would require to run another script that makes a fat static libraries for both simulators and iOS devices with lipo after running build.sh. And it is not entirely clear (at least for not very experienced people like me) what folders to take the required libraries from (i.e. build-$platform or install-$platform).

olSolo commented 6 years ago

The instructions are completely incomplete. You can't just follow them and build it for iOS. Besides, no-one needs a .dylib as a result for an iOS app, because you can develop with it, but you can't go to AppStore with a .dylib included (it should be a .framework). Integrating TDLib is a great headache for me at the moment

WingedDoom commented 6 years ago

@olSolo this is exactly what I am talking about. Thankfully, @leoMehlig did leave a working link above.

olSolo commented 6 years ago

@WingedDoom yeah, @leoMehlig did a great job. Unfortunately I can't use a pre-built framework from an unknown source in my project, so my final hope is @leoMehlig's build script

leoMehlig commented 6 years ago

There is a build script in the project of the prebuilt framework. I use this one to build the project on Travis. You should be able to build it using this script. Maybe take a look at the .travis.yml file.

Sent from my iPhone

On 31. Jul 2018, at 16:18, olSolo notifications@github.com wrote:

@WingedDoom yeah, @leoMehlig did a great job. Unfortunately I can't use a pre-built framework from an unknown source in my project, so my final hope is @leoMehlig's build script

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

levlam commented 6 years ago

@olSolo Apple has this documentation on embedding dylib into a Framework. But I haven't tested, whether this is enough to create an iOS app suitable for uploading to AppStore.

olSolo commented 6 years ago

@leoMehlig I get "No such module: libtdjson" error when I try to use the precompiled framework or when I use same framework but with built by myself .a libraries. No idea what to do :(

leoMehlig commented 6 years ago

@olSolo Can you provide more information. Maybe take a look at the modulemap. PS. I think this should be discussed in an issue on the TDJSON repo.

olSolo commented 6 years ago

@leoMehlig well, I build the framework, embed it in my project, in the file that use TDLib methods I do import TDJSON. On my machine it works great even after all kinds of cleaning and deleting Derived Data, but on the CI machine there is "Missing required module 'libtdjson' in the file that uses TDLib.

The module map is default:

module libtdjson [system][extern_c] { header "include/td/telegram/td_json_client.h" header "include/td/telegram/td_log.h" export * }

leoMehlig commented 6 years ago

@olSolo Are you also build tdlib on your CI? Maybe you are missing some .a file. One is too big for git, so it's ignored and instead in the release as a download.

olSolo commented 6 years ago

@leoMehlig no, the TDJSON.framework was taken already assembled from the repository. Yet no ideas

brilliant-mobile-dev commented 2 weeks ago

Dear all. How do I embed TDLib into an iOS app? I have completed the build step and found a lot of directories. I do follow the example project in the Swift folder, I have embedded libdtjson.dylib to my project and added .h file as well, but I got an error that the file was not found in the .h file, and I cannot access any functionality inside.