tesseract-ocr / tesseract

Tesseract Open Source OCR Engine (main repository)
https://tesseract-ocr.github.io/
Apache License 2.0
62.25k stars 9.51k forks source link

build for Android/i686,x86-64 failed due to 'asm/hwcap.h' file not found #3680

Open leleliu008 opened 2 years ago

leleliu008 commented 2 years ago

Environment

Current Behavior:

/tmp/tmp.wrf96PRFHZ/src/arch/simddetect.cpp:60:14: fatal error: 'asm/hwcap.h' file not found
#    include <asm/hwcap.h>
             ^~~~~~~~~~~~~
1 error generated.

Android NDK not provide asm/hwcap.h for i686,x86-64

Expected Behavior:

successfully build for Android/i686

Suggested Fix:

change macro ANDROID to __ANDROID__, __ANDROID__ macro is pre-defined by Android NDK toolchain

https://github.com/tesseract-ocr/tesseract/blob/main/src/arch/simddetect.cpp#L56

2

stweil commented 2 years ago

I wonder why that code lines are used at all, because they should only be used if HAVE_NEON is defined. And Intel CPUs should not define that macro because they don't have NEON instructions.

leleliu008 commented 2 years ago
CHECK_CXX_COMPILER_FLAG("-mfpu=neon" HAVE_NEON)
if(HAVE_NEON)
    set(NEON_COMPILE_FLAGS "-mfpu=neon")
    add_definitions("-DHAVE_NEON")
endif()
stweil commented 2 years ago

That part should fail for Android/i686 and only be used for Android/arm*.

leleliu008 commented 2 years ago

no, HAVE_NEON always TRUE, I'm sure.

leleliu008 commented 2 years ago
CHECK_CXX_COMPILER_FLAG("-mfpu=neon" HAVE_NEON)

HAVE_NEON=FALSE when CXX=gcc HAVE_NEON=TRUE when CXX=clang

Android NDK using clang

stweil commented 2 years ago

Which operation system / distribution / clang do you use? Please post the output of clang --version, too.

leleliu008 commented 2 years ago

CMakeLists.txt:

cmake_minimum_required(VERSION 3.0.0)

project(test CXX)

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-mfpu=neon" HAVE_NEON)
if(HAVE_NEON)
    message("HAVE_NEON")
endif()

build with following command:

cmake -S . -B build.d -DCMAKE_CXX_COMPILER=gcc
cmake -S . -B build.d -DCMAKE_CXX_COMPILER=clang

3 4

uname -a :

Linux ubuntu 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/os-release:

NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

clang --version:

clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
zdenop commented 2 years ago

Clang 13 on Windows fails for HAVE_NEON:

cmake -S . -B build.d -G Ninja
-- The CXX compiler identification is Clang 13.0.0 with MSVC-like command-line
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang-cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_NEON
-- Performing Test HAVE_NEON - Failed
-- Configuring done
-- Generating done
-- Build files have been written to: F:/Project-Personal/tesseract/testneon/build.d

Visual Studio 2019 fails too:

cmake -S . -B build.d
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.20348.0 to target Windows 10.0.19042.
-- The CXX compiler identification is MSVC 19.29.30137.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_NEON
-- Performing Test HAVE_NEON - Failed
-- Configuring done
-- Generating done
-- Build files have been written to: F:/Project-Personal/tesseract/testneon/build.d

Can you update clang to resent version?

leleliu008 commented 2 years ago

I tried the clang-13 and got the same result

5

amitdo commented 2 years ago

There was a similar issue with clang+autotools:

https://github.com/tesseract-ocr/tesseract/pull/2978#discussion_r430073351

leleliu008 commented 2 years ago

I wanna cross-build this project for Android(armv7a, aarch64, i686, x86_64) via Android NDK toolchain

Android/armv7a and Android/aarch64 are successfully built, build for Android/i686,x86-64 failed due to 'asm/hwcap.h' file not found.

amitdo commented 2 years ago

https://github.com/tesseract-ocr/tesseract/blob/82f510fe1e96127f251502c3ee24d328d38f676e/CMakeLists.txt#L152-L154

https://github.com/tesseract-ocr/tesseract/blob/82f510fe1e96127f251502c3ee24d328d38f676e/CMakeLists.txt#L236

Some other projects that use cmake have x86_64.* as one option in the regular expression.

amitdo commented 2 years ago

The regex also does not include i686.

leleliu008 commented 2 years ago

https://github.com/tesseract-ocr/tesseract/blob/82f510fe1e96127f251502c3ee24d328d38f676e/CMakeLists.txt#L223-L234

leleliu008 commented 2 years ago
gsed -i 's/x86|AMD64/i686|x86_64/' CMakeLists.txt

this change works for me.

amitdo commented 2 years ago

https://github.com/tesseract-ocr/tesseract/commit/5fd8bfb5ecbe3fb6605892870fdf809b3b5e4789

leleliu008 commented 2 years ago

@amitdo ANDROID macro should be changed to __ANDROID__, __ANDROID__ macro is pre-defined by Android NDK

leleliu008 commented 2 years ago

@amitdo I find this project using the cpufeatures library shipped with Android NDK, it is deprecated and replaced with https://github.com/google/cpu_features, Reference: https://developer.android.com/ndk/guides/cpu-features

stweil commented 2 years ago

ANDROID macro should be changed to __ANDROID__, __ANDROID__ macro is pre-defined by Android NDK

The discussion is not so clear whether that would work for everybody. I think we should either continue to check for ANDROID or check both macros.

stweil commented 2 years ago

I find this project using the cpufeatures library shipped with Android NDK

It is used only in (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) as far as I see. Do you think this is a problem? If yes, why?

leleliu008 commented 2 years ago

Android NDK has changed gcc to llvm many years. and old versions are marked as deprecated. I never saw ANDROID macro.

leleliu008 commented 2 years ago

6

this project just include the cpu-features.h, not compile the cpu-features.c, people who wanna compile from source is not easy.

https://github.com/google/cpu_features is very easy to integrate with our project. this new library is compat with the old one, the source code you have already written do not need to change. the only need to do is adding following code to our CMakeLists.txt:

find_package(CpuFeaturesNdkCompat)
if (CpuFeaturesNdkCompat_FOUND)
     target_link_libraries(xx PRIVATE CpuFeatures::ndk_compat)
endif()
zdenop commented 2 years ago

Please send PR.

BTW: did you tried cross-compile on windows e.g. like this https://bucket401.blogspot.com/2021/07/crosscompile-tesseract-for-android-on.html

leleliu008 commented 2 years ago

Sorry, I'm not familiar with windows, I use Windows now though, I just use it's web broswer and WSL2.

leleliu008 commented 2 years ago

I have writting a package manager for Android NDK in POSIX shell, but not support windows. If you are interested it, here is the link https://github.com/leleliu008/ndk-pkg

amitdo commented 2 years ago

CC:@Robyer

https://github.com/tesseract-ocr/tesseract/issues/3680#issuecomment-996604361

What do you recommend to use to detect Android in an ifdef condition?