vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b
This commit is contained in:
@@ -0,0 +1 @@
|
||||
See http://opencv.org/platforms/android
|
||||
@@ -0,0 +1,117 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'maven-publish'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'org.opencv'
|
||||
compileSdk ${COMPILE_SDK}
|
||||
ndkVersion "${NDK_VERSION}"
|
||||
|
||||
defaultConfig {
|
||||
minSdk ${MIN_SDK}
|
||||
targetSdk ${TARGET_SDK}
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags ""
|
||||
arguments "-DANDROID_STL=${LIB_TYPE}"
|
||||
}
|
||||
}
|
||||
ndk {
|
||||
abiFilters ${ABI_FILTERS}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_${JAVA_VERSION}
|
||||
targetCompatibility JavaVersion.VERSION_${JAVA_VERSION}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
prefabPublishing true
|
||||
buildConfig true
|
||||
}
|
||||
prefab {
|
||||
${LIB_NAME} {
|
||||
headers "src/main/cpp/include"
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs = ['src/main/java']
|
||||
//jniLibs.srcDirs = ['libs']
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
singleVariant('release') {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
release(MavenPublication) {
|
||||
// Builds aar, sources jar and javadoc jar from project sources and creates maven
|
||||
groupId = 'org.opencv'
|
||||
artifactId = '${PACKAGE_NAME}'
|
||||
version = '${OPENCV_VERSION}'
|
||||
afterEvaluate {
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
modified(MavenPublication) {
|
||||
// Creates maven from opencv-release.aar
|
||||
groupId = 'org.opencv'
|
||||
artifactId = '${PACKAGE_NAME}'
|
||||
version = '${OPENCV_VERSION}'
|
||||
artifact("opencv-release.aar")
|
||||
pom {
|
||||
name = "OpenCV"
|
||||
description = "Open Source Computer Vision Library"
|
||||
url = "https://opencv.org/"
|
||||
licenses {
|
||||
license {
|
||||
name = "The Apache License, Version 2.0"
|
||||
url = "https://github.com/opencv/opencv/blob/master/LICENSE"
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = "admin"
|
||||
name = "OpenCV Team"
|
||||
email = "admin@opencv.org"
|
||||
}
|
||||
}
|
||||
scm {
|
||||
connection = "scm:git:https://github.com/opencv/opencv.git"
|
||||
url = "https://github.com/opencv/opencv"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
name = 'myrepo'
|
||||
url = "${project.buildDir}/repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project("opencv")
|
||||
|
||||
add_library(${LIB_NAME} ${LIB_TYPE} native-lib.cpp)
|
||||
@@ -0,0 +1 @@
|
||||
// This empty .h file is used for creating an AAR with empty C++ lib that will be replaced with OpenCV C++ lib
|
||||
@@ -0,0 +1 @@
|
||||
// This empty .cpp file is used for creating an AAR with empty C++ lib that will be replaced with OpenCV C++ lib
|
||||
@@ -0,0 +1,29 @@
|
||||
## Scripts for creating an AAR package and a local Maven repository with OpenCV libraries for Android
|
||||
|
||||
### How to run the scripts
|
||||
1. Set JAVA_HOME and ANDROID_HOME environment variables. For example:
|
||||
```
|
||||
export JAVA_HOME=~/Android Studio/jbr
|
||||
export ANDROID_HOME=~/Android/SDK
|
||||
```
|
||||
2. Download OpenCV SDK for Android
|
||||
3. Run build script for version with Java and a shared C++ library:
|
||||
```
|
||||
python build_java_shared_aar.py "~/opencv-4.7.0-android-sdk/OpenCV-android-sdk"
|
||||
```
|
||||
4. Run build script for version with static C++ libraries:
|
||||
```
|
||||
python build_static_aar.py "~/opencv-4.7.0-android-sdk/OpenCV-android-sdk"
|
||||
```
|
||||
The AAR libraries and the local Maven repository will be created in the **outputs** directory
|
||||
### Technical details
|
||||
The scripts consist of 5 steps:
|
||||
1. Preparing Android AAR library project template
|
||||
2. Adding Java code to the project. Adding C++ public headers for shared version to the project.
|
||||
3. Compiling the project to build an AAR package
|
||||
4. Adding C++ binary libraries to the AAR package. Adding C++ public headers for static version to the AAR package.
|
||||
5. Creating Maven repository with the AAR package
|
||||
|
||||
There are a few minor limitations:
|
||||
1. Due to the AAR design the Java + shared C++ AAR package contains duplicates of C++ binary libraries, but the final user's Android application contains only one library instance.
|
||||
2. The compile definitions from cmake configs are skipped, but it shouldn't affect the library because the script uses precompiled C++ binaries from SDK.
|
||||
@@ -0,0 +1,5 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.library' version '8.6.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.20' apply false
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
#Mon Jul 10 11:57:38 SGT 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,16 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
rootProject.name = "OpenCV"
|
||||
include ':OpenCV'
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import unittest
|
||||
import os, sys, subprocess, argparse, shutil, re
|
||||
import logging as log
|
||||
|
||||
log.basicConfig(format='%(message)s', level=log.DEBUG)
|
||||
|
||||
CMAKE_TEMPLATE='''\
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
|
||||
|
||||
# Enable C++17
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
|
||||
SET(PROJECT_NAME hello-android)
|
||||
PROJECT(${PROJECT_NAME})
|
||||
|
||||
FIND_PACKAGE(OpenCV REQUIRED %(libset)s)
|
||||
FILE(GLOB srcs "*.cpp")
|
||||
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${srcs})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS} dl z)
|
||||
'''
|
||||
|
||||
CPP_TEMPLATE = '''\
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
using namespace cv;
|
||||
const char* message = "Hello Android!";
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
printf("%s\\n", message);
|
||||
Size textsize = getTextSize(message, FONT_HERSHEY_COMPLEX, 3, 5, 0);
|
||||
Mat img(textsize.height + 20, textsize.width + 20, CV_32FC1, Scalar(230,230,230));
|
||||
putText(img, message, Point(10, img.rows - 10), FONT_HERSHEY_COMPLEX, 3, Scalar(0, 0, 0), 5);
|
||||
imwrite("/mnt/sdcard/HelloAndroid.png", img);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
#===================================================================================================
|
||||
|
||||
class TestCmakeBuild(unittest.TestCase):
|
||||
def __init__(self, libset, abi, cmake_vars, opencv_cmake_path, workdir, *args, **kwargs):
|
||||
unittest.TestCase.__init__(self, *args, **kwargs)
|
||||
self.libset = libset
|
||||
self.abi = abi
|
||||
self.cmake_vars = cmake_vars
|
||||
self.opencv_cmake_path = opencv_cmake_path
|
||||
self.workdir = workdir
|
||||
self.srcdir = os.path.join(self.workdir, "src")
|
||||
self.bindir = os.path.join(self.workdir, "build")
|
||||
|
||||
def shortDescription(self):
|
||||
return "ABI: %s, LIBSET: %s" % (self.abi, self.libset)
|
||||
|
||||
def getCMakeToolchain(self):
|
||||
if True:
|
||||
toolchain = os.path.join(os.environ['ANDROID_NDK'], 'build', 'cmake', 'android.toolchain.cmake')
|
||||
if os.path.exists(toolchain):
|
||||
return toolchain
|
||||
toolchain = os.path.join(self.opencv_cmake_path, "android.toolchain.cmake")
|
||||
if os.path.exists(toolchain):
|
||||
return toolchain
|
||||
else:
|
||||
raise Exception("Can't find toolchain")
|
||||
|
||||
def gen_cmakelists(self):
|
||||
return CMAKE_TEMPLATE % {"libset": self.libset}
|
||||
|
||||
def gen_code(self):
|
||||
return CPP_TEMPLATE
|
||||
|
||||
def write_src_file(self, fname, content):
|
||||
with open(os.path.join(self.srcdir, fname), "w") as f:
|
||||
f.write(content)
|
||||
|
||||
def setUp(self):
|
||||
if os.path.exists(self.workdir):
|
||||
shutil.rmtree(self.workdir)
|
||||
os.mkdir(self.workdir)
|
||||
os.mkdir(self.srcdir)
|
||||
os.mkdir(self.bindir)
|
||||
self.write_src_file("CMakeLists.txt", self.gen_cmakelists())
|
||||
self.write_src_file("main.cpp", self.gen_code())
|
||||
os.chdir(self.bindir)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
#if os.path.exists(self.workdir):
|
||||
# shutil.rmtree(self.workdir)
|
||||
|
||||
def runTest(self):
|
||||
cmd = [
|
||||
"cmake",
|
||||
"-GNinja",
|
||||
"-DOpenCV_DIR=%s" % self.opencv_cmake_path,
|
||||
"-DCMAKE_TOOLCHAIN_FILE=%s" % self.getCMakeToolchain(),
|
||||
self.srcdir
|
||||
] + [ "-D{}={}".format(key, value) for key, value in self.cmake_vars.items() ]
|
||||
log.info("Executing: %s" % cmd)
|
||||
retcode = subprocess.call(cmd)
|
||||
self.assertEqual(retcode, 0, "cmake failed")
|
||||
|
||||
cmd = ["ninja", "-v"]
|
||||
log.info("Executing: %s" % cmd)
|
||||
retcode = subprocess.call(cmd)
|
||||
self.assertEqual(retcode, 0, "make failed")
|
||||
|
||||
def suite(workdir, opencv_cmake_path):
|
||||
abis = {
|
||||
"armeabi-v7a": { "ANDROID_ABI": "armeabi-v7a", "ANDROID_TOOLCHAIN": "clang", "ANDROID_STL": "c++_shared", 'ANDROID_NATIVE_API_LEVEL': "21" },
|
||||
"arm64-v8a": { "ANDROID_ABI": "arm64-v8a", "ANDROID_TOOLCHAIN": "clang", "ANDROID_STL": "c++_shared", 'ANDROID_NATIVE_API_LEVEL': "21" },
|
||||
"x86": { "ANDROID_ABI": "x86", "ANDROID_TOOLCHAIN": "clang", "ANDROID_STL": "c++_shared", 'ANDROID_NATIVE_API_LEVEL': "21" },
|
||||
"x86_64": { "ANDROID_ABI": "x86_64", "ANDROID_TOOLCHAIN": "clang", "ANDROID_STL": "c++_shared", 'ANDROID_NATIVE_API_LEVEL': "21" },
|
||||
}
|
||||
|
||||
suite = unittest.TestSuite()
|
||||
for libset in ["", "opencv_java"]:
|
||||
for abi, cmake_vars in abis.items():
|
||||
suite.addTest(TestCmakeBuild(libset, abi, cmake_vars, opencv_cmake_path,
|
||||
os.path.join(workdir, "{}-{}".format(abi, "static" if libset == "" else "shared"))))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Test OpenCV for Android SDK with cmake')
|
||||
parser.add_argument('--sdk_path', help="Path to Android SDK to use for build")
|
||||
parser.add_argument('--ndk_path', help="Path to Android NDK to use for build")
|
||||
parser.add_argument("--workdir", default="testspace", help="Working directory (and output)")
|
||||
parser.add_argument("opencv_cmake_path", help="Path to folder with OpenCVConfig.cmake and android.toolchain.cmake (usually <SDK>/sdk/native/jni/")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.sdk_path is not None:
|
||||
os.environ["ANDROID_SDK"] = os.path.abspath(args.sdk_path)
|
||||
if args.ndk_path is not None:
|
||||
os.environ["ANDROID_NDK"] = os.path.abspath(args.ndk_path)
|
||||
|
||||
if not 'ANDROID_HOME' in os.environ and 'ANDROID_SDK' in os.environ:
|
||||
os.environ['ANDROID_HOME'] = os.environ["ANDROID_SDK"]
|
||||
|
||||
print("Using SDK: %s" % os.environ["ANDROID_SDK"])
|
||||
print("Using NDK: %s" % os.environ["ANDROID_NDK"])
|
||||
|
||||
workdir = os.path.abspath(args.workdir)
|
||||
if not os.path.exists(workdir):
|
||||
os.mkdir(workdir)
|
||||
res = unittest.TextTestRunner(verbosity=3).run(suite(workdir, os.path.abspath(args.opencv_cmake_path)))
|
||||
if not res.wasSuccessful():
|
||||
sys.exit(res)
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash -e
|
||||
SDK_DIR=$1
|
||||
|
||||
echo "OpenCV Android SDK path: ${SDK_DIR}"
|
||||
|
||||
ANDROID_HOME=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-${ANDROID_SDK?Required ANDROID_HOME/ANDROID_SDK/ANDROID_SDK_ROOT}}}
|
||||
ANDROID_NDK=${ANDROID_NDK_HOME-${ANDROID_NDK:-${NDKROOT?Required ANDROID_NDK_HOME/ANDROID_NDK/NDKROOT}}}
|
||||
OPENCV_GRADLE_VERBOSE_OPTIONS=${OPENCV_GRADLE_VERBOSE_OPTIONS:-'-i'}
|
||||
|
||||
echo "Android SDK: ${ANDROID_HOME}"
|
||||
echo "Android NDK: ${ANDROID_NDK}"
|
||||
|
||||
if [ ! -d "${ANDROID_HOME}" ]; then
|
||||
echo "FATAL: Missing Android SDK directory"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "${ANDROID_NDK}" ]; then
|
||||
echo "FATAL: Missing Android NDK directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export ANDROID_HOME=${ANDROID_HOME}
|
||||
export ANDROID_SDK=${ANDROID_HOME}
|
||||
export ANDROID_SDK_ROOT=${ANDROID_HOME}
|
||||
|
||||
export ANDROID_NDK=${ANDROID_NDK}
|
||||
export ANDROID_NDK_HOME=${ANDROID_NDK}
|
||||
|
||||
echo "Cloning OpenCV Android SDK ..."
|
||||
rm -rf "test-gradle"
|
||||
cp -rp "${SDK_DIR}" "test-gradle"
|
||||
echo "Cloning OpenCV Android SDK ... Done!"
|
||||
|
||||
# drop cmake bin name and "bin" folder from path
|
||||
echo "ndk.dir=${ANDROID_NDK}" > "test-gradle/samples/local.properties"
|
||||
echo "cmake.dir=$(dirname $(dirname $(which cmake)))" >> "test-gradle/samples/local.properties"
|
||||
|
||||
echo "Run gradle ..."
|
||||
(cd "test-gradle/samples"; ./gradlew ${OPENCV_GRADLE_VERBOSE_OPTIONS} assemble)
|
||||
|
||||
echo "#"
|
||||
echo "# Done!"
|
||||
echo "#"
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash -e
|
||||
SDK_DIR=$1
|
||||
LOCAL_MAVEN_REPO=$2
|
||||
echo "OpenCV Android SDK path: ${SDK_DIR}"
|
||||
echo "Use local maven repo from $LOCAL_MAVEN_REPO"
|
||||
|
||||
ANDROID_HOME=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-${ANDROID_SDK?Required ANDROID_HOME/ANDROID_SDK/ANDROID_SDK_ROOT}}}
|
||||
ANDROID_NDK=${ANDROID_NDK_HOME-${ANDROID_NDK:-${NDKROOT?Required ANDROID_NDK_HOME/ANDROID_NDK/NDKROOT}}}
|
||||
OPENCV_GRADLE_VERBOSE_OPTIONS=${OPENCV_GRADLE_VERBOSE_OPTIONS:-'-i'}
|
||||
|
||||
echo "Android SDK: ${ANDROID_HOME}"
|
||||
echo "Android NDK: ${ANDROID_NDK}"
|
||||
|
||||
if [ ! -d "${ANDROID_HOME}" ]; then
|
||||
echo "FATAL: Missing Android SDK directory"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "${ANDROID_NDK}" ]; then
|
||||
echo "FATAL: Missing Android NDK directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export ANDROID_HOME=${ANDROID_HOME}
|
||||
export ANDROID_SDK=${ANDROID_HOME}
|
||||
export ANDROID_SDK_ROOT=${ANDROID_HOME}
|
||||
|
||||
export ANDROID_NDK=${ANDROID_NDK}
|
||||
export ANDROID_NDK_HOME=${ANDROID_NDK}
|
||||
|
||||
echo "Cloning OpenCV Android SDK ..."
|
||||
rm -rf "test-gradle-aar"
|
||||
mkdir test-gradle-aar
|
||||
cp -rp ${SDK_DIR}/samples/* test-gradle-aar/
|
||||
echo "Cloning OpenCV Android SDK ... Done!"
|
||||
|
||||
# drop cmake bin name and "bin" folder from path
|
||||
echo "ndk.dir=${ANDROID_NDK}" > "test-gradle-aar/local.properties"
|
||||
echo "cmake.dir=$(dirname $(dirname $(which cmake)))" >> "test-gradle-aar/local.properties"
|
||||
|
||||
sed -i "s/opencv_source = 'sdk_path'/opencv_source = 'maven_local'/g" test-gradle-aar/settings.gradle
|
||||
sed -i "s+opencv_maven_path = '<path_to_maven_repo>'+opencv_maven_path = 'file\\://$LOCAL_MAVEN_REPO'+g" test-gradle-aar/settings.gradle
|
||||
|
||||
echo "Run gradle ..."
|
||||
(cd "test-gradle-aar"; ./gradlew ${OPENCV_GRADLE_VERBOSE_OPTIONS} assemble)
|
||||
|
||||
echo "#"
|
||||
echo "# Done!"
|
||||
echo "#"
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash -e
|
||||
SDK_DIR=$1
|
||||
|
||||
echo "OpenCV Android SDK path: ${SDK_DIR}"
|
||||
|
||||
ANDROID_HOME=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-${ANDROID_SDK?Required ANDROID_HOME/ANDROID_SDK/ANDROID_SDK_ROOT}}}
|
||||
ANDROID_NDK=${ANDROID_NDK_HOME-${ANDROID_NDK:-${NDKROOT?Required ANDROID_NDK_HOME/ANDROID_NDK/NDKROOT}}}
|
||||
OPENCV_GRADLE_VERBOSE_OPTIONS=${OPENCV_GRADLE_VERBOSE_OPTIONS:-'-i'}
|
||||
|
||||
echo "Android SDK: ${ANDROID_HOME}"
|
||||
echo "Android NDK: ${ANDROID_NDK}"
|
||||
|
||||
if [ ! -d "${ANDROID_HOME}" ]; then
|
||||
echo "FATAL: Missing Android SDK directory"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "${ANDROID_NDK}" ]; then
|
||||
echo "FATAL: Missing Android NDK directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export ANDROID_HOME=${ANDROID_HOME}
|
||||
export ANDROID_SDK=${ANDROID_HOME}
|
||||
export ANDROID_SDK_ROOT=${ANDROID_HOME}
|
||||
|
||||
export ANDROID_NDK=${ANDROID_NDK}
|
||||
export ANDROID_NDK_HOME=${ANDROID_NDK}
|
||||
|
||||
echo "Cloning OpenCV Android SDK ..."
|
||||
rm -rf "aar-build"
|
||||
cp -rp "${SDK_DIR}" "aar-build"
|
||||
echo "Cloning OpenCV Android SDK ... Done!"
|
||||
|
||||
# drop cmake bin name and "bin" folder from path
|
||||
echo "ndk.dir=${ANDROID_NDK}" > "aar-build/samples/local.properties"
|
||||
echo "cmake.dir=$(dirname $(dirname $(which cmake)))" >> "aar-build/samples/local.properties"
|
||||
|
||||
echo "Run gradle ..."
|
||||
(cd "aar-build/samples"; ./gradlew ${OPENCV_GRADLE_VERBOSE_OPTIONS} opencv:publishReleasePublicationToMyrepoRepository)
|
||||
|
||||
mkdir "maven_repo"
|
||||
cp -r aar-build/sdk/build/repo/* ./maven_repo/
|
||||
|
||||
echo "#"
|
||||
echo "# Done!"
|
||||
echo "#"
|
||||
Executable
+193
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
from os import path
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
|
||||
COPY_FROM_SDK_TO_ANDROID_PROJECT = [
|
||||
["sdk/native/jni/include", "OpenCV/src/main/cpp/include"],
|
||||
["sdk/java/src/org", "OpenCV/src/main/java/org"],
|
||||
["sdk/java/res", "OpenCV/src/main/res"]
|
||||
]
|
||||
|
||||
COPY_FROM_SDK_TO_APK = [
|
||||
["sdk/native/libs/<ABI>/lib<LIB_NAME>.so", "jni/<ABI>/lib<LIB_NAME>.so"],
|
||||
["sdk/native/libs/<ABI>/lib<LIB_NAME>.so", "prefab/modules/<LIB_NAME>/libs/android.<ABI>/lib<LIB_NAME>.so"],
|
||||
]
|
||||
|
||||
ANDROID_PROJECT_TEMPLATE_DIR = path.join(path.dirname(__file__), "aar-template")
|
||||
TEMP_DIR = "build_java_shared"
|
||||
ANDROID_PROJECT_DIR = path.join(TEMP_DIR, "AndroidProject")
|
||||
COMPILED_AAR_PATH_1 = path.join(ANDROID_PROJECT_DIR, "OpenCV/build/outputs/aar/OpenCV-release.aar") # original package name
|
||||
COMPILED_AAR_PATH_2 = path.join(ANDROID_PROJECT_DIR, "OpenCV/build/outputs/aar/opencv-release.aar") # lower case package name
|
||||
AAR_UNZIPPED_DIR = path.join(TEMP_DIR, "aar_unzipped")
|
||||
FINAL_AAR_PATH_TEMPLATE = "outputs/opencv_java_shared_<OPENCV_VERSION>.aar"
|
||||
FINAL_REPO_PATH = "outputs/maven_repo"
|
||||
MAVEN_PACKAGE_NAME = "opencv"
|
||||
|
||||
def fill_template(src_path, dst_path, args_dict):
|
||||
with open(src_path, "r") as f:
|
||||
template_text = f.read()
|
||||
template = string.Template(template_text)
|
||||
text = template.safe_substitute(args_dict)
|
||||
with open(dst_path, "w") as f:
|
||||
f.write(text)
|
||||
|
||||
def get_opencv_version(opencv_sdk_path):
|
||||
version_hpp_path = path.join(opencv_sdk_path, "sdk/native/jni/include/opencv2/core/version.hpp")
|
||||
with open(version_hpp_path, "rt") as f:
|
||||
data = f.read()
|
||||
major = re.search(r'^#define\W+CV_VERSION_MAJOR\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
minor = re.search(r'^#define\W+CV_VERSION_MINOR\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
revision = re.search(r'^#define\W+CV_VERSION_REVISION\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
return "%(major)s.%(minor)s.%(revision)s" % locals()
|
||||
|
||||
def get_ndk_version(ndk_path):
|
||||
props_path = path.join(ndk_path, "source.properties")
|
||||
with open(props_path, "rt") as f:
|
||||
data = f.read()
|
||||
version = re.search(r'Pkg\.Revision\W+=\W+(\d+\.\d+\.\d+)', data).group(1)
|
||||
return version.strip()
|
||||
|
||||
|
||||
def get_compiled_aar_path(path1, path2):
|
||||
if path.exists(path1):
|
||||
return path1
|
||||
elif path.exists(path2):
|
||||
return path2
|
||||
else:
|
||||
raise Exception("Can't find compiled AAR path in [" + path1 + ", " + path2 + "]")
|
||||
|
||||
def cleanup(paths_to_remove):
|
||||
exists = False
|
||||
for p in paths_to_remove:
|
||||
if path.exists(p):
|
||||
exists = True
|
||||
if path.isdir(p):
|
||||
shutil.rmtree(p)
|
||||
else:
|
||||
os.remove(p)
|
||||
print("Removed", p)
|
||||
if not exists:
|
||||
print("Nothing to remove")
|
||||
|
||||
def main(args):
|
||||
opencv_version = get_opencv_version(args.opencv_sdk_path)
|
||||
ndk_version = get_ndk_version(args.ndk_location)
|
||||
print("Detected ndk_version:", ndk_version)
|
||||
abis = os.listdir(path.join(args.opencv_sdk_path, "sdk/native/libs"))
|
||||
lib_name = "opencv_java" + opencv_version.split(".")[0]
|
||||
final_aar_path = FINAL_AAR_PATH_TEMPLATE.replace("<OPENCV_VERSION>", opencv_version)
|
||||
|
||||
print("Removing data from previous runs...")
|
||||
cleanup([TEMP_DIR, final_aar_path, path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME)])
|
||||
|
||||
print("Preparing Android project...")
|
||||
# ANDROID_PROJECT_TEMPLATE_DIR contains an Android project template that creates AAR
|
||||
shutil.copytree(ANDROID_PROJECT_TEMPLATE_DIR, ANDROID_PROJECT_DIR)
|
||||
|
||||
# Configuring the Android project to Java + shared C++ lib version
|
||||
shutil.rmtree(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/include"))
|
||||
|
||||
fill_template(path.join(ANDROID_PROJECT_DIR, "OpenCV/build.gradle.template"),
|
||||
path.join(ANDROID_PROJECT_DIR, "OpenCV/build.gradle"),
|
||||
{"LIB_NAME": lib_name,
|
||||
"LIB_TYPE": "c++_shared",
|
||||
"PACKAGE_NAME": MAVEN_PACKAGE_NAME,
|
||||
"OPENCV_VERSION": opencv_version,
|
||||
"NDK_VERSION": ndk_version,
|
||||
"COMPILE_SDK": args.android_compile_sdk,
|
||||
"MIN_SDK": args.android_min_sdk,
|
||||
"TARGET_SDK": args.android_target_sdk,
|
||||
"ABI_FILTERS": ", ".join(['"' + x + '"' for x in abis]),
|
||||
"JAVA_VERSION": args.java_version,
|
||||
})
|
||||
fill_template(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt.template"),
|
||||
path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt"),
|
||||
{"LIB_NAME": lib_name, "LIB_TYPE": "SHARED"})
|
||||
|
||||
local_props = ""
|
||||
if args.ndk_location:
|
||||
local_props += "ndk.dir=" + args.ndk_location + "\n"
|
||||
if args.cmake_location:
|
||||
local_props += "cmake.dir=" + args.cmake_location + "\n"
|
||||
|
||||
if local_props:
|
||||
with open(path.join(ANDROID_PROJECT_DIR, "local.properties"), "wt") as f:
|
||||
f.write(local_props)
|
||||
|
||||
# Copying Java code and C++ public headers from SDK to the Android project
|
||||
for src, dst in COPY_FROM_SDK_TO_ANDROID_PROJECT:
|
||||
shutil.copytree(path.join(args.opencv_sdk_path, src),
|
||||
path.join(ANDROID_PROJECT_DIR, dst))
|
||||
|
||||
print("Running gradle assembleRelease...")
|
||||
# Running gradle to build the Android project
|
||||
cmd = ["./gradlew", "assembleRelease"]
|
||||
if args.offline:
|
||||
cmd = cmd + ["--offline"]
|
||||
subprocess.run(cmd, shell=False, cwd=ANDROID_PROJECT_DIR, check=True)
|
||||
|
||||
print("Adding libs to AAR...")
|
||||
# The created AAR package doesn't contain C++ shared libs.
|
||||
# We need to add them manually.
|
||||
# AAR package is just a zip archive.
|
||||
complied_aar_path = get_compiled_aar_path(COMPILED_AAR_PATH_1, COMPILED_AAR_PATH_2) # two possible paths
|
||||
shutil.unpack_archive(complied_aar_path, AAR_UNZIPPED_DIR, "zip")
|
||||
|
||||
for abi in abis:
|
||||
for src, dst in COPY_FROM_SDK_TO_APK:
|
||||
src = src.replace("<ABI>", abi).replace("<LIB_NAME>", lib_name)
|
||||
dst = dst.replace("<ABI>", abi).replace("<LIB_NAME>", lib_name)
|
||||
shutil.copy(path.join(args.opencv_sdk_path, src),
|
||||
path.join(AAR_UNZIPPED_DIR, dst))
|
||||
|
||||
# Creating final AAR zip archive
|
||||
os.makedirs("outputs", exist_ok=True)
|
||||
shutil.make_archive(final_aar_path, "zip", AAR_UNZIPPED_DIR, ".")
|
||||
os.rename(final_aar_path + ".zip", final_aar_path)
|
||||
|
||||
print("Creating local maven repo...")
|
||||
|
||||
shutil.copy(final_aar_path, path.join(ANDROID_PROJECT_DIR, "OpenCV/opencv-release.aar"))
|
||||
|
||||
print("Creating a maven repo from project sources (with sources jar and javadoc jar)...")
|
||||
cmd = ["./gradlew", "publishReleasePublicationToMyrepoRepository"]
|
||||
if args.offline:
|
||||
cmd = cmd + ["--offline"]
|
||||
subprocess.run(cmd, shell=False, cwd=ANDROID_PROJECT_DIR, check=True)
|
||||
|
||||
os.makedirs(path.join(FINAL_REPO_PATH, "org/opencv"), exist_ok=True)
|
||||
shutil.move(path.join(ANDROID_PROJECT_DIR, "OpenCV/build/repo/org/opencv", MAVEN_PACKAGE_NAME),
|
||||
path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME))
|
||||
|
||||
print("Creating a maven repo from modified AAR (with cpp libraries)...")
|
||||
cmd = ["./gradlew", "publishModifiedPublicationToMyrepoRepository"]
|
||||
if args.offline:
|
||||
cmd = cmd + ["--offline"]
|
||||
subprocess.run(cmd, shell=False, cwd=ANDROID_PROJECT_DIR, check=True)
|
||||
|
||||
# Replacing AAR from the first maven repo with modified AAR from the second maven repo
|
||||
shutil.copytree(path.join(ANDROID_PROJECT_DIR, "OpenCV/build/repo/org/opencv", MAVEN_PACKAGE_NAME),
|
||||
path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME),
|
||||
dirs_exist_ok=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Builds AAR with Java and shared C++ libs from OpenCV SDK")
|
||||
parser.add_argument('opencv_sdk_path')
|
||||
parser.add_argument('--android_compile_sdk', default="34")
|
||||
parser.add_argument('--android_min_sdk', default="21")
|
||||
parser.add_argument('--android_target_sdk', default="34")
|
||||
parser.add_argument('--java_version', default="17")
|
||||
parser.add_argument('--ndk_location', default="")
|
||||
parser.add_argument('--cmake_location', default="")
|
||||
parser.add_argument('--offline', action="store_true", help="Force Gradle use offline mode")
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
Executable
+547
@@ -0,0 +1,547 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os, sys
|
||||
import argparse
|
||||
import glob
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import logging as log
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
class Fail(Exception):
|
||||
def __init__(self, text=None):
|
||||
self.t = text
|
||||
def __str__(self):
|
||||
return "ERROR" if self.t is None else self.t
|
||||
|
||||
def execute(cmd, shell=False):
|
||||
try:
|
||||
log.debug("Executing: %s" % cmd)
|
||||
log.info('Executing: ' + ' '.join(cmd))
|
||||
retcode = subprocess.call(cmd, shell=shell)
|
||||
if retcode < 0:
|
||||
raise Fail("Child was terminated by signal: %s" % -retcode)
|
||||
elif retcode > 0:
|
||||
raise Fail("Child returned: %s" % retcode)
|
||||
except OSError as e:
|
||||
raise Fail("Execution failed: %d / %s" % (e.errno, e.strerror))
|
||||
|
||||
def rm_one(d):
|
||||
d = os.path.abspath(d)
|
||||
if os.path.exists(d):
|
||||
if os.path.isdir(d):
|
||||
log.info("Removing dir: %s", d)
|
||||
shutil.rmtree(d)
|
||||
elif os.path.isfile(d):
|
||||
log.info("Removing file: %s", d)
|
||||
os.remove(d)
|
||||
|
||||
def check_dir(d, create=False, clean=False):
|
||||
d = os.path.abspath(d)
|
||||
log.info("Check dir %s (create: %s, clean: %s)", d, create, clean)
|
||||
if os.path.exists(d):
|
||||
if not os.path.isdir(d):
|
||||
raise Fail("Not a directory: %s" % d)
|
||||
if clean:
|
||||
for x in glob.glob(os.path.join(d, "*")):
|
||||
rm_one(x)
|
||||
else:
|
||||
if create:
|
||||
os.makedirs(d)
|
||||
return d
|
||||
|
||||
def check_executable(cmd):
|
||||
try:
|
||||
log.debug("Executing: %s" % cmd)
|
||||
result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
|
||||
if not isinstance(result, str):
|
||||
result = result.decode("utf-8")
|
||||
log.debug("Result: %s" % (result+'\n').split('\n')[0])
|
||||
return True
|
||||
except Exception as e:
|
||||
log.debug('Failed: %s' % e)
|
||||
return False
|
||||
|
||||
def determine_opencv_version(version_hpp_path):
|
||||
# version in 2.4 - CV_VERSION_EPOCH.CV_VERSION_MAJOR.CV_VERSION_MINOR.CV_VERSION_REVISION
|
||||
# version in master - CV_VERSION_MAJOR.CV_VERSION_MINOR.CV_VERSION_REVISION-CV_VERSION_STATUS
|
||||
with open(version_hpp_path, "rt") as f:
|
||||
data = f.read()
|
||||
major = re.search(r'^#define\W+CV_VERSION_MAJOR\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
minor = re.search(r'^#define\W+CV_VERSION_MINOR\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
revision = re.search(r'^#define\W+CV_VERSION_REVISION\W+(\d+)$', data, re.MULTILINE).group(1)
|
||||
version_status = re.search(r'^#define\W+CV_VERSION_STATUS\W+"([^"]*)"$', data, re.MULTILINE).group(1)
|
||||
return "%(major)s.%(minor)s.%(revision)s%(version_status)s" % locals()
|
||||
|
||||
# shutil.move fails if dst exists
|
||||
def move_smart(src, dst):
|
||||
def move_recurse(subdir):
|
||||
s = os.path.join(src, subdir)
|
||||
d = os.path.join(dst, subdir)
|
||||
if os.path.exists(d):
|
||||
if os.path.isdir(d):
|
||||
for item in os.listdir(s):
|
||||
move_recurse(os.path.join(subdir, item))
|
||||
elif os.path.isfile(s):
|
||||
shutil.move(s, d)
|
||||
else:
|
||||
shutil.move(s, d)
|
||||
move_recurse('')
|
||||
|
||||
# shutil.copytree fails if dst exists
|
||||
def copytree_smart(src, dst):
|
||||
def copy_recurse(subdir):
|
||||
s = os.path.join(src, subdir)
|
||||
d = os.path.join(dst, subdir)
|
||||
if os.path.exists(d):
|
||||
if os.path.isdir(d):
|
||||
for item in os.listdir(s):
|
||||
copy_recurse(os.path.join(subdir, item))
|
||||
elif os.path.isfile(s):
|
||||
shutil.copy2(s, d)
|
||||
else:
|
||||
if os.path.isdir(s):
|
||||
shutil.copytree(s, d)
|
||||
elif os.path.isfile(s):
|
||||
shutil.copy2(s, d)
|
||||
copy_recurse('')
|
||||
|
||||
def get_highest_version(subdirs):
|
||||
return max(subdirs, key=lambda dir: [int(comp) for comp in os.path.split(dir)[-1].split('.')])
|
||||
|
||||
|
||||
#===================================================================================================
|
||||
|
||||
class ABI:
|
||||
def __init__(self, platform_id, name, toolchain, ndk_api_level = None, cmake_vars = dict()):
|
||||
self.platform_id = platform_id # platform code to add to apk version (for cmake)
|
||||
self.name = name # general name (official Android ABI identifier)
|
||||
self.toolchain = toolchain # toolchain identifier (for cmake)
|
||||
self.cmake_vars = dict(
|
||||
ANDROID_STL="gnustl_static",
|
||||
ANDROID_ABI=self.name,
|
||||
ANDROID_PLATFORM_ID=platform_id,
|
||||
)
|
||||
if toolchain is not None:
|
||||
self.cmake_vars['ANDROID_TOOLCHAIN_NAME'] = toolchain
|
||||
else:
|
||||
self.cmake_vars['ANDROID_TOOLCHAIN'] = 'clang'
|
||||
self.cmake_vars['ANDROID_STL'] = 'c++_shared'
|
||||
if ndk_api_level:
|
||||
self.cmake_vars['ANDROID_NATIVE_API_LEVEL'] = ndk_api_level
|
||||
self.cmake_vars.update(cmake_vars)
|
||||
def __str__(self):
|
||||
return "%s (%s)" % (self.name, self.toolchain)
|
||||
def haveIPP(self):
|
||||
return self.name == "x86" or self.name == "x86_64"
|
||||
def haveKleidiCV(self):
|
||||
return self.name == "arm64-v8a"
|
||||
|
||||
#===================================================================================================
|
||||
|
||||
class Builder:
|
||||
def __init__(self, workdir, opencvdir, config):
|
||||
self.workdir = check_dir(workdir, create=True)
|
||||
self.opencvdir = check_dir(opencvdir)
|
||||
self.config = config
|
||||
self.libdest = check_dir(os.path.join(self.workdir, "o4a"), create=True, clean=True)
|
||||
self.resultdest = check_dir(os.path.join(self.workdir, 'OpenCV-android-sdk'), create=True, clean=True)
|
||||
self.docdest = check_dir(os.path.join(self.workdir, 'OpenCV-android-sdk', 'sdk', 'java', 'javadoc'), create=True, clean=True)
|
||||
self.extra_packs = []
|
||||
self.opencv_version = determine_opencv_version(os.path.join(self.opencvdir, "modules", "core", "include", "opencv2", "core", "version.hpp"))
|
||||
self.use_ccache = False if config.no_ccache else True
|
||||
self.cmake_path = self.get_cmake()
|
||||
self.ninja_path = self.get_ninja()
|
||||
self.debug = True if config.debug else False
|
||||
self.debug_info = True if config.debug_info else False
|
||||
self.no_samples_build = True if config.no_samples_build else False
|
||||
self.hwasan = True if config.hwasan else False
|
||||
self.opencl = True if config.opencl else False
|
||||
self.no_kotlin = True if config.no_kotlin else False
|
||||
self.shared = True if config.shared else False
|
||||
self.disable = args.disable
|
||||
|
||||
def get_cmake(self):
|
||||
if not self.config.use_android_buildtools and check_executable(['cmake', '--version']):
|
||||
log.info("Using cmake from PATH")
|
||||
return 'cmake'
|
||||
# look to see if Android SDK's cmake is installed
|
||||
android_cmake = os.path.join(os.environ['ANDROID_SDK'], 'cmake')
|
||||
if os.path.exists(android_cmake):
|
||||
cmake_subdirs = [f for f in os.listdir(android_cmake) if check_executable([os.path.join(android_cmake, f, 'bin', 'cmake'), '--version'])]
|
||||
if len(cmake_subdirs) > 0:
|
||||
# there could be more than one - get the most recent
|
||||
cmake_from_sdk = os.path.join(android_cmake, get_highest_version(cmake_subdirs), 'bin', 'cmake')
|
||||
log.info("Using cmake from Android SDK: %s", cmake_from_sdk)
|
||||
return cmake_from_sdk
|
||||
raise Fail("Can't find cmake")
|
||||
|
||||
def get_ninja(self):
|
||||
if not self.config.use_android_buildtools and check_executable(['ninja', '--version']):
|
||||
log.info("Using ninja from PATH")
|
||||
return 'ninja'
|
||||
# Android SDK's cmake includes a copy of ninja - look to see if its there
|
||||
android_cmake = os.path.join(os.environ['ANDROID_SDK'], 'cmake')
|
||||
if os.path.exists(android_cmake):
|
||||
cmake_subdirs = [f for f in os.listdir(android_cmake) if check_executable([os.path.join(android_cmake, f, 'bin', 'ninja'), '--version'])]
|
||||
if len(cmake_subdirs) > 0:
|
||||
# there could be more than one - just take the first one
|
||||
ninja_from_sdk = os.path.join(android_cmake, cmake_subdirs[0], 'bin', 'ninja')
|
||||
log.info("Using ninja from Android SDK: %s", ninja_from_sdk)
|
||||
return ninja_from_sdk
|
||||
raise Fail("Can't find ninja")
|
||||
|
||||
def get_toolchain_file(self):
|
||||
if not self.config.force_opencv_toolchain:
|
||||
toolchain = os.path.join(os.environ['ANDROID_NDK'], 'build', 'cmake', 'android.toolchain.cmake')
|
||||
if os.path.exists(toolchain):
|
||||
return toolchain
|
||||
toolchain = os.path.join(SCRIPT_DIR, "android.toolchain.cmake")
|
||||
if os.path.exists(toolchain):
|
||||
return toolchain
|
||||
else:
|
||||
raise Fail("Can't find toolchain")
|
||||
|
||||
def get_engine_apk_dest(self, engdest):
|
||||
return os.path.join(engdest, "platforms", "android", "service", "engine", ".build")
|
||||
|
||||
def add_extra_pack(self, ver, path):
|
||||
if path is None:
|
||||
return
|
||||
self.extra_packs.append((ver, check_dir(path)))
|
||||
|
||||
def clean_library_build_dir(self):
|
||||
for d in ["CMakeCache.txt", "CMakeFiles/", "bin/", "libs/", "lib/", "package/", "install/samples/"]:
|
||||
rm_one(d)
|
||||
|
||||
def build_library(self, abi, do_install, no_media_ndk):
|
||||
cmd = [self.cmake_path, "-GNinja"]
|
||||
cmake_vars = dict(
|
||||
CMAKE_TOOLCHAIN_FILE=self.get_toolchain_file(),
|
||||
INSTALL_CREATE_DISTRIB="ON",
|
||||
WITH_OPENCL="OFF",
|
||||
BUILD_KOTLIN_EXTENSIONS="ON",
|
||||
WITH_IPP=("ON" if abi.haveIPP() else "OFF"),
|
||||
WITH_TBB="ON",
|
||||
BUILD_EXAMPLES="OFF",
|
||||
BUILD_TESTS="OFF",
|
||||
BUILD_PERF_TESTS="OFF",
|
||||
BUILD_DOCS="OFF",
|
||||
BUILD_ANDROID_EXAMPLES=("OFF" if self.no_samples_build else "ON"),
|
||||
INSTALL_ANDROID_EXAMPLES=("OFF" if self.no_samples_build else "ON"),
|
||||
)
|
||||
if self.ninja_path != 'ninja':
|
||||
cmake_vars['CMAKE_MAKE_PROGRAM'] = self.ninja_path
|
||||
|
||||
if self.debug:
|
||||
cmake_vars['CMAKE_BUILD_TYPE'] = "Debug"
|
||||
|
||||
if self.debug_info: # Release with debug info
|
||||
cmake_vars['BUILD_WITH_DEBUG_INFO'] = "ON"
|
||||
|
||||
if self.opencl:
|
||||
cmake_vars['WITH_OPENCL'] = "ON"
|
||||
|
||||
if self.no_kotlin:
|
||||
cmake_vars['BUILD_KOTLIN_EXTENSIONS'] = "OFF"
|
||||
|
||||
if self.shared:
|
||||
cmake_vars['BUILD_SHARED_LIBS'] = "ON"
|
||||
|
||||
if self.config.modules_list is not None:
|
||||
cmake_vars['BUILD_LIST'] = '%s' % self.config.modules_list
|
||||
|
||||
if self.config.extra_modules_path is not None:
|
||||
cmake_vars['OPENCV_EXTRA_MODULES_PATH'] = '%s' % self.config.extra_modules_path
|
||||
|
||||
if self.use_ccache == True:
|
||||
cmake_vars['NDK_CCACHE'] = 'ccache'
|
||||
if do_install:
|
||||
cmake_vars['BUILD_TESTS'] = "ON"
|
||||
cmake_vars['INSTALL_TESTS'] = "ON"
|
||||
|
||||
if no_media_ndk:
|
||||
cmake_vars['WITH_ANDROID_MEDIANDK'] = "OFF"
|
||||
|
||||
if self.hwasan and "arm64" in abi.name:
|
||||
cmake_vars['OPENCV_ENABLE_MEMORY_SANITIZER'] = "ON"
|
||||
hwasan_flags = "-fno-omit-frame-pointer -fsanitize=hwaddress"
|
||||
for s in ['OPENCV_EXTRA_C_FLAGS', 'OPENCV_EXTRA_CXX_FLAGS', 'OPENCV_EXTRA_EXE_LINKER_FLAGS',
|
||||
'OPENCV_EXTRA_SHARED_LINKER_FLAGS', 'OPENCV_EXTRA_MODULE_LINKER_FLAGS']:
|
||||
if s in cmake_vars.keys():
|
||||
cmake_vars[s] = cmake_vars[s] + ' ' + hwasan_flags
|
||||
else:
|
||||
cmake_vars[s] = hwasan_flags
|
||||
|
||||
cmake_vars.update(abi.cmake_vars)
|
||||
|
||||
if len(self.disable) > 0:
|
||||
cmake_vars.update({'WITH_%s' % f : "OFF" for f in self.disable})
|
||||
|
||||
cmd += [ "-D%s='%s'" % (k, v) for (k, v) in cmake_vars.items() if v is not None]
|
||||
cmd.append(self.opencvdir)
|
||||
execute(cmd)
|
||||
# full parallelism for C++ compilation tasks
|
||||
build_targets = ["opencv_modules"]
|
||||
if do_install:
|
||||
build_targets.append("opencv_tests")
|
||||
execute([self.ninja_path, *build_targets])
|
||||
# limit parallelism for building samples (avoid huge memory consumption)
|
||||
if self.no_samples_build:
|
||||
execute([self.ninja_path, "install" if (self.debug_info or self.debug) else "install/strip"])
|
||||
else:
|
||||
execute([self.ninja_path, "-j1", "install" if (self.debug_info or self.debug) else "install/strip"])
|
||||
|
||||
def build_javadoc(self):
|
||||
classpaths = []
|
||||
for dir, _, files in os.walk(os.environ["ANDROID_SDK"]):
|
||||
for f in files:
|
||||
if f == "android.jar" or f == "annotations.jar":
|
||||
classpaths.append(os.path.join(dir, f))
|
||||
srcdir = os.path.join(self.resultdest, 'sdk', 'java', 'src')
|
||||
dstdir = self.docdest
|
||||
# HACK: create stubs for auto-generated files to satisfy imports
|
||||
with open(os.path.join(srcdir, 'org', 'opencv', 'BuildConfig.java'), 'wt') as fs:
|
||||
fs.write("package org.opencv;\n public class BuildConfig {\n}")
|
||||
fs.close()
|
||||
with open(os.path.join(srcdir, 'org', 'opencv', 'R.java'), 'wt') as fs:
|
||||
fs.write("package org.opencv;\n public class R {\n}")
|
||||
fs.close()
|
||||
|
||||
# synchronize with modules/java/jar/build.xml.in
|
||||
shutil.copy2(os.path.join(SCRIPT_DIR, '../../doc/mymath.js'), dstdir)
|
||||
cmd = [
|
||||
"javadoc",
|
||||
'-windowtitle', 'OpenCV %s Java documentation' % self.opencv_version,
|
||||
'-doctitle', 'OpenCV Java documentation (%s)' % self.opencv_version,
|
||||
"-nodeprecated",
|
||||
"-public",
|
||||
'-sourcepath', srcdir,
|
||||
'-encoding', 'UTF-8',
|
||||
'-charset', 'UTF-8',
|
||||
'-docencoding', 'UTF-8',
|
||||
'--allow-script-in-comments',
|
||||
'-header',
|
||||
'''
|
||||
<script>
|
||||
var url = window.location.href;
|
||||
var pos = url.lastIndexOf('/javadoc/');
|
||||
url = pos >= 0 ? (url.substring(0, pos) + '/javadoc/mymath.js') : (window.location.origin + '/mymath.js');
|
||||
var script = document.createElement('script');
|
||||
script.src = '%s/MathJax.js?config=TeX-AMS-MML_HTMLorMML,' + url;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
</script>
|
||||
''' % 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0',
|
||||
'-bottom', 'Generated on %s / OpenCV %s' % (time.strftime("%Y-%m-%d %H:%M:%S"), self.opencv_version),
|
||||
"-d", dstdir,
|
||||
"-classpath", ":".join(classpaths),
|
||||
'-subpackages', 'org.opencv'
|
||||
]
|
||||
execute(cmd)
|
||||
# HACK: remove temporary files needed to satisfy javadoc imports
|
||||
os.remove(os.path.join(srcdir, 'org', 'opencv', 'BuildConfig.java'))
|
||||
os.remove(os.path.join(srcdir, 'org', 'opencv', 'R.java'))
|
||||
|
||||
def gather_results(self):
|
||||
# Copy all files
|
||||
root = os.path.join(self.libdest, "install")
|
||||
for item in os.listdir(root):
|
||||
src = os.path.join(root, item)
|
||||
dst = os.path.join(self.resultdest, item)
|
||||
if os.path.isdir(src):
|
||||
log.info("Copy dir: %s", item)
|
||||
if self.config.force_copy:
|
||||
copytree_smart(src, dst)
|
||||
else:
|
||||
move_smart(src, dst)
|
||||
elif os.path.isfile(src):
|
||||
log.info("Copy file: %s", item)
|
||||
if self.config.force_copy:
|
||||
shutil.copy2(src, dst)
|
||||
else:
|
||||
shutil.move(src, dst)
|
||||
|
||||
def get_ndk_dir():
|
||||
# look to see if Android NDK is installed
|
||||
android_sdk_ndk = os.path.join(os.environ["ANDROID_SDK"], 'ndk')
|
||||
android_sdk_ndk_bundle = os.path.join(os.environ["ANDROID_SDK"], 'ndk-bundle')
|
||||
if os.path.exists(android_sdk_ndk):
|
||||
ndk_subdirs = [f for f in os.listdir(android_sdk_ndk) if os.path.exists(os.path.join(android_sdk_ndk, f, 'package.xml'))]
|
||||
if len(ndk_subdirs) > 0:
|
||||
# there could be more than one - get the most recent
|
||||
ndk_from_sdk = os.path.join(android_sdk_ndk, get_highest_version(ndk_subdirs))
|
||||
log.info("Using NDK (side-by-side) from Android SDK: %s", ndk_from_sdk)
|
||||
return ndk_from_sdk
|
||||
if os.path.exists(os.path.join(android_sdk_ndk_bundle, 'package.xml')):
|
||||
log.info("Using NDK bundle from Android SDK: %s", android_sdk_ndk_bundle)
|
||||
return android_sdk_ndk_bundle
|
||||
return None
|
||||
|
||||
def check_cmake_flag_enabled(cmake_file, flag_name, strict=True):
|
||||
print(f"Checking build flag '{flag_name}' in: {cmake_file}")
|
||||
|
||||
if not os.path.isfile(cmake_file):
|
||||
msg = f"ERROR: File {cmake_file} does not exist."
|
||||
if strict:
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("WARNING:", msg)
|
||||
return
|
||||
|
||||
with open(cmake_file, 'r') as file:
|
||||
for line in file:
|
||||
if line.strip().startswith(f"{flag_name}="):
|
||||
value = line.strip().split('=')[1]
|
||||
if value == '1' or value == 'ON':
|
||||
print(f"{flag_name}=1 found. Support is enabled.")
|
||||
return
|
||||
else:
|
||||
msg = f"ERROR: {flag_name} is set to {value}, expected 1."
|
||||
if strict:
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("WARNING:", msg)
|
||||
return
|
||||
msg = f"ERROR: {flag_name} not found in {os.path.basename(cmake_file)}."
|
||||
if strict:
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("WARNING:", msg)
|
||||
|
||||
#===================================================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Build OpenCV for Android SDK')
|
||||
parser.add_argument("work_dir", nargs='?', default='.', help="Working directory (and output)")
|
||||
parser.add_argument("opencv_dir", nargs='?', default=os.path.join(SCRIPT_DIR, '../..'), help="Path to OpenCV source dir")
|
||||
parser.add_argument('--config', default='ndk-18-api-level-21.config.py', type=str, help="Package build configuration", )
|
||||
parser.add_argument('--ndk_path', help="Path to Android NDK to use for build")
|
||||
parser.add_argument('--sdk_path', help="Path to Android SDK to use for build")
|
||||
parser.add_argument('--use_android_buildtools', action="store_true", help='Use cmake/ninja build tools from Android SDK')
|
||||
parser.add_argument("--modules_list", help="List of modules to include for build")
|
||||
parser.add_argument("--extra_modules_path", help="Path to extra modules to use for build")
|
||||
parser.add_argument('--sign_with', help="Certificate to sign the Manager apk")
|
||||
parser.add_argument('--build_doc', action="store_true", help="Build javadoc")
|
||||
parser.add_argument('--no_ccache', action="store_true", help="Do not use ccache during library build")
|
||||
parser.add_argument('--force_copy', action="store_true", help="Do not use file move during library build (useful for debug)")
|
||||
parser.add_argument('--force_opencv_toolchain', action="store_true", help="Do not use toolchain from Android NDK")
|
||||
parser.add_argument('--debug', action="store_true", help="Build 'Debug' binaries (CMAKE_BUILD_TYPE=Debug)")
|
||||
parser.add_argument('--debug_info', action="store_true", help="Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)")
|
||||
parser.add_argument('--no_samples_build', action="store_true", help="Do not build samples (speeds up build)")
|
||||
parser.add_argument('--opencl', action="store_true", help="Enable OpenCL support")
|
||||
parser.add_argument('--no_kotlin', action="store_true", help="Disable Kotlin extensions")
|
||||
parser.add_argument('--shared', action="store_true", help="Build shared libraries")
|
||||
parser.add_argument('--no_media_ndk', action="store_true", help="Do not link Media NDK (required for video I/O support)")
|
||||
parser.add_argument('--hwasan', action="store_true", help="Enable Hardware Address Sanitizer on ARM64")
|
||||
parser.add_argument('--disable', metavar='FEATURE', default=[], action='append', help='OpenCV features to disable (add WITH_*=OFF). To disable multiple, specify this flag again, e.g. "--disable TBB --disable OPENMP"')
|
||||
parser.add_argument('--no-strict-dependencies',action='store_false',dest='strict_dependencies',help='Disable strict dependency checking (default: strict mode ON)')
|
||||
args = parser.parse_args()
|
||||
|
||||
log.basicConfig(format='%(message)s', level=log.DEBUG)
|
||||
log.debug("Args: %s", args)
|
||||
|
||||
if args.ndk_path is not None:
|
||||
os.environ["ANDROID_NDK"] = args.ndk_path
|
||||
if args.sdk_path is not None:
|
||||
os.environ["ANDROID_SDK"] = args.sdk_path
|
||||
|
||||
if not 'ANDROID_HOME' in os.environ and 'ANDROID_SDK' in os.environ:
|
||||
os.environ['ANDROID_HOME'] = os.environ["ANDROID_SDK"]
|
||||
|
||||
if not 'ANDROID_SDK' in os.environ:
|
||||
raise Fail("SDK location not set. Either pass --sdk_path or set ANDROID_SDK environment variable")
|
||||
|
||||
# look for an NDK installed with the Android SDK
|
||||
if not 'ANDROID_NDK' in os.environ and 'ANDROID_SDK' in os.environ:
|
||||
sdk_ndk_dir = get_ndk_dir()
|
||||
if sdk_ndk_dir:
|
||||
os.environ['ANDROID_NDK'] = sdk_ndk_dir
|
||||
|
||||
if not 'ANDROID_NDK' in os.environ:
|
||||
raise Fail("NDK location not set. Either pass --ndk_path or set ANDROID_NDK environment variable")
|
||||
|
||||
show_samples_build_warning = False
|
||||
#also set ANDROID_NDK_HOME (needed by the gradle build)
|
||||
if not 'ANDROID_NDK_HOME' in os.environ and 'ANDROID_NDK' in os.environ:
|
||||
os.environ['ANDROID_NDK_HOME'] = os.environ["ANDROID_NDK"]
|
||||
show_samples_build_warning = True
|
||||
|
||||
if not check_executable(['ccache', '--version']):
|
||||
log.info("ccache not found - disabling ccache support")
|
||||
args.no_ccache = True
|
||||
|
||||
if os.path.realpath(args.work_dir) == os.path.realpath(SCRIPT_DIR):
|
||||
raise Fail("Specify workdir (building from script directory is not supported)")
|
||||
if os.path.realpath(args.work_dir) == os.path.realpath(args.opencv_dir):
|
||||
raise Fail("Specify workdir (building from OpenCV source directory is not supported)")
|
||||
|
||||
# Relative paths become invalid in sub-directories
|
||||
if args.opencv_dir is not None and not os.path.isabs(args.opencv_dir):
|
||||
args.opencv_dir = os.path.abspath(args.opencv_dir)
|
||||
if args.extra_modules_path is not None and not os.path.isabs(args.extra_modules_path):
|
||||
args.extra_modules_path = os.path.abspath(args.extra_modules_path)
|
||||
|
||||
cpath = args.config
|
||||
if not os.path.exists(cpath):
|
||||
cpath = os.path.join(SCRIPT_DIR, cpath)
|
||||
if not os.path.exists(cpath):
|
||||
raise Fail('Config "%s" is missing' % args.config)
|
||||
with open(cpath, 'r') as f:
|
||||
cfg = f.read()
|
||||
print("Package configuration:")
|
||||
print('=' * 80)
|
||||
print(cfg.strip())
|
||||
print('=' * 80)
|
||||
|
||||
ABIs = None # make flake8 happy
|
||||
exec(compile(cfg, cpath, 'exec'))
|
||||
|
||||
log.info("Android NDK path: %s", os.environ["ANDROID_NDK"])
|
||||
log.info("Android SDK path: %s", os.environ["ANDROID_SDK"])
|
||||
|
||||
builder = Builder(args.work_dir, args.opencv_dir, args)
|
||||
|
||||
log.info("Detected OpenCV version: %s", builder.opencv_version)
|
||||
|
||||
for i, abi in enumerate(ABIs):
|
||||
do_install = (i == 0)
|
||||
|
||||
log.info("=====")
|
||||
log.info("===== Building library for %s", abi)
|
||||
log.info("=====")
|
||||
|
||||
os.chdir(builder.libdest)
|
||||
builder.clean_library_build_dir()
|
||||
builder.build_library(abi, do_install, args.no_media_ndk)
|
||||
|
||||
#Check HAVE_IPP x86 / x86_64
|
||||
if abi.haveIPP():
|
||||
log.info("Checking HAVE_IPP for ABI: %s", abi.name)
|
||||
check_cmake_flag_enabled(os.path.join(builder.libdest,"CMakeVars.txt"), "HAVE_IPP", strict=args.strict_dependencies)
|
||||
|
||||
#Check HAVE_KLEIDICV for armv8
|
||||
if abi.haveKleidiCV():
|
||||
log.info("Checking HAVE_KLEIDICV for ABI: %s", abi.name)
|
||||
check_cmake_flag_enabled(os.path.join(builder.libdest,"CMakeVars.txt"), "HAVE_KLEIDICV", strict=args.strict_dependencies)
|
||||
|
||||
builder.gather_results()
|
||||
|
||||
if args.build_doc:
|
||||
builder.build_javadoc()
|
||||
|
||||
log.info("=====")
|
||||
log.info("===== Build finished")
|
||||
log.info("=====")
|
||||
if show_samples_build_warning:
|
||||
#give a hint how to solve "Gradle sync failed: NDK not configured."
|
||||
log.info("ANDROID_NDK_HOME environment variable required by the samples project is not set")
|
||||
log.info("SDK location: %s", builder.resultdest)
|
||||
log.info("Documentation location: %s", builder.docdest)
|
||||
Executable
+260
@@ -0,0 +1,260 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from os import path
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from build_java_shared_aar import cleanup, fill_template, get_compiled_aar_path, get_opencv_version, get_ndk_version
|
||||
|
||||
|
||||
ANDROID_PROJECT_TEMPLATE_DIR = path.join(path.dirname(__file__), "aar-template")
|
||||
TEMP_DIR = "build_static"
|
||||
ANDROID_PROJECT_DIR = path.join(TEMP_DIR, "AndroidProject")
|
||||
COMPILED_AAR_PATH_1 = path.join(ANDROID_PROJECT_DIR, "OpenCV/build/outputs/aar/OpenCV-release.aar") # original package name
|
||||
COMPILED_AAR_PATH_2 = path.join(ANDROID_PROJECT_DIR, "OpenCV/build/outputs/aar/opencv-release.aar") # lower case package name
|
||||
AAR_UNZIPPED_DIR = path.join(TEMP_DIR, "aar_unzipped")
|
||||
FINAL_AAR_PATH_TEMPLATE = "outputs/opencv_static_<OPENCV_VERSION>.aar"
|
||||
FINAL_REPO_PATH = "outputs/maven_repo"
|
||||
MAVEN_PACKAGE_NAME = "opencv-static"
|
||||
|
||||
|
||||
def get_list_of_opencv_libs(sdk_dir):
|
||||
files = os.listdir(path.join(sdk_dir, "sdk/native/staticlibs/arm64-v8a"))
|
||||
libs = [f[3:-2] for f in files if f[:3] == "lib" and f[-2:] == ".a"]
|
||||
return libs
|
||||
|
||||
def get_list_of_3rdparty_libs(sdk_dir, abis):
|
||||
libs = []
|
||||
for abi in abis:
|
||||
files = os.listdir(path.join(sdk_dir, "sdk/native/3rdparty/libs/" + abi))
|
||||
cur_libs = [f[3:-2] for f in files if f[:3] == "lib" and f[-2:] == ".a"]
|
||||
for lib in cur_libs:
|
||||
if lib not in libs:
|
||||
libs.append(lib)
|
||||
return libs
|
||||
|
||||
def add_printing_linked_libs(sdk_dir, opencv_libs):
|
||||
"""
|
||||
Modifies CMakeLists.txt file in Android project, so it prints linked libraries for each OpenCV library"
|
||||
"""
|
||||
sdk_jni_dir = sdk_dir + "/sdk/native/jni"
|
||||
with open(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt"), "a") as f:
|
||||
f.write('\nset(OpenCV_DIR "' + sdk_jni_dir + '")\n')
|
||||
f.write('find_package(OpenCV REQUIRED)\n')
|
||||
for lib_name in opencv_libs:
|
||||
output_filename_prefix = "linkedlibs." + lib_name + "."
|
||||
f.write('get_target_property(OUT "' + lib_name + '" INTERFACE_LINK_LIBRARIES)\n')
|
||||
f.write('file(WRITE "' + output_filename_prefix + '${ANDROID_ABI}.txt" "${OUT}")\n')
|
||||
|
||||
def read_linked_libs(lib_name, abis):
|
||||
"""
|
||||
Reads linked libs for each OpenCV library from files, that was generated by gradle. See add_printing_linked_libs()
|
||||
"""
|
||||
deps_lists = []
|
||||
for abi in abis:
|
||||
with open(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp", f"linkedlibs.{lib_name}.{abi}.txt")) as f:
|
||||
text = f.read()
|
||||
linked_libs = text.split(";")
|
||||
linked_libs = [x.replace("$<LINK_ONLY:", "").replace(">", "") for x in linked_libs]
|
||||
deps_lists.append(linked_libs)
|
||||
|
||||
return merge_dependencies_lists(deps_lists)
|
||||
|
||||
def merge_dependencies_lists(deps_lists):
|
||||
"""
|
||||
One library may have different dependencies for different ABIS.
|
||||
We need to merge them into one list with all the dependencies preserving the order.
|
||||
"""
|
||||
result = []
|
||||
for d_list in deps_lists:
|
||||
for i in range(len(d_list)):
|
||||
if d_list[i] not in result:
|
||||
if i == 0:
|
||||
result.append(d_list[i])
|
||||
else:
|
||||
index = result.index(d_list[i-1])
|
||||
result = result[:index + 1] + [d_list[i]] + result[index + 1:]
|
||||
|
||||
return result
|
||||
|
||||
def convert_deps_list_to_prefab(linked_libs, opencv_libs, external_libs):
|
||||
"""
|
||||
Converting list of dependencies into prefab format.
|
||||
"""
|
||||
prefab_linked_libs = []
|
||||
for lib in linked_libs:
|
||||
if (lib in opencv_libs) or (lib in external_libs):
|
||||
prefab_linked_libs.append(":" + lib)
|
||||
elif (lib[:3] == "lib" and lib[3:] in external_libs):
|
||||
prefab_linked_libs.append(":" + lib[3:])
|
||||
elif lib == "ocv.3rdparty.android_mediandk":
|
||||
prefab_linked_libs += ["-landroid", "-llog", "-lmediandk"]
|
||||
print("Warning: manualy handled ocv.3rdparty.android_mediandk dependency")
|
||||
elif lib == "ocv.3rdparty.flatbuffers":
|
||||
print("Warning: manualy handled ocv.3rdparty.flatbuffers dependency")
|
||||
elif lib.startswith("ocv.3rdparty"):
|
||||
raise Exception("Unknown lib " + lib)
|
||||
else:
|
||||
prefab_linked_libs.append("-l" + lib)
|
||||
return prefab_linked_libs
|
||||
|
||||
def main(args):
|
||||
opencv_version = get_opencv_version(args.opencv_sdk_path)
|
||||
ndk_version = get_ndk_version(args.ndk_location)
|
||||
print("Detected ndk_version:", ndk_version)
|
||||
abis = os.listdir(path.join(args.opencv_sdk_path, "sdk/native/libs"))
|
||||
final_aar_path = FINAL_AAR_PATH_TEMPLATE.replace("<OPENCV_VERSION>", opencv_version)
|
||||
sdk_dir = args.opencv_sdk_path
|
||||
|
||||
print("Removing data from previous runs...")
|
||||
cleanup([TEMP_DIR, final_aar_path, path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME)])
|
||||
|
||||
print("Preparing Android project...")
|
||||
# ANDROID_PROJECT_TEMPLATE_DIR contains an Android project template that creates AAR
|
||||
shutil.copytree(ANDROID_PROJECT_TEMPLATE_DIR, ANDROID_PROJECT_DIR)
|
||||
|
||||
# Configuring the Android project to static C++ libs version
|
||||
fill_template(path.join(ANDROID_PROJECT_DIR, "OpenCV/build.gradle.template"),
|
||||
path.join(ANDROID_PROJECT_DIR, "OpenCV/build.gradle"),
|
||||
{"LIB_NAME": "templib",
|
||||
"LIB_TYPE": "c++_static",
|
||||
"PACKAGE_NAME": MAVEN_PACKAGE_NAME,
|
||||
"OPENCV_VERSION": opencv_version,
|
||||
"NDK_VERSION": ndk_version,
|
||||
"COMPILE_SDK": args.android_compile_sdk,
|
||||
"MIN_SDK": args.android_min_sdk,
|
||||
"TARGET_SDK": args.android_target_sdk,
|
||||
"ABI_FILTERS": ", ".join(['"' + x + '"' for x in abis]),
|
||||
"JAVA_VERSION": args.java_version,
|
||||
})
|
||||
fill_template(path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt.template"),
|
||||
path.join(ANDROID_PROJECT_DIR, "OpenCV/src/main/cpp/CMakeLists.txt"),
|
||||
{"LIB_NAME": "templib", "LIB_TYPE": "STATIC"})
|
||||
|
||||
local_props = ""
|
||||
if args.ndk_location:
|
||||
local_props += "ndk.dir=" + args.ndk_location + "\n"
|
||||
if args.cmake_location:
|
||||
local_props += "cmake.dir=" + args.cmake_location + "\n"
|
||||
|
||||
if local_props:
|
||||
with open(path.join(ANDROID_PROJECT_DIR, "local.properties"), "wt") as f:
|
||||
f.write(local_props)
|
||||
|
||||
opencv_libs = get_list_of_opencv_libs(sdk_dir)
|
||||
external_libs = get_list_of_3rdparty_libs(sdk_dir, abis)
|
||||
|
||||
add_printing_linked_libs(sdk_dir, opencv_libs)
|
||||
|
||||
print("Running gradle assembleRelease...")
|
||||
cmd = ["./gradlew", "assembleRelease"]
|
||||
if args.offline:
|
||||
cmd = cmd + ["--offline"]
|
||||
# Running gradle to build the Android project
|
||||
subprocess.run(cmd, shell=False, cwd=ANDROID_PROJECT_DIR, check=True)
|
||||
|
||||
# The created AAR package contains only one empty libtemplib.a library.
|
||||
# We need to add OpenCV libraries manually.
|
||||
# AAR package is just a zip archive
|
||||
complied_aar_path = get_compiled_aar_path(COMPILED_AAR_PATH_1, COMPILED_AAR_PATH_2) # two possible paths
|
||||
shutil.unpack_archive(complied_aar_path, AAR_UNZIPPED_DIR, "zip")
|
||||
|
||||
print("Adding libs to AAR...")
|
||||
|
||||
# Copying 3rdparty libs from SDK into the AAR
|
||||
for lib in external_libs:
|
||||
for abi in abis:
|
||||
os.makedirs(path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi))
|
||||
if path.exists(path.join(sdk_dir, "sdk/native/3rdparty/libs/" + abi, "lib" + lib + ".a")):
|
||||
shutil.copy(path.join(sdk_dir, "sdk/native/3rdparty/libs/" + abi, "lib" + lib + ".a"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi, "lib" + lib + ".a"))
|
||||
else:
|
||||
# One OpenCV library may have different dependency lists for different ABIs, but we can write only one
|
||||
# full dependency list for all ABIs. So we just add empty .a library if this ABI doesn't have this dependency.
|
||||
shutil.copy(path.join(AAR_UNZIPPED_DIR, "prefab/modules/templib/libs/android." + abi, "libtemplib.a"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi, "lib" + lib + ".a"))
|
||||
shutil.copy(path.join(AAR_UNZIPPED_DIR, "prefab/modules/templib/libs/android." + abi + "/abi.json"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi + "/abi.json"))
|
||||
shutil.copy(path.join(AAR_UNZIPPED_DIR, "prefab/modules/templib/module.json"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/module.json"))
|
||||
|
||||
# Copying OpenV libs from SDK into the AAR
|
||||
for lib in opencv_libs:
|
||||
for abi in abis:
|
||||
os.makedirs(path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi))
|
||||
shutil.copy(path.join(sdk_dir, "sdk/native/staticlibs/" + abi, "lib" + lib + ".a"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi, "lib" + lib + ".a"))
|
||||
shutil.copy(path.join(AAR_UNZIPPED_DIR, "prefab/modules/templib/libs/android." + abi + "/abi.json"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/libs/android." + abi + "/abi.json"))
|
||||
os.makedirs(path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/include/opencv2"))
|
||||
shutil.copy(path.join(sdk_dir, "sdk/native/jni/include/opencv2/" + lib.replace("opencv_", "") + ".hpp"),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/include/opencv2/" + lib.replace("opencv_", "") + ".hpp"))
|
||||
module_include_folder = path.join(sdk_dir, "sdk/native/jni/include/opencv2/" + lib.replace("opencv_", ""))
|
||||
if os.path.exists(module_include_folder):
|
||||
shutil.copytree(module_include_folder,
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/include/opencv2/" + lib.replace("opencv_", "")))
|
||||
|
||||
# Adding dependencies list
|
||||
module_json_text = {
|
||||
"export_libraries": convert_deps_list_to_prefab(read_linked_libs(lib, abis), opencv_libs, external_libs),
|
||||
"android": {},
|
||||
}
|
||||
with open(path.join(AAR_UNZIPPED_DIR, "prefab/modules/" + lib + "/module.json"), "w") as f:
|
||||
json.dump(module_json_text, f)
|
||||
|
||||
for h_file in ("cvconfig.h", "opencv.hpp", "opencv_modules.hpp"):
|
||||
shutil.copy(path.join(sdk_dir, "sdk/native/jni/include/opencv2/" + h_file),
|
||||
path.join(AAR_UNZIPPED_DIR, "prefab/modules/opencv_core/include/opencv2/" + h_file))
|
||||
|
||||
|
||||
shutil.rmtree(path.join(AAR_UNZIPPED_DIR, "prefab/modules/templib"))
|
||||
|
||||
# Creating final AAR zip archive
|
||||
os.makedirs("outputs", exist_ok=True)
|
||||
shutil.make_archive(final_aar_path, "zip", AAR_UNZIPPED_DIR, ".")
|
||||
os.rename(final_aar_path + ".zip", final_aar_path)
|
||||
|
||||
print("Creating local maven repo...")
|
||||
|
||||
shutil.copy(final_aar_path, path.join(ANDROID_PROJECT_DIR, "OpenCV/opencv-release.aar"))
|
||||
|
||||
print("Creating a maven repo from project sources (with sources jar and javadoc jar)...")
|
||||
cmd = ["./gradlew", "publishReleasePublicationToMyrepoRepository"]
|
||||
if args.offline:
|
||||
cmd = cmd + ["--offline"]
|
||||
subprocess.run(cmd, shell=False, cwd=ANDROID_PROJECT_DIR, check=True)
|
||||
|
||||
os.makedirs(path.join(FINAL_REPO_PATH, "org/opencv"), exist_ok=True)
|
||||
shutil.move(path.join(ANDROID_PROJECT_DIR, "OpenCV/build/repo/org/opencv", MAVEN_PACKAGE_NAME),
|
||||
path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME))
|
||||
|
||||
print("Creating a maven repo from modified AAR (with cpp libraries)...")
|
||||
cmd = ["./gradlew", "publishModifiedPublicationToMyrepoRepository"]
|
||||
if args.offline:
|
||||
cmd = cmd + ["--offline"]
|
||||
subprocess.run(cmd, shell=False, cwd=ANDROID_PROJECT_DIR, check=True)
|
||||
|
||||
# Replacing AAR from the first maven repo with modified AAR from the second maven repo
|
||||
shutil.copytree(path.join(ANDROID_PROJECT_DIR, "OpenCV/build/repo/org/opencv", MAVEN_PACKAGE_NAME),
|
||||
path.join(FINAL_REPO_PATH, "org/opencv", MAVEN_PACKAGE_NAME),
|
||||
dirs_exist_ok=True)
|
||||
|
||||
print("Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Builds AAR with static C++ libs from OpenCV SDK")
|
||||
parser.add_argument('opencv_sdk_path')
|
||||
parser.add_argument('--android_compile_sdk', default="34")
|
||||
parser.add_argument('--android_min_sdk', default="21")
|
||||
parser.add_argument('--android_target_sdk', default="34")
|
||||
parser.add_argument('--java_version', default="1_8")
|
||||
parser.add_argument('--ndk_location', default="")
|
||||
parser.add_argument('--cmake_location', default="")
|
||||
parser.add_argument('--offline', action="store_true", help="Force Gradle use offline mode")
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, 21, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("3", "arm64-v8a", None, 21, cmake_vars=dict(ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES='ON')),
|
||||
ABI("5", "x86_64", None, 21, cmake_vars=dict(ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES='ON')),
|
||||
ABI("4", "x86", None, 21),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, 21, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON', WITH_FASTCV='ON')),
|
||||
ABI("3", "arm64-v8a", None, 21, cmake_vars=dict(ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES='ON', WITH_FASTCV='ON')),
|
||||
ABI("5", "x86_64", None, 21, cmake_vars=dict(ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES='ON')),
|
||||
ABI("4", "x86", None, 21),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2g
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-@GRADLE_VERSION@-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,9 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", "arm-linux-androideabi-4.8", cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("1", "armeabi", "arm-linux-androideabi-4.8"),
|
||||
ABI("3", "arm64-v8a", "aarch64-linux-android-4.9"),
|
||||
ABI("5", "x86_64", "x86_64-4.9"),
|
||||
ABI("4", "x86", "x86-4.8"),
|
||||
ABI("7", "mips64", "mips64el-linux-android-4.9"),
|
||||
ABI("6", "mips", "mipsel-linux-android-4.8")
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", "arm-linux-androideabi-4.9", cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("1", "armeabi", "arm-linux-androideabi-4.9", cmake_vars=dict(WITH_TBB='OFF')),
|
||||
ABI("3", "arm64-v8a", "aarch64-linux-android-4.9"),
|
||||
ABI("5", "x86_64", "x86_64-4.9"),
|
||||
ABI("4", "x86", "x86-4.9"),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("3", "arm64-v8a", None),
|
||||
ABI("5", "x86_64", None),
|
||||
ABI("4", "x86", None),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, 21, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("3", "arm64-v8a", None, 21),
|
||||
ABI("5", "x86_64", None, 21),
|
||||
ABI("4", "x86", None, 21),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, 24, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("3", "arm64-v8a", None, 24),
|
||||
ABI("5", "x86_64", None, 24),
|
||||
ABI("4", "x86", None, 24),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
|
||||
ABI("3", "arm64-v8a", None),
|
||||
ABI("5", "x86_64", None),
|
||||
ABI("4", "x86", None),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON', ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')),
|
||||
ABI("3", "arm64-v8a", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')),
|
||||
ABI("5", "x86_64", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')),
|
||||
ABI("4", "x86", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')),
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
# Docs: https://developer.android.com/ndk/guides/cmake#android_native_api_level
|
||||
ANDROID_NATIVE_API_LEVEL = int(os.environ.get('ANDROID_NATIVE_API_LEVEL', 32))
|
||||
cmake_common_vars = {
|
||||
# Docs: https://source.android.com/docs/setup/about/build-numbers
|
||||
# Docs: https://developer.android.com/studio/publish/versioning
|
||||
'ANDROID_COMPILE_SDK_VERSION': os.environ.get('ANDROID_COMPILE_SDK_VERSION', 32),
|
||||
'ANDROID_TARGET_SDK_VERSION': os.environ.get('ANDROID_TARGET_SDK_VERSION', 32),
|
||||
'ANDROID_MIN_SDK_VERSION': os.environ.get('ANDROID_MIN_SDK_VERSION', ANDROID_NATIVE_API_LEVEL),
|
||||
# Docs: https://developer.android.com/studio/releases/gradle-plugin
|
||||
'ANDROID_GRADLE_PLUGIN_VERSION': '7.3.1',
|
||||
'GRADLE_VERSION': '7.5.1',
|
||||
'KOTLIN_PLUGIN_VERSION': '1.8.20',
|
||||
}
|
||||
ABIs = [
|
||||
ABI("2", "armeabi-v7a", None, ndk_api_level=ANDROID_NATIVE_API_LEVEL, cmake_vars=cmake_common_vars),
|
||||
ABI("3", "arm64-v8a", None, ndk_api_level=ANDROID_NATIVE_API_LEVEL, cmake_vars=cmake_common_vars),
|
||||
ABI("5", "x86_64", None, ndk_api_level=ANDROID_NATIVE_API_LEVEL, cmake_vars=cmake_common_vars),
|
||||
ABI("4", "x86", None, ndk_api_level=ANDROID_NATIVE_API_LEVEL, cmake_vars=cmake_common_vars),
|
||||
]
|
||||
Executable
+182
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This script builds OpenCV into an xcframework compatible with the platforms
|
||||
of your choice. Just run it and grab a snack; you'll be waiting a while.
|
||||
"""
|
||||
|
||||
import sys, os, argparse, pathlib, traceback, contextlib, shutil
|
||||
from cv_build_utils import execute, print_error, print_header, get_xcode_version, get_cmake_version
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Check for dependencies
|
||||
assert sys.version_info >= (3, 6), "Python 3.6 or later is required! Current version is {}".format(sys.version_info)
|
||||
# Need CMake 3.18.5/3.19 or later for a Silicon-related fix to building for the iOS Simulator.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/21425 for context.
|
||||
assert get_cmake_version() >= (3, 18, 5), "CMake 3.18.5 or later is required. Current version is {}".format(get_cmake_version())
|
||||
# Need Xcode 12.2 for Apple Silicon support
|
||||
assert get_xcode_version() >= (12, 2), \
|
||||
"Xcode 12.2 command line tools or later are required! Current version is {}. ".format(get_xcode_version()) + \
|
||||
"Run xcode-select to switch if you have multiple Xcode installs."
|
||||
|
||||
# Parse arguments
|
||||
description = """
|
||||
This script builds OpenCV into an xcframework supporting the Apple platforms of your choice.
|
||||
"""
|
||||
epilog = """
|
||||
Any arguments that are not recognized by this script are passed through to the ios/osx build_framework.py scripts.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description=description, epilog=epilog)
|
||||
parser.add_argument('-o', '--out', metavar='OUTDIR', help='<Required> The directory where the xcframework will be created', required=True)
|
||||
parser.add_argument('--framework_name', default='opencv2', help='Name of OpenCV xcframework (default: opencv2, will change to OpenCV in future version)')
|
||||
parser.add_argument('--iphoneos_archs', default=None, help='select iPhoneOS target ARCHS. Default is "armv7,arm64"')
|
||||
parser.add_argument('--iphonesimulator_archs', default=None, help='select iPhoneSimulator target ARCHS. Default is "x86_64,arm64"')
|
||||
parser.add_argument('--visionos_archs', default=None, help='select visionOS target ARCHS. Default is "arm64"')
|
||||
parser.add_argument('--visionsimulator_archs', default=None, help='select visionSimulator target ARCHS. Default is "arm64"')
|
||||
parser.add_argument('--macos_archs', default=None, help='Select MacOS ARCHS. Default is "x86_64,arm64"')
|
||||
parser.add_argument('--catalyst_archs', default=None, help='Select Catalyst ARCHS. Default is "x86_64,arm64"')
|
||||
parser.add_argument('--build_only_specified_archs', default=False, action='store_true', help='if enabled, only directly specified archs are built and defaults are ignored')
|
||||
|
||||
args, unknown_args = parser.parse_known_args()
|
||||
if unknown_args:
|
||||
print("The following args are not recognized by this script and will be passed through to the ios/osx build_framework.py scripts: {}".format(unknown_args))
|
||||
|
||||
# Parse architectures from args
|
||||
iphoneos_archs = args.iphoneos_archs
|
||||
if not iphoneos_archs and not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
iphoneos_archs = "armv7,arm64"
|
||||
print('Using iPhoneOS ARCHS={}'.format(iphoneos_archs))
|
||||
|
||||
iphonesimulator_archs = args.iphonesimulator_archs
|
||||
if not iphonesimulator_archs and not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
iphonesimulator_archs = "x86_64,arm64"
|
||||
print('Using iPhoneSimulator ARCHS={}'.format(iphonesimulator_archs))
|
||||
|
||||
# Parse architectures from args
|
||||
visionos_archs = args.visionos_archs
|
||||
print('Using visionOS ARCHS={}'.format(visionos_archs))
|
||||
|
||||
visionsimulator_archs = args.visionsimulator_archs
|
||||
print('Using visionSimulator ARCHS={}'.format(visionsimulator_archs))
|
||||
|
||||
macos_archs = args.macos_archs
|
||||
if not macos_archs and not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
macos_archs = "x86_64,arm64"
|
||||
print('Using MacOS ARCHS={}'.format(macos_archs))
|
||||
|
||||
catalyst_archs = args.catalyst_archs
|
||||
if not catalyst_archs and not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
catalyst_archs = "x86_64,arm64"
|
||||
print('Using Catalyst ARCHS={}'.format(catalyst_archs))
|
||||
|
||||
# Build phase
|
||||
|
||||
try:
|
||||
# Phase 1: build .frameworks for each platform
|
||||
osx_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../osx/build_framework.py')
|
||||
ios_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_framework.py')
|
||||
visionos_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_visionos_framework.py')
|
||||
|
||||
build_folders = []
|
||||
docs_build_folder_dict = {}
|
||||
|
||||
def get_or_create_build_folder(base_dir, platform):
|
||||
build_folder = "{}/{}".format(base_dir, platform).replace(" ", "\\ ") # Escape spaces in output path
|
||||
pathlib.Path(build_folder).mkdir(parents=True, exist_ok=True)
|
||||
return build_folder
|
||||
|
||||
if iphoneos_archs:
|
||||
build_folder = get_or_create_build_folder(args.out, "iphoneos")
|
||||
build_folders.append(build_folder)
|
||||
docs_build_folder_dict["ios"] = build_folder
|
||||
command = ["python3", ios_script_path, build_folder, "--iphoneos_archs", iphoneos_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
|
||||
print_header("Building iPhoneOS frameworks")
|
||||
print(command)
|
||||
execute(command, cwd=os.getcwd())
|
||||
if iphonesimulator_archs:
|
||||
build_folder = get_or_create_build_folder(args.out, "iphonesimulator")
|
||||
build_folders.append(build_folder)
|
||||
if not iphoneos_archs:
|
||||
docs_build_folder_dict["ios"] = build_folder
|
||||
command = ["python3", ios_script_path, build_folder, "--iphonesimulator_archs", iphonesimulator_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
|
||||
print_header("Building iPhoneSimulator frameworks")
|
||||
execute(command, cwd=os.getcwd())
|
||||
if visionos_archs:
|
||||
build_folder = get_or_create_build_folder(args.out, "visionos")
|
||||
build_folders.append(build_folder)
|
||||
docs_build_folder_dict["visionos"] = build_folder
|
||||
command = ["python3", visionos_script_path, build_folder, "--visionos_archs", visionos_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
|
||||
print_header("Building visionOS frameworks")
|
||||
print(command)
|
||||
execute(command, cwd=os.getcwd())
|
||||
if visionsimulator_archs:
|
||||
build_folder = get_or_create_build_folder(args.out, "visionsimulator")
|
||||
build_folders.append(build_folder)
|
||||
if not visionos_archs:
|
||||
docs_build_folder_dict["visionos"] = build_folder
|
||||
command = ["python3", visionos_script_path, build_folder, "--visionsimulator_archs", visionsimulator_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
|
||||
print_header("Building visionSimulator frameworks")
|
||||
execute(command, cwd=os.getcwd())
|
||||
if macos_archs:
|
||||
build_folder = get_or_create_build_folder(args.out, "macos")
|
||||
build_folders.append(build_folder)
|
||||
docs_build_folder_dict["macos"] = build_folder
|
||||
command = ["python3", osx_script_path, build_folder, "--macos_archs", macos_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
|
||||
print_header("Building MacOS frameworks")
|
||||
execute(command, cwd=os.getcwd())
|
||||
if catalyst_archs:
|
||||
build_folder = get_or_create_build_folder(args.out, "catalyst")
|
||||
build_folders.append(build_folder)
|
||||
docs_build_folder_dict["catalyst"] = build_folder
|
||||
command = ["python3", osx_script_path, build_folder, "--catalyst_archs", catalyst_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
|
||||
print_header("Building Catalyst frameworks")
|
||||
execute(command, cwd=os.getcwd())
|
||||
|
||||
# Phase 2: put all the built .frameworks together into a .xcframework
|
||||
|
||||
xcframework_path = "{}/{}.xcframework".format(args.out, args.framework_name)
|
||||
print_header("Building {}".format(xcframework_path))
|
||||
|
||||
# Remove the xcframework if it exists, otherwise the existing
|
||||
# file will cause the xcodebuild command to fail.
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
shutil.rmtree(xcframework_path)
|
||||
print("Removed existing xcframework at {}".format(xcframework_path))
|
||||
|
||||
xcframework_build_command = [
|
||||
"xcodebuild",
|
||||
"-create-xcframework",
|
||||
"-output",
|
||||
xcframework_path,
|
||||
]
|
||||
for folder in build_folders:
|
||||
xcframework_build_command += ["-framework", "{}/{}.framework".format(folder, args.framework_name)]
|
||||
execute(xcframework_build_command, cwd=os.getcwd())
|
||||
|
||||
print("")
|
||||
print_header("Finished building {}".format(xcframework_path))
|
||||
|
||||
# Phase 3: copy documentation
|
||||
|
||||
print_header("Copying documentation")
|
||||
|
||||
for platform, build_folder in docs_build_folder_dict.items():
|
||||
docs_src = "{}/docs".format(build_folder)
|
||||
docs_dst = "{}/docs_{}".format(args.out, platform)
|
||||
# Remove the docs folder if it exists
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
shutil.rmtree(docs_dst)
|
||||
print("Removed existing documentation at {}".format(docs_dst))
|
||||
shutil.copytree(docs_src, docs_dst)
|
||||
|
||||
print("")
|
||||
print_header("Finished copying documentation")
|
||||
|
||||
except Exception as e:
|
||||
print_error(e)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Common utilities. These should be compatible with Python3.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import sys, re
|
||||
from subprocess import check_call, check_output, CalledProcessError
|
||||
|
||||
def execute(cmd, cwd = None):
|
||||
print("Executing: %s in %s" % (cmd, cwd), file=sys.stderr)
|
||||
print('Executing: ' + ' '.join(cmd))
|
||||
retcode = check_call(cmd, cwd = cwd)
|
||||
if retcode != 0:
|
||||
raise Exception("Child returned:", retcode)
|
||||
|
||||
def print_header(text):
|
||||
print("="*60)
|
||||
print(text)
|
||||
print("="*60)
|
||||
|
||||
def print_error(text):
|
||||
print("="*60, file=sys.stderr)
|
||||
print("ERROR: %s" % text, file=sys.stderr)
|
||||
print("="*60, file=sys.stderr)
|
||||
|
||||
def get_xcode_major():
|
||||
ret = check_output(["xcodebuild", "-version"]).decode('utf-8')
|
||||
m = re.match(r'Xcode\s+(\d+)\..*', ret, flags=re.IGNORECASE)
|
||||
if m:
|
||||
return int(m.group(1))
|
||||
else:
|
||||
raise Exception("Failed to parse Xcode version")
|
||||
|
||||
def get_xcode_version():
|
||||
"""
|
||||
Returns the major and minor version of the current Xcode
|
||||
command line tools as a tuple of (major, minor)
|
||||
"""
|
||||
ret = check_output(["xcodebuild", "-version"]).decode('utf-8')
|
||||
m = re.match(r'Xcode\s+(\d+)\.(\d+)', ret, flags=re.IGNORECASE)
|
||||
if m:
|
||||
return (int(m.group(1)), int(m.group(2)))
|
||||
else:
|
||||
raise Exception("Failed to parse Xcode version")
|
||||
|
||||
def get_xcode_setting(var, projectdir):
|
||||
ret = check_output(["xcodebuild", "-showBuildSettings"], cwd = projectdir).decode('utf-8')
|
||||
m = re.search("\s" + var + " = (.*)", ret)
|
||||
if m:
|
||||
return m.group(1)
|
||||
else:
|
||||
raise Exception("Failed to parse Xcode settings")
|
||||
|
||||
def get_cmake_version():
|
||||
"""
|
||||
Returns the major and minor version of the current CMake
|
||||
command line tools as a tuple of (major, minor, revision)
|
||||
"""
|
||||
ret = check_output(["cmake", "--version"]).decode('utf-8')
|
||||
m = re.match(r'cmake\sversion\s+(\d+)\.(\d+).(\d+)', ret, flags=re.IGNORECASE)
|
||||
if m:
|
||||
return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
|
||||
else:
|
||||
raise Exception("Failed to parse CMake version")
|
||||
|
||||
def get_current_branch(opencv_dir):
|
||||
ret = check_output(["git", "branch", "--show-current"], cwd = opencv_dir).decode('utf-8').strip()
|
||||
if ret != "":
|
||||
return ret
|
||||
else:
|
||||
raise Exception("Failed to get current branch")
|
||||
|
||||
def find_directory(base_dir, search_dir):
|
||||
dirs = check_output(["find", base_dir, "-type", "d", "-name", search_dir]).decode('utf-8').splitlines()
|
||||
if dirs and len(dirs) > 0:
|
||||
return dirs[0]
|
||||
else:
|
||||
raise Exception("Failed to find directory: " + search_dir)
|
||||
@@ -0,0 +1,56 @@
|
||||
# Building for Apple Platforms
|
||||
|
||||
build_xcframework.py creates an xcframework supporting a variety of Apple platforms.
|
||||
|
||||
You'll need the following to run these steps:
|
||||
- MacOS 10.15 or later
|
||||
- Python 3.6 or later
|
||||
- CMake 3.18.5/3.19.0 or later (make sure the `cmake` command is available on your PATH)
|
||||
- Xcode 12.2 or later (and its command line tools)
|
||||
|
||||
You can then run build_xcframework.py, as below:
|
||||
```
|
||||
cd ~/<my_working_directory>
|
||||
python opencv/platforms/apple/build_xcframework.py --out ./build_xcframework
|
||||
```
|
||||
|
||||
Grab a coffee, because you'll be here for a while. By default this builds OpenCV for 8 architectures across 4 platforms:
|
||||
|
||||
- iOS (`--iphoneos_archs`): arm64, armv7
|
||||
- iOS Simulator (`--iphonesimulator_archs`): x86_64, arm64
|
||||
- macOS (`--macos_archs`): x86_64, arm64
|
||||
- Mac Catalyst (`--catalyst_archs`): x86_64, arm64
|
||||
|
||||
If everything's fine, you will eventually get `opencv2.xcframework` in the output directory.
|
||||
|
||||
The script has some configuration options to exclude platforms and architectures you don't want to build for. Use the `--help` flag for more information.
|
||||
|
||||
## How it Works
|
||||
|
||||
This script generates a fat `.framework` for each platform you specify, and stitches them together into a `.xcframework`. This file can be used to support the same architecture on different platforms, which fat `.framework`s don't allow. To build the intermediate `.framework`s, `build_xcframework.py` leverages the `build_framework.py` scripts in the ios and osx platform folders.
|
||||
|
||||
### Passthrough Arguments
|
||||
|
||||
Any arguments that aren't recognized by `build_xcframework.py` will be passed to the platform-specific `build_framework.py` scripts. The `--without` flag mentioned in the examples is an example of this in action. For more info, see the `--help` info for those scripts.
|
||||
|
||||
## Examples
|
||||
|
||||
You may override the defaults by specifying a value for any of the `*_archs` flags. For example, if you want to build for arm64 on every platform, you can do this:
|
||||
|
||||
```
|
||||
python build_xcframework.py --out somedir --iphoneos_archs arm64 --iphonesimulator_archs arm64 --macos_archs arm64 --catalyst_archs arm64
|
||||
```
|
||||
|
||||
|
||||
If you want to build only for certain platforms, you can supply the `--build_only_specified_archs` flag, which makes the script build only the archs you directly ask for. For example, to build only for Catalyst, you can do this:
|
||||
|
||||
```
|
||||
python build_xcframework.py --out somedir --catalyst_archs x86_64,arm64 --build_only_specified_archs
|
||||
```
|
||||
|
||||
You can also build without OpenCV functionality you don't need. You can do this by using the `--without` flag, which you use once per item you want to go without. For example, if you wanted to compile without `video` or `objc`, you'd can do this:
|
||||
|
||||
```
|
||||
python build_xcframework.py --out somedir --without video --without objc
|
||||
```
|
||||
(if you have issues with this, try using `=`, e.g. `--without=video --without=objc`, and file an issue on GitHub.)
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${FRAMEWORK_NAME}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${OPENCV_APPLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${OPENCV_APPLE_BUNDLE_ID}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${OPENCV_LIBVERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${OPENCV_LIBVERSION}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>${IPHONEOS_DEPLOYMENT_TARGET}</string>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>${OPENCV_APPLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${OPENCV_APPLE_BUNDLE_ID}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${OPENCV_LIBVERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${OPENCV_LIBVERSION}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>0A2A.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+654
@@ -0,0 +1,654 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
The script builds OpenCV.framework for iOS.
|
||||
The built framework is universal, it can be used to build app and run it on either iOS simulator or real device.
|
||||
|
||||
Usage:
|
||||
./build_framework.py <outputdir>
|
||||
|
||||
By cmake conventions (and especially if you work with OpenCV repository),
|
||||
the output dir should not be a subdirectory of OpenCV source tree.
|
||||
|
||||
Script will create <outputdir>, if it's missing, and a few its subdirectories:
|
||||
|
||||
<outputdir>
|
||||
build/
|
||||
iPhoneOS-*/
|
||||
[cmake-generated build tree for an iOS device target]
|
||||
iPhoneSimulator-*/
|
||||
[cmake-generated build tree for iOS simulator]
|
||||
{framework_name}.framework/
|
||||
[the framework content]
|
||||
samples/
|
||||
[sample projects]
|
||||
docs/
|
||||
[documentation]
|
||||
|
||||
The script should handle minor OpenCV updates efficiently
|
||||
- it does not recompile the library from scratch each time.
|
||||
However, {framework_name}.framework directory is erased and recreated on each run.
|
||||
|
||||
Adding --dynamic parameter will build {framework_name}.framework as App Store dynamic framework. Only iOS 8+ versions are supported.
|
||||
"""
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
import glob, os, os.path, shutil, string, sys, argparse, traceback, multiprocessing, io
|
||||
from subprocess import check_call, check_output, CalledProcessError
|
||||
|
||||
if sys.version_info >= (3, 8): # Python 3.8+
|
||||
def copy_tree(src, dst):
|
||||
shutil.copytree(src, dst, dirs_exist_ok=True)
|
||||
else:
|
||||
from distutils.dir_util import copy_tree
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../apple'))
|
||||
from cv_build_utils import execute, print_error, get_xcode_major, get_xcode_setting, get_xcode_version, get_cmake_version, get_current_branch, find_directory
|
||||
|
||||
IPHONEOS_DEPLOYMENT_TARGET='11.0' # default, can be changed via command line options or environment variable
|
||||
|
||||
CURRENT_FILE_DIR = os.path.dirname(__file__)
|
||||
|
||||
|
||||
class Builder:
|
||||
def __init__(self, opencv, contrib, dynamic, exclude, disable, enablenonfree, targets, debug, debug_info, framework_name, run_tests, hosting_base_path, swiftdisabled):
|
||||
self.opencv = os.path.abspath(opencv)
|
||||
self.contrib = None
|
||||
if contrib:
|
||||
modpath = os.path.join(contrib, "modules")
|
||||
if os.path.isdir(modpath):
|
||||
self.contrib = os.path.abspath(modpath)
|
||||
else:
|
||||
print("Note: contrib repository is bad - modules subfolder not found", file=sys.stderr)
|
||||
self.dynamic = dynamic
|
||||
self.exclude = exclude
|
||||
self.build_objc_wrapper = not "objc" in self.exclude
|
||||
self.disable = disable
|
||||
self.enablenonfree = enablenonfree
|
||||
self.targets = targets
|
||||
self.debug = debug
|
||||
self.debug_info = debug_info
|
||||
self.framework_name = framework_name
|
||||
self.run_tests = run_tests
|
||||
if hosting_base_path is None:
|
||||
current_branch = get_current_branch(self.opencv)
|
||||
objc_target = self.getObjcTarget(self.targets[0][1])
|
||||
self.hosting_base_path = os.path.join(current_branch, "macos" if objc_target == "osx" else objc_target)
|
||||
else:
|
||||
self.hosting_base_path = hosting_base_path
|
||||
self.swiftdisabled = swiftdisabled
|
||||
self.docs_built = False
|
||||
self.build_docs = False
|
||||
|
||||
def checkCMakeVersion(self):
|
||||
if get_xcode_version() >= (12, 2):
|
||||
assert get_cmake_version() >= (3, 19), "CMake 3.19 or later is required when building with Xcode 12.2 or greater. Current version is {}".format(get_cmake_version())
|
||||
else:
|
||||
assert get_cmake_version() >= (3, 17), "CMake 3.17 or later is required. Current version is {}".format(get_cmake_version())
|
||||
|
||||
def getBuildDir(self, parent, target):
|
||||
|
||||
res = os.path.join(parent, 'build-%s-%s' % (target[0].lower(), target[1].lower()))
|
||||
|
||||
if not os.path.isdir(res):
|
||||
os.makedirs(res)
|
||||
return os.path.abspath(res)
|
||||
|
||||
def _build(self, outdir):
|
||||
self.checkCMakeVersion()
|
||||
outdir = os.path.abspath(outdir)
|
||||
if not os.path.isdir(outdir):
|
||||
os.makedirs(outdir)
|
||||
main_working_dir = os.path.join(outdir, "build")
|
||||
dirs = []
|
||||
|
||||
xcode_ver = get_xcode_major()
|
||||
xcode_supports_ios_32bit_arch = xcode_ver <= 13
|
||||
self.build_docs = xcode_ver >= 13
|
||||
|
||||
# build each architecture separately
|
||||
alltargets = []
|
||||
|
||||
for target_group in self.targets:
|
||||
for arch in target_group[0]:
|
||||
if arch in ["armv7", "armv7s", "i386"] and not xcode_supports_ios_32bit_arch:
|
||||
print("Skipping unsupported architecture: " + arch)
|
||||
continue
|
||||
current = ( arch, target_group[1] )
|
||||
alltargets.append(current)
|
||||
|
||||
for target in alltargets:
|
||||
main_build_dir = self.getBuildDir(main_working_dir, target)
|
||||
dirs.append(main_build_dir)
|
||||
|
||||
cmake_flags = []
|
||||
if self.contrib:
|
||||
cmake_flags.append("-DOPENCV_EXTRA_MODULES_PATH=%s" % self.contrib)
|
||||
if xcode_ver >= 7 and target[1] == 'Catalyst':
|
||||
sdk_path = check_output(["xcodebuild", "-version", "-sdk", "macosx", "Path"]).decode('utf-8').rstrip()
|
||||
c_flags = [
|
||||
"-target %s-apple-ios14.0-macabi" % target[0], # e.g. x86_64-apple-ios13.2-macabi # -mmacosx-version-min=10.15
|
||||
"-isysroot %s" % sdk_path,
|
||||
"-iframework %s/System/iOSSupport/System/Library/Frameworks" % sdk_path,
|
||||
"-isystem %s/System/iOSSupport/usr/include" % sdk_path,
|
||||
]
|
||||
cmake_flags.append("-DCMAKE_C_FLAGS=" + " ".join(c_flags))
|
||||
cmake_flags.append("-DCMAKE_CXX_FLAGS=" + " ".join(c_flags))
|
||||
cmake_flags.append("-DCMAKE_EXE_LINKER_FLAGS=" + " ".join(c_flags))
|
||||
|
||||
# CMake cannot compile Swift for Catalyst https://gitlab.kitware.com/cmake/cmake/-/issues/21436
|
||||
# cmake_flags.append("-DCMAKE_Swift_FLAGS=" + " " + target_flag)
|
||||
cmake_flags.append("-DSWIFT_DISABLED=1")
|
||||
|
||||
cmake_flags.append("-DIOS=1") # Build the iOS codebase
|
||||
cmake_flags.append("-DMAC_CATALYST=1") # Set a flag for Mac Catalyst, just in case we need it
|
||||
cmake_flags.append("-DWITH_OPENCL=OFF") # Disable OpenCL; it isn't compatible with iOS
|
||||
cmake_flags.append("-DCMAKE_OSX_SYSROOT=%s" % sdk_path)
|
||||
cmake_flags.append("-DCMAKE_CXX_COMPILER_WORKS=TRUE")
|
||||
cmake_flags.append("-DCMAKE_C_COMPILER_WORKS=TRUE")
|
||||
|
||||
print("::group::Building target", target[0], target[1], flush=True)
|
||||
self.buildOne(target[0], target[1], main_build_dir, cmake_flags)
|
||||
print("::endgroup::", flush=True)
|
||||
|
||||
if not self.dynamic:
|
||||
print("::group::Merge libs", target[0], target[1], flush=True)
|
||||
self.mergeLibs(main_build_dir)
|
||||
print("::endgroup::", flush=True)
|
||||
else:
|
||||
print("::group::Make dynamic lib", target[0], target[1], flush=True)
|
||||
self.makeDynamicLib(main_build_dir)
|
||||
print("::endgroup::", flush=True)
|
||||
|
||||
self.makeFramework(outdir, dirs)
|
||||
if self.build_objc_wrapper:
|
||||
doc_output = os.path.join(outdir, "docs")
|
||||
if os.path.exists(doc_output):
|
||||
shutil.rmtree(doc_output)
|
||||
|
||||
doc_build_path = os.path.join(dirs[0], "lib", self.getConfiguration(), "docs")
|
||||
if os.path.exists(doc_build_path):
|
||||
copy_tree(doc_build_path, doc_output)
|
||||
else:
|
||||
print("Documentation not found at: " + doc_build_path);
|
||||
if self.run_tests:
|
||||
check_call([sys.argv[0].replace("build_framework", "run_tests"), "--framework_dir=" + outdir, "--framework_name=" + self.framework_name, dirs[0] + "/modules/objc_bindings_generator/{}/test".format(self.getObjcTarget(target[1]))])
|
||||
else:
|
||||
print("To run tests call:")
|
||||
print(sys.argv[0].replace("build_framework", "run_tests") + " --framework_dir=" + outdir + " --framework_name=" + self.framework_name + " " + dirs[0] + "/modules/objc_bindings_generator/{}/test".format(self.getObjcTarget(target[1])))
|
||||
self.copy_samples(outdir)
|
||||
if self.swiftdisabled:
|
||||
swift_sources_dir = os.path.join(outdir, "SwiftSources")
|
||||
if not os.path.exists(swift_sources_dir):
|
||||
os.makedirs(swift_sources_dir)
|
||||
for root, dirs, files in os.walk(dirs[0]):
|
||||
for file in files:
|
||||
if file.endswith(".swift") and file.find("Test") == -1:
|
||||
with io.open(os.path.join(root, file), encoding="utf-8", errors="ignore") as file_in:
|
||||
body = file_in.read()
|
||||
if body.find("import Foundation") != -1:
|
||||
insert_pos = body.find("import Foundation") + len("import Foundation") + 1
|
||||
body = body[:insert_pos] + "import " + self.framework_name + "\n" + body[insert_pos:]
|
||||
else:
|
||||
body = "import " + self.framework_name + "\n\n" + body
|
||||
with open(os.path.join(swift_sources_dir, file), "w", encoding="utf-8") as file_out:
|
||||
file_out.write(body)
|
||||
|
||||
def build(self, outdir):
|
||||
try:
|
||||
self._build(outdir)
|
||||
except Exception as e:
|
||||
print_error(e)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def getToolchain(self, arch, target):
|
||||
return None
|
||||
|
||||
def getConfiguration(self):
|
||||
return "Debug" if self.debug else "Release"
|
||||
|
||||
def getCMakeArgs(self, arch, target):
|
||||
|
||||
args = [
|
||||
"cmake",
|
||||
"-GXcode",
|
||||
"-DAPPLE_FRAMEWORK=ON",
|
||||
"-DCMAKE_INSTALL_PREFIX=install",
|
||||
"-DCMAKE_BUILD_TYPE=%s" % self.getConfiguration(),
|
||||
"-DOPENCV_INCLUDE_INSTALL_PATH=include",
|
||||
"-DOPENCV_3P_LIB_INSTALL_PATH=lib/3rdparty",
|
||||
"-DFRAMEWORK_NAME=%s" % self.framework_name,
|
||||
]
|
||||
if self.dynamic:
|
||||
args += [
|
||||
"-DDYNAMIC_PLIST=ON"
|
||||
]
|
||||
if self.enablenonfree:
|
||||
args += [
|
||||
"-DOPENCV_ENABLE_NONFREE=ON"
|
||||
]
|
||||
if self.debug_info:
|
||||
args += [
|
||||
"-DBUILD_WITH_DEBUG_INFO=ON"
|
||||
]
|
||||
|
||||
if len(self.exclude) > 0:
|
||||
args += ["-DBUILD_opencv_%s=OFF" % m for m in self.exclude]
|
||||
|
||||
if len(self.disable) > 0:
|
||||
args += ["-DWITH_%s=OFF" % f for f in self.disable]
|
||||
|
||||
return args
|
||||
|
||||
def getBuildCommand(self, arch, target):
|
||||
|
||||
buildcmd = [
|
||||
"xcodebuild",
|
||||
]
|
||||
|
||||
buildcmd += [
|
||||
"IPHONEOS_DEPLOYMENT_TARGET=" + os.environ['IPHONEOS_DEPLOYMENT_TARGET'],
|
||||
"ARCHS=%s" % arch,
|
||||
"-sdk", target.lower(),
|
||||
"-configuration", self.getConfiguration(),
|
||||
"-parallelizeTargets",
|
||||
"-jobs", str(multiprocessing.cpu_count()),
|
||||
]
|
||||
|
||||
return buildcmd
|
||||
|
||||
def getDocBuildCommand(self, base_build_dir, source_dir, framework_build_dir, docs_dir):
|
||||
output_dir = docs_dir if self.hosting_base_path == "" else os.path.join(docs_dir, self.hosting_base_path)
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
symbol_graph_dir = find_directory(os.path.join(framework_build_dir, "build", self.framework_name + ".build"), "symbol-graph")
|
||||
doc_buildcmd = [
|
||||
"xcrun",
|
||||
"docc",
|
||||
"convert",
|
||||
"--emit-lmdb-index",
|
||||
"--fallback-display-name", self.framework_name,
|
||||
"--fallback-bundle-identifier", "org.opencv." + self.framework_name,
|
||||
"--fallback-bundle-version", "1",
|
||||
"--output-dir", output_dir,
|
||||
"--transform-for-static-hosting",
|
||||
"--ide-console-output",
|
||||
os.path.join(source_dir, "Documentation.docc"),
|
||||
"--additional-symbol-graph-dir", symbol_graph_dir
|
||||
]
|
||||
|
||||
if self.hosting_base_path != "":
|
||||
doc_buildcmd += ["--hosting-base-path", self.hosting_base_path]
|
||||
|
||||
return doc_buildcmd
|
||||
|
||||
def getInfoPlist(self, builddirs):
|
||||
return os.path.join(builddirs[0], "ios", "Info.plist")
|
||||
|
||||
def getObjcTarget(self, target):
|
||||
# Obj-C generation target
|
||||
return 'ios'
|
||||
|
||||
def makeCMakeCmd(self, arch, target, dir, cmakeargs = []):
|
||||
toolchain = self.getToolchain(arch, target)
|
||||
cmakecmd = self.getCMakeArgs(arch, target) + \
|
||||
(["-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain] if toolchain is not None else [])
|
||||
if target.lower().startswith("iphoneos") or target.lower().startswith("xros"):
|
||||
cmakecmd.append("-DCPU_BASELINE=DETECT")
|
||||
if target.lower().startswith("iphonesimulator") or target.lower().startswith("xrsimulator"):
|
||||
build_arch = check_output(["uname", "-m"]).decode('utf-8').rstrip()
|
||||
if build_arch != arch:
|
||||
print("build_arch (%s) != arch (%s)" % (build_arch, arch))
|
||||
cmakecmd.append("-DCMAKE_SYSTEM_PROCESSOR=" + arch)
|
||||
cmakecmd.append("-DCMAKE_OSX_ARCHITECTURES=" + arch)
|
||||
cmakecmd.append("-DCPU_BASELINE=DETECT")
|
||||
cmakecmd.append("-DCMAKE_CROSSCOMPILING=ON")
|
||||
cmakecmd.append("-DOPENCV_WORKAROUND_CMAKE_20989=ON")
|
||||
if target.lower() == "catalyst":
|
||||
build_arch = check_output(["uname", "-m"]).decode('utf-8').rstrip()
|
||||
if build_arch != arch:
|
||||
print("build_arch (%s) != arch (%s)" % (build_arch, arch))
|
||||
cmakecmd.append("-DCMAKE_SYSTEM_PROCESSOR=" + arch)
|
||||
cmakecmd.append("-DCMAKE_OSX_ARCHITECTURES=" + arch)
|
||||
cmakecmd.append("-DCPU_BASELINE=DETECT")
|
||||
cmakecmd.append("-DCMAKE_CROSSCOMPILING=ON")
|
||||
cmakecmd.append("-DOPENCV_WORKAROUND_CMAKE_20989=ON")
|
||||
if target.lower() == "macosx":
|
||||
build_arch = check_output(["uname", "-m"]).decode('utf-8').rstrip()
|
||||
if build_arch != arch:
|
||||
print("build_arch (%s) != arch (%s)" % (build_arch, arch))
|
||||
cmakecmd.append("-DCMAKE_SYSTEM_PROCESSOR=" + arch)
|
||||
cmakecmd.append("-DCMAKE_OSX_ARCHITECTURES=" + arch)
|
||||
cmakecmd.append("-DCPU_BASELINE=DETECT")
|
||||
cmakecmd.append("-DCMAKE_CROSSCOMPILING=ON")
|
||||
cmakecmd.append("-DOPENCV_WORKAROUND_CMAKE_20989=ON")
|
||||
|
||||
cmakecmd.append(dir)
|
||||
cmakecmd.extend(cmakeargs)
|
||||
return cmakecmd
|
||||
|
||||
def buildOne(self, arch, target, builddir, cmakeargs = []):
|
||||
# Run cmake
|
||||
#toolchain = self.getToolchain(arch, target)
|
||||
#cmakecmd = self.getCMakeArgs(arch, target) + \
|
||||
# (["-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain] if toolchain is not None else [])
|
||||
#if target.lower().startswith("iphoneos"):
|
||||
# cmakecmd.append("-DCPU_BASELINE=DETECT")
|
||||
#cmakecmd.append(self.opencv)
|
||||
#cmakecmd.extend(cmakeargs)
|
||||
cmakecmd = self.makeCMakeCmd(arch, target, self.opencv, cmakeargs)
|
||||
print("")
|
||||
print("=================================")
|
||||
print("CMake")
|
||||
print("=================================")
|
||||
print("")
|
||||
execute(cmakecmd, cwd = builddir)
|
||||
print("")
|
||||
print("=================================")
|
||||
print("Xcodebuild")
|
||||
print("=================================")
|
||||
print("")
|
||||
|
||||
# Clean and build
|
||||
clean_dir = os.path.join(builddir, "install")
|
||||
if os.path.isdir(clean_dir):
|
||||
shutil.rmtree(clean_dir)
|
||||
buildcmd = self.getBuildCommand(arch, target)
|
||||
execute(buildcmd + ["-target", "ALL_BUILD", "build"], cwd = builddir)
|
||||
execute(["cmake", "-DBUILD_TYPE=%s" % self.getConfiguration(), "-P", "cmake_install.cmake"], cwd = builddir)
|
||||
if self.build_objc_wrapper:
|
||||
objc_source_dir = builddir + "/modules/objc_bindings_generator/{}/gen".format(self.getObjcTarget(target))
|
||||
cmakecmd = self.makeCMakeCmd(arch, target, objc_source_dir, cmakeargs)
|
||||
if self.swiftdisabled:
|
||||
cmakecmd.append("-DSWIFT_DISABLED=1")
|
||||
cmakecmd.append("-DBUILD_ROOT=%s" % builddir)
|
||||
cmakecmd.append("-DCMAKE_INSTALL_NAME_TOOL=install_name_tool")
|
||||
cmakecmd.append("--no-warn-unused-cli")
|
||||
framework_build_dir = builddir + "/modules/objc/framework_build"
|
||||
execute(cmakecmd, cwd = framework_build_dir)
|
||||
execute(buildcmd + ["-target", "ALL_BUILD", "build"], cwd = framework_build_dir)
|
||||
if self.build_docs and not self.docs_built:
|
||||
# build the syntax graphs
|
||||
execute(buildcmd + ["-target", "ALL_BUILD", "docbuild"], cwd = framework_build_dir)
|
||||
# build the document catalog
|
||||
docs_dir = os.path.join(builddir, "lib", self.getConfiguration(), "docs")
|
||||
doc_buildcmd2 = self.getDocBuildCommand(builddir, objc_source_dir, framework_build_dir, docs_dir)
|
||||
execute(doc_buildcmd2, cwd = objc_source_dir)
|
||||
with open(os.path.join(self.opencv, "modules", "objc", "generator", "templates", "doc_howto.template"), "r") as f:
|
||||
howto_template = f.read()
|
||||
howto = string.Template(howto_template).substitute(
|
||||
framework = self.framework_name,
|
||||
hosting_base_path = self.hosting_base_path
|
||||
)
|
||||
with open(os.path.join(docs_dir, "HOWTO.md"), "w", encoding="utf-8") as file:
|
||||
file.write(howto)
|
||||
self.docs_built = True
|
||||
execute(["cmake", "-DBUILD_TYPE=%s" % self.getConfiguration(), "-DCMAKE_INSTALL_PREFIX=%s" % (builddir + "/install"), "-P", "cmake_install.cmake"], cwd = framework_build_dir)
|
||||
|
||||
def mergeLibs(self, builddir):
|
||||
res = os.path.join(builddir, "lib", self.getConfiguration(), "libopencv_merged.a")
|
||||
libs = glob.glob(os.path.join(builddir, "install", "lib", "*.a"))
|
||||
module = [os.path.join(builddir, "install", "lib", self.framework_name + ".framework", self.framework_name)] if self.build_objc_wrapper else []
|
||||
|
||||
libs3 = glob.glob(os.path.join(builddir, "install", "lib", "3rdparty", "*.a"))
|
||||
print("Merging libraries:\n\t%s" % "\n\t".join(libs + libs3 + module), file=sys.stderr)
|
||||
execute(["libtool", "-static", "-o", res] + libs + libs3 + module)
|
||||
|
||||
def makeDynamicLib(self, builddir):
|
||||
target = builddir[(builddir.rfind("build-") + 6):]
|
||||
target_platform = target[(target.rfind("-") + 1):]
|
||||
is_device = target_platform == "iphoneos" or target_platform == "visionos" or target_platform == "catalyst"
|
||||
framework_dir = os.path.join(builddir, "install", "lib", self.framework_name + ".framework")
|
||||
if not os.path.exists(framework_dir):
|
||||
os.makedirs(framework_dir)
|
||||
res = os.path.join(framework_dir, self.framework_name)
|
||||
libs = glob.glob(os.path.join(builddir, "install", "lib", "*.a"))
|
||||
if self.build_objc_wrapper:
|
||||
module = [os.path.join(builddir, "lib", self.getConfiguration(), self.framework_name + ".framework", self.framework_name)]
|
||||
else:
|
||||
module = []
|
||||
|
||||
libs3 = glob.glob(os.path.join(builddir, "install", "lib", "3rdparty", "*.a"))
|
||||
|
||||
if os.environ.get('IPHONEOS_DEPLOYMENT_TARGET'):
|
||||
link_target = target[:target.find("-")] + "-apple-ios" + os.environ['IPHONEOS_DEPLOYMENT_TARGET'] + ("-simulator" if target.endswith("simulator") else "")
|
||||
else:
|
||||
if target_platform == "catalyst":
|
||||
link_target = "%s-apple-ios14.0-macabi" % target[:target.find("-")]
|
||||
else:
|
||||
link_target = "%s-apple-darwin" % target[:target.find("-")]
|
||||
toolchain_dir = get_xcode_setting("TOOLCHAIN_DIR", builddir)
|
||||
sdk_dir = get_xcode_setting("SDK_DIR", builddir)
|
||||
framework_options = []
|
||||
swift_link_dirs = ["-L" + toolchain_dir + "/usr/lib/swift/" + target_platform, "-L/usr/lib/swift"]
|
||||
if target_platform == "catalyst":
|
||||
swift_link_dirs = ["-L" + toolchain_dir + "/usr/lib/swift/" + "maccatalyst", "-L/usr/lib/swift"]
|
||||
framework_options = [
|
||||
"-iframework", "%s/System/iOSSupport/System/Library/Frameworks" % sdk_dir,
|
||||
"-framework", "AVFoundation", "-framework", "UIKit", "-framework", "CoreGraphics",
|
||||
"-framework", "CoreImage", "-framework", "CoreMedia", "-framework", "QuartzCore",
|
||||
]
|
||||
elif target_platform == "macosx":
|
||||
framework_options = [
|
||||
"-framework", "AVFoundation", "-framework", "AppKit", "-framework", "CoreGraphics",
|
||||
"-framework", "CoreImage", "-framework", "CoreMedia", "-framework", "QuartzCore",
|
||||
"-framework", "Accelerate", "-framework", "OpenCL",
|
||||
]
|
||||
elif target_platform == "iphoneos" or target_platform == "iphonesimulator" or target_platform == "xros" or target_platform == "xrsimulator":
|
||||
framework_options = [
|
||||
"-iframework", "%s/System/iOSSupport/System/Library/Frameworks" % sdk_dir,
|
||||
"-framework", "AVFoundation", "-framework", "CoreGraphics",
|
||||
"-framework", "CoreImage", "-framework", "CoreMedia", "-framework", "QuartzCore",
|
||||
"-framework", "Accelerate", "-framework", "UIKit", "-framework", "CoreVideo",
|
||||
]
|
||||
execute([
|
||||
"clang++",
|
||||
"-Xlinker", "-rpath",
|
||||
"-Xlinker", "/usr/lib/swift",
|
||||
"-target", link_target,
|
||||
"-isysroot", sdk_dir,] +
|
||||
framework_options + [
|
||||
"-install_name", "@rpath/" + self.framework_name + ".framework/" + self.framework_name,
|
||||
"-dynamiclib", "-dead_strip", "-fobjc-link-runtime", "-all_load",
|
||||
"-o", res
|
||||
] + swift_link_dirs + module + libs + libs3)
|
||||
|
||||
def makeFramework(self, outdir, builddirs):
|
||||
name = self.framework_name
|
||||
|
||||
# set the current dir to the dst root
|
||||
framework_dir = os.path.join(outdir, "%s.framework" % name)
|
||||
if os.path.isdir(framework_dir):
|
||||
shutil.rmtree(framework_dir)
|
||||
os.makedirs(framework_dir)
|
||||
|
||||
if self.dynamic:
|
||||
dstdir = framework_dir
|
||||
else:
|
||||
dstdir = os.path.join(framework_dir, "Versions", "A")
|
||||
|
||||
# copy headers from one of build folders
|
||||
shutil.copytree(os.path.join(builddirs[0], "install", "include", "opencv2"), os.path.join(dstdir, "Headers"))
|
||||
if name != "opencv2":
|
||||
for dirname, dirs, files in os.walk(os.path.join(dstdir, "Headers")):
|
||||
for filename in files:
|
||||
filepath = os.path.join(dirname, filename)
|
||||
with open(filepath, "r", encoding="utf-8") as file:
|
||||
body = file.read()
|
||||
body = body.replace("include \"opencv2/", "include \"" + name + "/")
|
||||
body = body.replace("include <opencv2/", "include <" + name + "/")
|
||||
with open(filepath, "w", encoding="utf-8") as file:
|
||||
file.write(body)
|
||||
if self.build_objc_wrapper:
|
||||
copy_tree(os.path.join(builddirs[0], "install", "lib", name + ".framework", "Headers"), os.path.join(dstdir, "Headers"))
|
||||
platform_name_map = {
|
||||
"arm": "armv7-apple-ios",
|
||||
"arm64": "arm64-apple-ios",
|
||||
"i386": "i386-apple-ios-simulator",
|
||||
"x86_64": "x86_64-apple-ios-simulator",
|
||||
} if builddirs[0].find("iphone") != -1 else {
|
||||
"x86_64": "x86_64-apple-macos",
|
||||
"arm64": "arm64-apple-macos",
|
||||
}
|
||||
for d in builddirs:
|
||||
copy_tree(os.path.join(d, "install", "lib", name + ".framework", "Modules"), os.path.join(dstdir, "Modules"))
|
||||
for dirname, dirs, files in os.walk(os.path.join(dstdir, "Modules")):
|
||||
for filename in files:
|
||||
filestem = os.path.splitext(filename)[0]
|
||||
fileext = os.path.splitext(filename)[1]
|
||||
if filestem in platform_name_map:
|
||||
os.rename(os.path.join(dirname, filename), os.path.join(dirname, platform_name_map[filestem] + fileext))
|
||||
|
||||
# make universal static lib
|
||||
if self.dynamic:
|
||||
libs = [os.path.join(d, "install", "lib", name + ".framework", name) for d in builddirs]
|
||||
else:
|
||||
libs = [os.path.join(d, "lib", self.getConfiguration(), "libopencv_merged.a") for d in builddirs]
|
||||
lipocmd = ["lipo", "-create"]
|
||||
lipocmd.extend(libs)
|
||||
lipocmd.extend(["-o", os.path.join(dstdir, name)])
|
||||
print("Creating universal library from:\n\t%s" % "\n\t".join(libs), file=sys.stderr)
|
||||
execute(lipocmd)
|
||||
|
||||
# dynamic framework has different structure, just copy the Plist directly
|
||||
if self.dynamic:
|
||||
resdir = dstdir
|
||||
shutil.copyfile(self.getInfoPlist(builddirs), os.path.join(resdir, "Info.plist"))
|
||||
else:
|
||||
# copy Info.plist
|
||||
resdir = os.path.join(dstdir, "Resources")
|
||||
os.makedirs(resdir)
|
||||
shutil.copyfile(self.getInfoPlist(builddirs), os.path.join(resdir, "Info.plist"))
|
||||
|
||||
# make symbolic links
|
||||
links = [
|
||||
(["A"], ["Versions", "Current"]),
|
||||
(["Versions", "Current", "Headers"], ["Headers"]),
|
||||
(["Versions", "Current", "Resources"], ["Resources"]),
|
||||
(["Versions", "Current", "Modules"], ["Modules"]),
|
||||
(["Versions", "Current", name], [name])
|
||||
]
|
||||
for l in links:
|
||||
s = os.path.join(*l[0])
|
||||
d = os.path.join(framework_dir, *l[1])
|
||||
os.symlink(s, d)
|
||||
# Copy Apple privacy manifest
|
||||
shutil.copyfile(os.path.join(CURRENT_FILE_DIR, "PrivacyInfo.xcprivacy"),
|
||||
os.path.join(resdir, "PrivacyInfo.xcprivacy"))
|
||||
|
||||
def copy_samples(self, outdir):
|
||||
return
|
||||
|
||||
class iOSBuilder(Builder):
|
||||
|
||||
def getToolchain(self, arch, target):
|
||||
toolchain = os.path.join(self.opencv, "platforms", "ios", "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % target)
|
||||
return toolchain
|
||||
|
||||
def getCMakeArgs(self, arch, target):
|
||||
args = Builder.getCMakeArgs(self, arch, target)
|
||||
args = args + [
|
||||
'-DIOS_ARCH=%s' % arch
|
||||
]
|
||||
return args
|
||||
|
||||
def copy_samples(self, outdir):
|
||||
print('Copying samples to: ' + outdir)
|
||||
samples_dir = os.path.join(outdir, "samples")
|
||||
if os.path.exists(samples_dir):
|
||||
shutil.rmtree(samples_dir)
|
||||
shutil.copytree(os.path.join(self.opencv, "samples", "swift", "ios"), samples_dir)
|
||||
if self.framework_name != "OpenCV":
|
||||
for dirname, dirs, files in os.walk(samples_dir):
|
||||
for filename in files:
|
||||
if not filename.endswith((".h", ".swift", ".pbxproj")):
|
||||
continue
|
||||
filepath = os.path.join(dirname, filename)
|
||||
with open(filepath) as file:
|
||||
body = file.read()
|
||||
body = body.replace("import OpenCV", "import " + self.framework_name)
|
||||
body = body.replace("#import <OpenCV/OpenCV.h>", "#import <" + self.framework_name + "/" + self.framework_name + ".h>")
|
||||
body = body.replace("OpenCV.framework", self.framework_name + ".framework")
|
||||
body = body.replace("../../OpenCV/**", "../../" + self.framework_name + "/**")
|
||||
with open(filepath, "w") as file:
|
||||
file.write(body)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
folder = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
|
||||
parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for iOS.')
|
||||
# TODO: When we can make breaking changes, we should make the out argument explicit and required like in build_xcframework.py.
|
||||
parser.add_argument('out', metavar='OUTDIR', help='folder to put built framework')
|
||||
parser.add_argument('--opencv', metavar='DIR', default=folder, help='folder with opencv repository (default is "../.." relative to script location)')
|
||||
parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
|
||||
parser.add_argument('--without', metavar='MODULE', default=[], action='append', help='OpenCV modules to exclude from the framework. To exclude multiple, specify this flag again, e.g. "--without video --without objc"')
|
||||
parser.add_argument('--disable', metavar='FEATURE', default=[], action='append', help='OpenCV features to disable (add WITH_*=OFF). To disable multiple, specify this flag again, e.g. "--disable tbb --disable openmp"')
|
||||
parser.add_argument('--dynamic', default=False, action='store_true', help='build dynamic framework (default is "False" - builds static framework)')
|
||||
parser.add_argument('--iphoneos_deployment_target', default=os.environ.get('IPHONEOS_DEPLOYMENT_TARGET', IPHONEOS_DEPLOYMENT_TARGET), help='specify IPHONEOS_DEPLOYMENT_TARGET')
|
||||
parser.add_argument('--build_only_specified_archs', default=False, action='store_true', help='if enabled, only directly specified archs are built and defaults are ignored')
|
||||
parser.add_argument('--iphoneos_archs', default=None, help='select iPhoneOS target ARCHS. Default is "arm64"')
|
||||
parser.add_argument('--iphonesimulator_archs', default=None, help='select iPhoneSimulator target ARCHS. Default is "x86_64"')
|
||||
parser.add_argument('--enable_nonfree', default=False, dest='enablenonfree', action='store_true', help='enable non-free modules (disabled by default)')
|
||||
parser.add_argument('--debug', default=False, dest='debug', action='store_true', help='Build "Debug" binaries (disabled by default)')
|
||||
parser.add_argument('--debug_info', default=False, dest='debug_info', action='store_true', help='Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)')
|
||||
parser.add_argument('--framework_name', default='opencv2', dest='framework_name', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
|
||||
parser.add_argument('--legacy_build', default=False, dest='legacy_build', action='store_true', help='Build legacy opencv2 framework (default: False, equivalent to "--framework_name=opencv2 --without=objc")')
|
||||
parser.add_argument('--run_tests', default=False, dest='run_tests', action='store_true', help='Run tests')
|
||||
parser.add_argument('--doc_hosting_base_path', default=None, dest='hosting_base_path', action='store_true', help='Documentation hosting base path')
|
||||
parser.add_argument('--disable-swift', default=False, dest='swiftdisabled', action='store_true', help='Disable building of Swift extensions')
|
||||
|
||||
args, unknown_args = parser.parse_known_args()
|
||||
if unknown_args:
|
||||
print("The following args are not recognized and will not be used: %s" % unknown_args)
|
||||
|
||||
os.environ['IPHONEOS_DEPLOYMENT_TARGET'] = args.iphoneos_deployment_target
|
||||
print('Using IPHONEOS_DEPLOYMENT_TARGET=' + os.environ['IPHONEOS_DEPLOYMENT_TARGET'])
|
||||
|
||||
iphoneos_archs = None
|
||||
if args.iphoneos_archs:
|
||||
iphoneos_archs = args.iphoneos_archs.split(',')
|
||||
elif not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
iphoneos_archs = ["arm64"]
|
||||
print('Using iPhoneOS ARCHS=' + str(iphoneos_archs))
|
||||
|
||||
iphonesimulator_archs = None
|
||||
if args.iphonesimulator_archs:
|
||||
iphonesimulator_archs = args.iphonesimulator_archs.split(',')
|
||||
elif not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
iphonesimulator_archs = ["x86_64"]
|
||||
print('Using iPhoneSimulator ARCHS=' + str(iphonesimulator_archs))
|
||||
|
||||
# Prevent the build from happening if the same architecture is specified for multiple platforms.
|
||||
# When `lipo` is run to stitch the frameworks together into a fat framework, it'll fail, so it's
|
||||
# better to stop here while we're ahead.
|
||||
if iphoneos_archs and iphonesimulator_archs:
|
||||
duplicate_archs = set(iphoneos_archs).intersection(iphonesimulator_archs)
|
||||
if duplicate_archs:
|
||||
print_error("Cannot have the same architecture for multiple platforms in a fat framework! Consider using build_xcframework.py in the apple platform folder instead. Duplicate archs are %s" % duplicate_archs)
|
||||
exit(1)
|
||||
|
||||
if args.legacy_build:
|
||||
args.framework_name = "opencv2"
|
||||
if not "objc" in args.without:
|
||||
args.without.append("objc")
|
||||
|
||||
targets = []
|
||||
if os.environ.get('BUILD_PRECOMMIT', None):
|
||||
if not iphoneos_archs:
|
||||
print_error("--iphoneos_archs must have at least one value")
|
||||
sys.exit(1)
|
||||
targets.append((iphoneos_archs, "iPhoneOS"))
|
||||
else:
|
||||
if not iphoneos_archs and not iphonesimulator_archs:
|
||||
print_error("--iphoneos_archs and --iphonesimulator_archs are undefined; nothing will be built.")
|
||||
sys.exit(1)
|
||||
if iphoneos_archs:
|
||||
targets.append((iphoneos_archs, "iPhoneOS"))
|
||||
if iphonesimulator_archs:
|
||||
targets.append((iphonesimulator_archs, "iPhoneSimulator"))
|
||||
|
||||
b = iOSBuilder(args.opencv, args.contrib, args.dynamic, args.without, args.disable, args.enablenonfree, targets, args.debug, args.debug_info, args.framework_name, args.run_tests, args.hosting_base_path, args.swiftdisabled)
|
||||
|
||||
b.build(args.out)
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
The script builds OpenCV.framework for visionOS.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import os, os.path, sys, argparse, traceback, multiprocessing
|
||||
|
||||
# import common code
|
||||
# sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios'))
|
||||
from build_framework import Builder
|
||||
sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../apple'))
|
||||
from cv_build_utils import print_error, get_cmake_version
|
||||
|
||||
XROS_DEPLOYMENT_TARGET='1.0' # default, can be changed via command line options or environment variable
|
||||
|
||||
class visionOSBuilder(Builder):
|
||||
|
||||
def checkCMakeVersion(self):
|
||||
assert get_cmake_version() >= (3, 17), "CMake 3.17 or later is required. Current version is {}".format(get_cmake_version())
|
||||
|
||||
def getObjcTarget(self, target):
|
||||
return 'visionos'
|
||||
|
||||
def getToolchain(self, arch, target):
|
||||
toolchain = os.path.join(self.opencv, "platforms", "ios", "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % target)
|
||||
return toolchain
|
||||
|
||||
def getCMakeArgs(self, arch, target):
|
||||
args = Builder.getCMakeArgs(self, arch, target)
|
||||
args = args + [
|
||||
'-DVISIONOS_ARCH=%s' % arch
|
||||
]
|
||||
return args
|
||||
|
||||
def getBuildCommand(self, arch, target):
|
||||
buildcmd = [
|
||||
"xcodebuild",
|
||||
"XROS_DEPLOYMENT_TARGET=" + os.environ['XROS_DEPLOYMENT_TARGET'],
|
||||
"ARCHS=%s" % arch,
|
||||
"-sdk", target.lower(),
|
||||
"-configuration", "Debug" if self.debug else "Release",
|
||||
"-parallelizeTargets",
|
||||
"-jobs", str(multiprocessing.cpu_count())
|
||||
]
|
||||
|
||||
return buildcmd
|
||||
|
||||
def getInfoPlist(self, builddirs):
|
||||
return os.path.join(builddirs[0], "visionos", "Info.plist")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
folder = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
|
||||
parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for visionOS.')
|
||||
# TODO: When we can make breaking changes, we should make the out argument explicit and required like in build_xcframework.py.
|
||||
parser.add_argument('out', metavar='OUTDIR', help='folder to put built framework')
|
||||
parser.add_argument('--opencv', metavar='DIR', default=folder, help='folder with opencv repository (default is "../.." relative to script location)')
|
||||
parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
|
||||
parser.add_argument('--without', metavar='MODULE', default=[], action='append', help='OpenCV modules to exclude from the framework. To exclude multiple, specify this flag again, e.g. "--without video --without objc"')
|
||||
parser.add_argument('--disable', metavar='FEATURE', default=[], action='append', help='OpenCV features to disable (add WITH_*=OFF). To disable multiple, specify this flag again, e.g. "--disable tbb --disable openmp"')
|
||||
parser.add_argument('--dynamic', default=False, action='store_true', help='build dynamic framework (default is "False" - builds static framework)')
|
||||
parser.add_argument('--enable_nonfree', default=False, dest='enablenonfree', action='store_true', help='enable non-free modules (disabled by default)')
|
||||
parser.add_argument('--visionos_deployment_target', default=os.environ.get('XROS_DEPLOYMENT_TARGET', XROS_DEPLOYMENT_TARGET), help='specify XROS_DEPLOYMENT_TARGET')
|
||||
parser.add_argument('--visionos_archs', default=None, help='select visionOS target ARCHS. Default is none')
|
||||
parser.add_argument('--visionsimulator_archs', default=None, help='select visionSimulator target ARCHS. Default is none')
|
||||
parser.add_argument('--debug', action='store_true', help='Build "Debug" binaries (CMAKE_BUILD_TYPE=Debug)')
|
||||
parser.add_argument('--debug_info', action='store_true', help='Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)')
|
||||
parser.add_argument('--framework_name', default='opencv2', dest='framework_name', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
|
||||
parser.add_argument('--legacy_build', default=False, dest='legacy_build', action='store_true', help='Build legacy framework (default: False, equivalent to "--framework_name=opencv2 --without=objc")')
|
||||
parser.add_argument('--run_tests', default=False, dest='run_tests', action='store_true', help='Run tests')
|
||||
parser.add_argument('--doc_hosting_base_path', default=None, dest='hosting_base_path', action='store_true', help='Documentation hosting base path')
|
||||
parser.add_argument('--disable-swift', default=False, dest='swiftdisabled', action='store_true', help='Disable building of Swift extensions')
|
||||
|
||||
args, unknown_args = parser.parse_known_args()
|
||||
if unknown_args:
|
||||
print("The following args are not recognized and will not be used: %s" % unknown_args)
|
||||
|
||||
os.environ['XROS_DEPLOYMENT_TARGET'] = args.visionos_deployment_target
|
||||
print('Using XROS_DEPLOYMENT_TARGET=' + os.environ['XROS_DEPLOYMENT_TARGET'])
|
||||
|
||||
visionos_archs = None
|
||||
if args.visionos_archs:
|
||||
visionos_archs = args.visionos_archs.split(',')
|
||||
print('Using visionOS ARCHS=' + str(visionos_archs))
|
||||
|
||||
visionsimulator_archs = None
|
||||
if args.visionsimulator_archs:
|
||||
visionsimulator_archs = args.visionsimulator_archs.split(',')
|
||||
print('Using visionOS ARCHS=' + str(visionsimulator_archs))
|
||||
|
||||
# Prevent the build from happening if the same architecture is specified for multiple platforms.
|
||||
# When `lipo` is run to stitch the frameworks together into a fat framework, it'll fail, so it's
|
||||
# better to stop here while we're ahead.
|
||||
if visionos_archs and visionsimulator_archs:
|
||||
duplicate_archs = set(visionos_archs).intersection(visionsimulator_archs)
|
||||
if duplicate_archs:
|
||||
print_error("Cannot have the same architecture for multiple platforms in a fat framework! Consider using build_xcframework.py in the apple platform folder instead. Duplicate archs are %s" % duplicate_archs)
|
||||
exit(1)
|
||||
|
||||
if args.legacy_build:
|
||||
args.framework_name = "opencv2"
|
||||
if not "objc" in args.without:
|
||||
args.without.append("objc")
|
||||
|
||||
targets = []
|
||||
if not visionos_archs and not visionsimulator_archs:
|
||||
print_error("--visionos_archs and --visionsimulator_archs are undefined; nothing will be built.")
|
||||
sys.exit(1)
|
||||
if visionos_archs:
|
||||
targets.append((visionos_archs, "XROS"))
|
||||
if visionsimulator_archs:
|
||||
targets.append((visionsimulator_archs, "XRSimulator")),
|
||||
|
||||
b = visionOSBuilder(args.opencv, args.contrib, args.dynamic, args.without, args.disable, args.enablenonfree, targets, args.debug, args.debug_info, args.framework_name, args.run_tests, args.hosting_base_path, args.swiftdisabled)
|
||||
b.build(args.out)
|
||||
@@ -0,0 +1,174 @@
|
||||
# This file is based off of the Platform/Darwin.cmake and Platform/UnixPaths.cmake
|
||||
# files which are included with CMake 2.8.4
|
||||
# It has been altered for iOS development
|
||||
set (UNIX 1)
|
||||
set (APPLE 1)
|
||||
set (IOS 1)
|
||||
|
||||
# Darwin versions:
|
||||
# 6.x == Mac OSX 10.2
|
||||
# 7.x == Mac OSX 10.3
|
||||
# 8.x == Mac OSX 10.4
|
||||
# 9.x == Mac OSX 10.5
|
||||
# 10.x == Mac OSX 10.6 (Snow Leopard)
|
||||
string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_SYSTEM_VERSION}")
|
||||
string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\2" DARWIN_MINOR_VERSION "${CMAKE_SYSTEM_VERSION}")
|
||||
|
||||
# Do not use the "-Wl,-search_paths_first" flag with the OSX 10.2 compiler.
|
||||
# Done this way because it is too early to do a TRY_COMPILE.
|
||||
if (NOT DEFINED HAVE_FLAG_SEARCH_PATHS_FIRST)
|
||||
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
|
||||
if ("${DARWIN_MAJOR_VERSION}" GREATER 6)
|
||||
set (HAVE_FLAG_SEARCH_PATHS_FIRST 1)
|
||||
endif ("${DARWIN_MAJOR_VERSION}" GREATER 6)
|
||||
endif (NOT DEFINED HAVE_FLAG_SEARCH_PATHS_FIRST)
|
||||
# More desirable, but does not work:
|
||||
#INCLUDE(CheckCXXCompilerFlag)
|
||||
#CHECK_CXX_COMPILER_FLAG("-Wl,-search_paths_first" HAVE_FLAG_SEARCH_PATHS_FIRST)
|
||||
|
||||
set (CMAKE_SHARED_LIBRARY_PREFIX "lib")
|
||||
set (CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
|
||||
set (CMAKE_SHARED_MODULE_PREFIX "lib")
|
||||
set (CMAKE_SHARED_MODULE_SUFFIX ".so")
|
||||
set (CMAKE_MODULE_EXISTS 1)
|
||||
set (CMAKE_DL_LIBS "")
|
||||
|
||||
set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
|
||||
set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
|
||||
set (CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
|
||||
set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
|
||||
|
||||
# Additional flags for dynamic framework
|
||||
if (APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
|
||||
set (CMAKE_MODULE_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks")
|
||||
set (CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1)
|
||||
set (CMAKE_INSTALL_NAME_DIR "@rpath")
|
||||
endif()
|
||||
|
||||
# Hidden visibility is required for cxx on iOS
|
||||
set (no_warn "-Wno-unused-function -Wno-overloaded-virtual")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${no_warn}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fvisibility=hidden -fvisibility-inlines-hidden ${no_warn}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -ffast-math")
|
||||
if(NOT IOS_ARCH STREQUAL "armv7" AND NOT IOS_ARCH STREQUAL "armv7s")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
|
||||
endif()
|
||||
|
||||
if (HAVE_FLAG_SEARCH_PATHS_FIRST)
|
||||
set (CMAKE_C_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
|
||||
set (CMAKE_CXX_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
|
||||
endif (HAVE_FLAG_SEARCH_PATHS_FIRST)
|
||||
|
||||
set (CMAKE_PLATFORM_HAS_INSTALLNAME 1)
|
||||
set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names")
|
||||
set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names")
|
||||
set (CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
|
||||
set (CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
|
||||
|
||||
# hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree
|
||||
# (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache
|
||||
# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun)
|
||||
# hardcode CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did before, Alex
|
||||
if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
|
||||
find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool)
|
||||
endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
|
||||
|
||||
# Setup iOS developer location
|
||||
if (IPHONEOS)
|
||||
set (_CMAKE_IOS_DEVELOPER_ROOT "/Developer/Platforms/iPhoneOS.platform/Developer")
|
||||
else ()
|
||||
if (IPHONESIMULATOR)
|
||||
set (_CMAKE_IOS_DEVELOPER_ROOT "/Developer/Platforms/iPhoneSimulator.platform/Developer")
|
||||
endif ()
|
||||
endif ()
|
||||
# Find installed iOS SDKs
|
||||
file (GLOB _CMAKE_IOS_SDKS "${_CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*")
|
||||
|
||||
# Find and use the most recent iOS sdk
|
||||
if (_CMAKE_IOS_SDKS)
|
||||
list (SORT _CMAKE_IOS_SDKS)
|
||||
list (REVERSE _CMAKE_IOS_SDKS)
|
||||
list (GET _CMAKE_IOS_SDKS 0 _CMAKE_IOS_SDK_ROOT)
|
||||
|
||||
# Set the sysroot default to the most recent SDK
|
||||
set (CMAKE_OSX_SYSROOT ${_CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support")
|
||||
|
||||
# set the architecture for iOS - this env var sets armv6,armv7 and appears to be XCode's standard. The other found is ARCHS_UNIVERSAL_IPHONE_OS but that is armv7 only
|
||||
set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_BIT)" CACHE string "Build architecture for iOS")
|
||||
|
||||
# Set the default based on this file and not the environment variable
|
||||
set (CMAKE_FIND_ROOT_PATH ${_CMAKE_IOS_DEVELOPER_ROOT} ${_CMAKE_IOS_SDK_ROOT} CACHE string "iOS library search path root")
|
||||
|
||||
# default to searching for frameworks first
|
||||
set (CMAKE_FIND_FRAMEWORK FIRST)
|
||||
|
||||
# set up the default search directories for frameworks
|
||||
set (CMAKE_SYSTEM_FRAMEWORK_PATH
|
||||
${_CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks
|
||||
${_CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks
|
||||
${_CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks
|
||||
)
|
||||
endif (_CMAKE_IOS_SDKS)
|
||||
|
||||
if ("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
|
||||
set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress")
|
||||
endif ("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
|
||||
|
||||
if (NOT XCODE)
|
||||
# Enable shared library versioning. This flag is not actually referenced
|
||||
# but the fact that the setting exists will cause the generators to support
|
||||
# soname computation.
|
||||
set (CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name")
|
||||
endif (NOT XCODE)
|
||||
|
||||
# Xcode does not support -isystem yet.
|
||||
if (XCODE)
|
||||
set (CMAKE_INCLUDE_SYSTEM_FLAG_C)
|
||||
set (CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
|
||||
endif (XCODE)
|
||||
|
||||
# Need to list dependent shared libraries on link line. When building
|
||||
# with -isysroot (for universal binaries), the linker always looks for
|
||||
# dependent libraries under the sysroot. Listing them on the link
|
||||
# line works around the problem.
|
||||
set (CMAKE_LINK_DEPENDENT_LIBRARY_FILES 1)
|
||||
|
||||
set (CMAKE_C_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
|
||||
set (CMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
|
||||
|
||||
set (CMAKE_C_CREATE_SHARED_LIBRARY
|
||||
"<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> -install_name <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
|
||||
set (CMAKE_CXX_CREATE_SHARED_LIBRARY
|
||||
"<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> -install_name <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
|
||||
|
||||
set (CMAKE_CXX_CREATE_SHARED_MODULE
|
||||
"<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
||||
|
||||
set (CMAKE_C_CREATE_SHARED_MODULE
|
||||
"<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
||||
|
||||
set (CMAKE_C_CREATE_MACOSX_FRAMEWORK
|
||||
"<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> -install_name <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
|
||||
set (CMAKE_CXX_CREATE_MACOSX_FRAMEWORK
|
||||
"<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> -install_name <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
|
||||
|
||||
# Add the install directory of the running cmake to the search directories
|
||||
# CMAKE_ROOT is CMAKE_INSTALL_PREFIX/share/cmake, so we need to go two levels up
|
||||
get_filename_component (_CMAKE_INSTALL_DIR "${CMAKE_ROOT}" PATH)
|
||||
get_filename_component (_CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" PATH)
|
||||
|
||||
# List common installation prefixes. These will be used for all search types
|
||||
list (APPEND CMAKE_SYSTEM_PREFIX_PATH
|
||||
# Standard
|
||||
${_CMAKE_IOS_DEVELOPER_ROOT}/usr
|
||||
${_CMAKE_IOS_SDK_ROOT}/usr
|
||||
|
||||
# CMake install location
|
||||
"${_CMAKE_INSTALL_DIR}"
|
||||
|
||||
# Project install destination.
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
set(MAC_CATALYST TRUE)
|
||||
message(STATUS "Setting up Catalyst toolchain for IOS_ARCH='${IOS_ARCH}'")
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
|
||||
message(STATUS "Catalyst toolchain loaded")
|
||||
@@ -0,0 +1,5 @@
|
||||
message(STATUS "Setting up visionOS toolchain for VISIONOS_ARCH='${VISIONOS_ARCH}'")
|
||||
set(VISIONOS TRUE)
|
||||
set(XROS 1)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
|
||||
message(STATUS "visionOS toolchain loaded")
|
||||
@@ -0,0 +1,5 @@
|
||||
message(STATUS "Setting up visionSimulator toolchain for VISIONOS_ARCH='${VISIONOS_ARCH}'")
|
||||
set(VISIONSIMULATOR TRUE)
|
||||
set(XROS 1)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
|
||||
message(STATUS "visionSimulator toolchain loaded")
|
||||
@@ -0,0 +1,4 @@
|
||||
message(STATUS "Setting up iPhoneOS toolchain for IOS_ARCH='${IOS_ARCH}'")
|
||||
set(IPHONEOS TRUE)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
|
||||
message(STATUS "iPhoneOS toolchain loaded")
|
||||
@@ -0,0 +1,4 @@
|
||||
message(STATUS "Setting up iPhoneSimulator toolchain for IOS_ARCH='${IOS_ARCH}'")
|
||||
set(IPHONESIMULATOR TRUE)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
|
||||
message(STATUS "iPhoneSimulator toolchain loaded")
|
||||
@@ -0,0 +1,223 @@
|
||||
# load settings in case of "try compile"
|
||||
set(TOOLCHAIN_CONFIG_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain.config.cmake")
|
||||
get_property(__IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if(__IN_TRY_COMPILE)
|
||||
set(TOOLCHAIN_CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../toolchain.config.cmake")
|
||||
if(NOT EXISTS "${TOOLCHAIN_CONFIG_FILE}")
|
||||
# Hack for "try_compile" commands with other binary directory
|
||||
set(TOOLCHAIN_CONFIG_FILE "${CMAKE_PLATFORM_INFO_DIR}/../toolchain.config.cmake")
|
||||
if(NOT EXISTS "${TOOLCHAIN_CONFIG_FILE}")
|
||||
message(FATAL_ERROR "Current CMake version (${CMAKE_VERSION}) is not supported")
|
||||
endif()
|
||||
endif()
|
||||
include("${TOOLCHAIN_CONFIG_FILE}")
|
||||
macro(toolchain_save_config)
|
||||
# nothing
|
||||
endmacro()
|
||||
else()
|
||||
macro(toolchain_save_config)
|
||||
set(__config "#message(\"Load TOOLCHAIN config...\")\n")
|
||||
get_cmake_property(__variableNames VARIABLES)
|
||||
set(__vars_list ${ARGN})
|
||||
list(APPEND __vars_list
|
||||
${TOOLCHAIN_CONFIG_VARS}
|
||||
CMAKE_SYSTEM_NAME
|
||||
CMAKE_SYSTEM_VERSION
|
||||
CMAKE_SYSTEM_PROCESSOR
|
||||
CMAKE_C_COMPILER
|
||||
CMAKE_CXX_COMPILER
|
||||
CMAKE_C_FLAGS
|
||||
CMAKE_CXX_FLAGS
|
||||
CMAKE_SHARED_LINKER_FLAGS
|
||||
CMAKE_MODULE_LINKER_FLAGS
|
||||
CMAKE_EXE_LINKER_FLAGS
|
||||
CMAKE_SKIP_RPATH
|
||||
CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
foreach(__var ${__variableNames})
|
||||
foreach(_v ${__vars_list})
|
||||
if("x${__var}" STREQUAL "x${_v}")
|
||||
if(${__var} MATCHES " ")
|
||||
set(__config "${__config}set(${__var} \"${${__var}}\")\n")
|
||||
else()
|
||||
set(__config "${__config}set(${__var} ${${__var}})\n")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
if(EXISTS "${TOOLCHAIN_CONFIG_FILE}")
|
||||
file(READ "${TOOLCHAIN_CONFIG_FILE}" __config_old)
|
||||
endif()
|
||||
if("${__config_old}" STREQUAL "${__config}")
|
||||
# nothing
|
||||
else()
|
||||
#message("Update TOOLCHAIN config: ${__config}")
|
||||
file(WRITE "${TOOLCHAIN_CONFIG_FILE}" "${__config}")
|
||||
endif()
|
||||
unset(__config)
|
||||
unset(__config_old)
|
||||
unset(__vars_list)
|
||||
unset(__variableNames)
|
||||
endmacro()
|
||||
endif() # IN_TRY_COMPILE
|
||||
|
||||
if((IPHONEOS OR IPHONESIMULATOR) AND NOT DEFINED IOS_ARCH)
|
||||
message(FATAL_ERROR "iOS toolchain requires ARCH option for proper configuration of compiler flags")
|
||||
endif()
|
||||
if((VISIONOS OR VISIONSIMULATOR) AND NOT DEFINED VISIONOS_ARCH)
|
||||
message(FATAL_ERROR "visionOS toolchain requires ARCH option for proper configuration of compiler flags")
|
||||
endif()
|
||||
if((IOS_ARCH MATCHES "^arm64") OR (VISIONOS_ARCH MATCHES "^arm64"))
|
||||
set(AARCH64 1)
|
||||
elseif(IOS_ARCH MATCHES "^armv")
|
||||
set(ARM 1)
|
||||
elseif((IOS_ARCH MATCHES "^x86_64") OR (VISIONOS_ARCH MATCHES "^x86_64"))
|
||||
set(X86_64 1)
|
||||
elseif(IOS_ARCH MATCHES "^i386")
|
||||
set(X86 1)
|
||||
else()
|
||||
if(IPHONEOS OR IPHONESIMULATOR)
|
||||
message(FATAL_ERROR "invalid value of IOS_ARCH='${IOS_ARCH}'")
|
||||
elseif(VISIONOS OR VISIONSIMULATOR)
|
||||
message(FATAL_ERROR "invalid value of VISIONOS_ARCH='${VISIONOS_ARCH}'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_OSX_SYSROOT)
|
||||
if(IPHONEOS)
|
||||
set(CMAKE_OSX_SYSROOT "iphoneos")
|
||||
set(SYSTEM "iOS")
|
||||
set(ARCH "${IOS_ARCH}")
|
||||
elseif(IPHONESIMULATOR)
|
||||
set(CMAKE_OSX_SYSROOT "iphonesimulator")
|
||||
set(SYSTEM "iOS")
|
||||
set(ARCH "${IOS_ARCH}")
|
||||
elseif(VISIONOS)
|
||||
set(CMAKE_OSX_SYSROOT "xros")
|
||||
set(SYSTEM "visionOS")
|
||||
set(ARCH "${VISIONOS_ARCH}")
|
||||
elseif(VISIONSIMULATOR)
|
||||
set(CMAKE_OSX_SYSROOT "xrsimulator")
|
||||
set(SYSTEM "visionOS")
|
||||
set(ARCH "${VISIONOS_ARCH}")
|
||||
elseif(MAC_CATALYST)
|
||||
# Use MacOS SDK for Catalyst builds
|
||||
set(CMAKE_OSX_SYSROOT "macosx")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_MACOSX_BUNDLE YES)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
|
||||
|
||||
if(APPLE_FRAMEWORK AND NOT BUILD_SHARED_LIBS)
|
||||
set(CMAKE_OSX_ARCHITECTURES "${ARCH}" CACHE INTERNAL "Build architecture for iOS/visionOS" FORCE)
|
||||
endif()
|
||||
|
||||
if((IPHONEOS OR IPHONESIMULATOR) AND NOT DEFINED IPHONEOS_DEPLOYMENT_TARGET)
|
||||
if(NOT DEFINED ENV{IPHONEOS_DEPLOYMENT_TARGET})
|
||||
message(FATAL_ERROR "IPHONEOS_DEPLOYMENT_TARGET is not specified")
|
||||
endif()
|
||||
set(IPHONEOS_DEPLOYMENT_TARGET "$ENV{IPHONEOS_DEPLOYMENT_TARGET}")
|
||||
set(DEPLOYMENT_TARGET "${IPHONEOS_DEPLOYMENT_TARGET}")
|
||||
set(DEPLOYMENT_TARGET_CMDLINE "IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
if((VISIONOS OR VISIONSIMULATOR) AND NOT DEFINED XROS_DEPLOYMENT_TARGET)
|
||||
if(NOT DEFINED ENV{XROS_DEPLOYMENT_TARGET})
|
||||
message(FATAL_ERROR "XROS_DEPLOYMENT_TARGET is not specified")
|
||||
endif()
|
||||
set(XROS_DEPLOYMENT_TARGET "$ENV{XROS_DEPLOYMENT_TARGET}")
|
||||
set(DEPLOYMENT_TARGET "${XROS_DEPLOYMENT_TARGET}")
|
||||
set(DEPLOYMENT_TARGET_CMDLINE "XROS_DEPLOYMENT_TARGET=${XROS_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
if(NOT __IN_TRY_COMPILE)
|
||||
set(_xcodebuild_wrapper "")
|
||||
if(NOT (CMAKE_VERSION VERSION_LESS "3.25.1")) # >= 3.25.1
|
||||
# no workaround is required (#23156)
|
||||
elseif(NOT (CMAKE_VERSION VERSION_LESS "3.25.0")) # >= 3.25.0 < 3.25.1
|
||||
if(NOT OPENCV_SKIP_MESSAGE_ISSUE_23156)
|
||||
message(FATAL_ERROR "OpenCV: Please upgrade CMake to 3.25.1+. Current CMake version is ${CMAKE_VERSION}. Details: https://github.com/opencv/opencv/issues/23156")
|
||||
endif()
|
||||
else() # < 3.25.0, apply workaround from #13912
|
||||
set(_xcodebuild_wrapper "${CMAKE_BINARY_DIR}/xcodebuild_wrapper")
|
||||
endif()
|
||||
if(_xcodebuild_wrapper AND NOT EXISTS "${_xcodebuild_wrapper}")
|
||||
set(_xcodebuild_wrapper_tmp "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/xcodebuild_wrapper")
|
||||
if(NOT DEFINED CMAKE_MAKE_PROGRAM) # empty since CMake 3.10
|
||||
find_program(XCODEBUILD_PATH "xcodebuild")
|
||||
if(NOT XCODEBUILD_PATH)
|
||||
message(FATAL_ERROR "Specify CMAKE_MAKE_PROGRAM variable ('xcodebuild' absolute path)")
|
||||
endif()
|
||||
set(CMAKE_MAKE_PROGRAM "${XCODEBUILD_PATH}")
|
||||
endif()
|
||||
if(CMAKE_MAKE_PROGRAM STREQUAL _xcodebuild_wrapper)
|
||||
message(FATAL_ERROR "Can't prepare xcodebuild_wrapper")
|
||||
endif()
|
||||
if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
|
||||
set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} ${DEPLOYMENT_TARGET_CMDLINE} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO -sdk ${CMAKE_OSX_SYSROOT}")
|
||||
else()
|
||||
set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} ${DEPLOYMENT_TARGET_CMDLINE} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO ARCHS=${ARCH} -sdk ${CMAKE_OSX_SYSROOT}")
|
||||
endif()
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/xcodebuild_wrapper.in" "${_xcodebuild_wrapper_tmp}" @ONLY)
|
||||
file(COPY "${_xcodebuild_wrapper_tmp}" DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
endif()
|
||||
if(_xcodebuild_wrapper)
|
||||
set(CMAKE_MAKE_PROGRAM "${_xcodebuild_wrapper}" CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Standard settings
|
||||
set(CMAKE_SYSTEM_NAME "${SYSTEM}")
|
||||
|
||||
# Apple Framework settings
|
||||
if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
|
||||
set(CMAKE_SYSTEM_VERSION "${DEPLOYMENT_TARGET}")
|
||||
set(CMAKE_C_SIZEOF_DATA_PTR 4)
|
||||
set(CMAKE_CXX_SIZEOF_DATA_PTR 4)
|
||||
else()
|
||||
set(CMAKE_SYSTEM_VERSION "${DEPLOYMENT_TARGET}")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "${ARCH}")
|
||||
|
||||
if(AARCH64 OR X86_64)
|
||||
set(CMAKE_C_SIZEOF_DATA_PTR 8)
|
||||
set(CMAKE_CXX_SIZEOF_DATA_PTR 8)
|
||||
else()
|
||||
set(CMAKE_C_SIZEOF_DATA_PTR 4)
|
||||
set(CMAKE_CXX_SIZEOF_DATA_PTR 4)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Include extra modules for the iOS platform files
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/cmake/Modules")
|
||||
|
||||
# Force the compilers to clang for iOS
|
||||
include(CMakeForceCompiler)
|
||||
#CMAKE_FORCE_C_COMPILER (clang GNU)
|
||||
#CMAKE_FORCE_CXX_COMPILER (clang++ GNU)
|
||||
|
||||
set(CMAKE_C_HAS_ISYSROOT 1)
|
||||
set(CMAKE_CXX_HAS_ISYSROOT 1)
|
||||
set(CMAKE_C_COMPILER_ABI ELF)
|
||||
set(CMAKE_CXX_COMPILER_ABI ELF)
|
||||
|
||||
# Skip the platform compiler checks for cross compiling
|
||||
set(CMAKE_CXX_COMPILER_WORKS TRUE)
|
||||
set(CMAKE_C_COMPILER_WORKS TRUE)
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
endif()
|
||||
|
||||
toolchain_save_config(IOS_ARCH VISIONOS_ARCH ARCH DEPLOYMENT_TARGET)
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Force 'Debug' configuration
|
||||
# Details: https://github.com/opencv/opencv/issues/13856
|
||||
if [[ "$@" =~ "-project CMAKE_TRY_COMPILE.xcodeproj" && -z "${OPENCV_SKIP_XCODEBUILD_FORCE_TRYCOMPILE_DEBUG}" ]]; then
|
||||
ARGS=()
|
||||
for ((i=1; i<=$#; i++))
|
||||
do
|
||||
arg=${!i}
|
||||
ARGS+=("$arg")
|
||||
if [[ "$arg" == "-configuration" ]]; then
|
||||
ARGS+=("Debug")
|
||||
i=$(($i+1))
|
||||
fi
|
||||
done
|
||||
set -- "${ARGS[@]}"
|
||||
fi
|
||||
|
||||
@CMAKE_MAKE_PROGRAM@ @XCODEBUILD_EXTRA_ARGS@ $*
|
||||
@@ -0,0 +1,7 @@
|
||||
Building OpenCV from Source, using CMake and Command Line
|
||||
=========================================================
|
||||
|
||||
cd ~/<my_working_directory>
|
||||
python3 opencv/platforms/ios/build_framework.py ios
|
||||
|
||||
If everything's fine, a few minutes later you will get ~/<my_working_directory>/ios/opencv2.framework. You can add this framework to your Xcode projects.
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This script runs OpenCV.framework tests for iOS.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import glob, re, os, os.path, shutil, string, sys, argparse, traceback, multiprocessing
|
||||
from subprocess import check_call, check_output, CalledProcessError
|
||||
|
||||
IPHONEOS_DEPLOYMENT_TARGET='11.0' # default, can be changed via command line options or environment variable
|
||||
|
||||
def execute(cmd, cwd = None):
|
||||
print("Executing: %s in %s" % (cmd, cwd), file=sys.stderr)
|
||||
print('Executing: ' + ' '.join(cmd))
|
||||
retcode = check_call(cmd, cwd = cwd)
|
||||
if retcode != 0:
|
||||
raise Exception("Child returned:", retcode)
|
||||
|
||||
class TestRunner:
|
||||
def __init__(self, script_dir, tests_dir, build_dir, framework_dir, framework_name, arch, target, platform):
|
||||
self.script_dir = script_dir
|
||||
self.tests_dir = tests_dir
|
||||
self.build_dir = build_dir
|
||||
self.framework_dir = framework_dir
|
||||
self.framework_name = framework_name
|
||||
self.arch = arch
|
||||
self.target = target
|
||||
self.platform = platform
|
||||
|
||||
def _run(self):
|
||||
if not os.path.isdir(self.build_dir):
|
||||
os.makedirs(self.build_dir)
|
||||
|
||||
self.runTest()
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self._run()
|
||||
except Exception as e:
|
||||
print("="*60, file=sys.stderr)
|
||||
print("ERROR: %s" % e, file=sys.stderr)
|
||||
print("="*60, file=sys.stderr)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def getToolchain(self):
|
||||
return None
|
||||
|
||||
def getCMakeArgs(self):
|
||||
args = [
|
||||
"cmake",
|
||||
"-GXcode",
|
||||
"-DFRAMEWORK_DIR=%s" % self.framework_dir,
|
||||
"-DFRAMEWORK_NAME=%s" % self.framework_name,
|
||||
]
|
||||
return args
|
||||
|
||||
def makeCMakeCmd(self):
|
||||
toolchain = self.getToolchain()
|
||||
cmakecmd = self.getCMakeArgs() + \
|
||||
(["-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain] if toolchain is not None else []) + \
|
||||
["-DCMAKE_INSTALL_NAME_TOOL=install_name_tool"]
|
||||
cmakecmd.append(self.tests_dir)
|
||||
return cmakecmd
|
||||
|
||||
def runTest(self):
|
||||
cmakecmd = self.makeCMakeCmd()
|
||||
execute(cmakecmd, cwd = self.build_dir)
|
||||
buildcmd = self.getTestCommand()
|
||||
execute(buildcmd, cwd = self.build_dir)
|
||||
|
||||
def getTestCommand(self):
|
||||
testcmd = [
|
||||
"xcodebuild",
|
||||
"test",
|
||||
"-project", "OpenCVTest.xcodeproj",
|
||||
"-scheme", "OpenCVTestTests",
|
||||
"-destination", "platform=%s" % self.platform
|
||||
]
|
||||
return testcmd
|
||||
|
||||
class iOSTestRunner(TestRunner):
|
||||
|
||||
def getToolchain(self):
|
||||
toolchain = os.path.join(self.script_dir, "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % self.target)
|
||||
return toolchain
|
||||
|
||||
def getCMakeArgs(self):
|
||||
args = TestRunner.getCMakeArgs(self)
|
||||
args = args + [
|
||||
"-DIOS_ARCH=%s" % self.arch,
|
||||
"-DIPHONEOS_DEPLOYMENT_TARGET=%s" % os.environ['IPHONEOS_DEPLOYMENT_TARGET'],
|
||||
]
|
||||
return args
|
||||
|
||||
if __name__ == "__main__":
|
||||
script_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for iOS.')
|
||||
parser.add_argument('tests_dir', metavar='TEST_DIR', help='folder where test files are located')
|
||||
parser.add_argument('--build_dir', default=None, help='folder where test will be built (default is "../test_build" relative to tests_dir)')
|
||||
parser.add_argument('--framework_dir', default=None, help='folder where OpenCV framework is located')
|
||||
parser.add_argument('--framework_name', default='opencv2', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
|
||||
parser.add_argument('--iphoneos_deployment_target', default=os.environ.get('IPHONEOS_DEPLOYMENT_TARGET', IPHONEOS_DEPLOYMENT_TARGET), help='specify IPHONEOS_DEPLOYMENT_TARGET')
|
||||
parser.add_argument('--platform', default='iOS Simulator,name=iPhone 11', help='xcodebuild platform parameter (default is iOS 11 simulator)')
|
||||
args = parser.parse_args()
|
||||
|
||||
os.environ['IPHONEOS_DEPLOYMENT_TARGET'] = args.iphoneos_deployment_target
|
||||
print('Using IPHONEOS_DEPLOYMENT_TARGET=' + os.environ['IPHONEOS_DEPLOYMENT_TARGET'])
|
||||
arch = "x86_64"
|
||||
target = "iPhoneSimulator"
|
||||
print('Using iPhoneSimulator ARCH=' + arch)
|
||||
|
||||
r = iOSTestRunner(script_dir, args.tests_dir, args.build_dir if args.build_dir else os.path.join(args.tests_dir, "../test_build"), args.framework_dir, args.framework_name, arch, target, args.platform)
|
||||
r.run()
|
||||
@@ -0,0 +1,15 @@
|
||||
Building OpenCV.js by Emscripten
|
||||
====================
|
||||
|
||||
[Download and install Emscripten](https://emscripten.org/docs/getting_started/downloads.html).
|
||||
|
||||
Execute `build_js.py` script:
|
||||
```
|
||||
emcmake python <opencv_src_dir>/platforms/js/build_js.py <build_dir>
|
||||
```
|
||||
|
||||
If everything is fine, a few minutes later you will get `<build_dir>/bin/opencv.js`. You can add this into your web pages.
|
||||
|
||||
Find out more build options by `-h` switch.
|
||||
|
||||
For detailed build tutorial, check out `<opencv_src_dir>/doc/js_tutorials/js_setup/js_setup/js_setup.markdown`.
|
||||
Executable
+362
@@ -0,0 +1,362 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os, sys, subprocess, argparse, shutil, glob, re, multiprocessing
|
||||
import logging as log
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
class Fail(Exception):
|
||||
def __init__(self, text=None):
|
||||
self.t = text
|
||||
def __str__(self):
|
||||
return "ERROR" if self.t is None else self.t
|
||||
|
||||
def execute(cmd, shell=False):
|
||||
try:
|
||||
log.info("Executing: %s" % cmd)
|
||||
env = os.environ.copy()
|
||||
env['VERBOSE'] = '1'
|
||||
retcode = subprocess.call(cmd, shell=shell, env=env)
|
||||
if retcode < 0:
|
||||
raise Fail("Child was terminated by signal: %s" % -retcode)
|
||||
elif retcode > 0:
|
||||
raise Fail("Child returned: %s" % retcode)
|
||||
except OSError as e:
|
||||
raise Fail("Execution failed: %d / %s" % (e.errno, e.strerror))
|
||||
|
||||
def rm_one(d):
|
||||
d = os.path.abspath(d)
|
||||
if os.path.exists(d):
|
||||
if os.path.isdir(d):
|
||||
log.info("Removing dir: %s", d)
|
||||
shutil.rmtree(d)
|
||||
elif os.path.isfile(d):
|
||||
log.info("Removing file: %s", d)
|
||||
os.remove(d)
|
||||
|
||||
def check_dir(d, create=False, clean=False):
|
||||
d = os.path.abspath(d)
|
||||
log.info("Check dir %s (create: %s, clean: %s)", d, create, clean)
|
||||
if os.path.exists(d):
|
||||
if not os.path.isdir(d):
|
||||
raise Fail("Not a directory: %s" % d)
|
||||
if clean:
|
||||
for x in glob.glob(os.path.join(d, "*")):
|
||||
rm_one(x)
|
||||
else:
|
||||
if create:
|
||||
os.makedirs(d)
|
||||
return d
|
||||
|
||||
def check_file(d):
|
||||
d = os.path.abspath(d)
|
||||
if os.path.exists(d):
|
||||
if os.path.isfile(d):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
def find_file(name, path):
|
||||
for root, dirs, files in os.walk(path):
|
||||
if name in files:
|
||||
return os.path.join(root, name)
|
||||
|
||||
class Builder:
|
||||
def __init__(self, options):
|
||||
self.options = options
|
||||
self.build_dir = check_dir(options.build_dir, create=True)
|
||||
self.opencv_dir = check_dir(options.opencv_dir)
|
||||
print('-----------------------------------------------------------')
|
||||
print('options.opencv_dir:', options.opencv_dir)
|
||||
self.emscripten_dir = check_dir(options.emscripten_dir)
|
||||
|
||||
def get_toolchain_file(self):
|
||||
return os.path.join(self.emscripten_dir, "cmake", "Modules", "Platform", "Emscripten.cmake")
|
||||
|
||||
def clean_build_dir(self):
|
||||
for d in ["CMakeCache.txt", "CMakeFiles/", "bin/", "libs/", "lib/", "modules"]:
|
||||
rm_one(d)
|
||||
|
||||
def get_cmake_cmd(self):
|
||||
cmd = [
|
||||
"cmake",
|
||||
"-DPYTHON_DEFAULT_EXECUTABLE=%s" % sys.executable,
|
||||
"-DENABLE_PIC=FALSE", # To workaround emscripten upstream backend issue https://github.com/emscripten-core/emscripten/issues/8761
|
||||
"-DCMAKE_BUILD_TYPE=Release",
|
||||
"-DCPU_BASELINE=''",
|
||||
"-DCMAKE_INSTALL_PREFIX=/usr/local",
|
||||
"-DCPU_DISPATCH=''",
|
||||
"-DCV_TRACE=OFF",
|
||||
"-DBUILD_SHARED_LIBS=OFF",
|
||||
"-DWITH_1394=OFF",
|
||||
"-DWITH_ADE=OFF",
|
||||
"-DWITH_VTK=OFF",
|
||||
"-DWITH_EIGEN=OFF",
|
||||
"-DWITH_FFMPEG=OFF",
|
||||
"-DWITH_GSTREAMER=OFF",
|
||||
"-DWITH_GTK=OFF",
|
||||
"-DWITH_GTK_2_X=OFF",
|
||||
"-DWITH_IPP=OFF",
|
||||
"-DWITH_AVIF=OFF",
|
||||
"-DWITH_JASPER=OFF",
|
||||
"-DWITH_JPEG=OFF",
|
||||
"-DWITH_WEBP=OFF",
|
||||
"-DWITH_OPENEXR=OFF",
|
||||
"-DWITH_OPENJPEG=OFF",
|
||||
"-DWITH_OPENGL=OFF",
|
||||
"-DWITH_OPENNI=OFF",
|
||||
"-DWITH_OPENNI2=OFF",
|
||||
"-DWITH_PNG=OFF",
|
||||
"-DWITH_TBB=OFF",
|
||||
"-DWITH_TIFF=OFF",
|
||||
"-DWITH_V4L=OFF",
|
||||
"-DWITH_OPENCL=OFF",
|
||||
"-DWITH_OPENCL_SVM=OFF",
|
||||
"-DWITH_OPENCLAMDFFT=OFF",
|
||||
"-DWITH_OPENCLAMDBLAS=OFF",
|
||||
"-DWITH_GPHOTO2=OFF",
|
||||
"-DWITH_LAPACK=OFF",
|
||||
"-DWITH_ITT=OFF",
|
||||
"-DBUILD_ZLIB=ON",
|
||||
"-DBUILD_opencv_apps=OFF",
|
||||
"-DBUILD_opencv_3d=ON",
|
||||
"-DBUILD_opencv_dnn=ON",
|
||||
"-DBUILD_opencv_features=ON",
|
||||
"-DBUILD_opencv_flann=ON", # No bindings provided. This module is used as a dependency for other modules.
|
||||
"-DBUILD_opencv_gapi=OFF",
|
||||
"-DBUILD_opencv_ml=OFF",
|
||||
"-DBUILD_opencv_photo=ON",
|
||||
"-DBUILD_opencv_imgcodecs=OFF",
|
||||
"-DBUILD_opencv_shape=OFF",
|
||||
"-DBUILD_opencv_videoio=OFF",
|
||||
"-DBUILD_opencv_videostab=OFF",
|
||||
"-DBUILD_opencv_highgui=OFF",
|
||||
"-DBUILD_opencv_superres=OFF",
|
||||
"-DBUILD_opencv_stitching=OFF",
|
||||
"-DBUILD_opencv_java=OFF",
|
||||
"-DBUILD_opencv_js=ON",
|
||||
"-DBUILD_opencv_python3=OFF",
|
||||
"-DBUILD_EXAMPLES=ON",
|
||||
"-DBUILD_PACKAGE=OFF",
|
||||
"-DBUILD_TESTS=ON",
|
||||
"-DBUILD_PERF_TESTS=ON"]
|
||||
if self.options.cmake_option:
|
||||
cmd += self.options.cmake_option
|
||||
if not self.options.cmake_option or all(["-DCMAKE_TOOLCHAIN_FILE" not in opt for opt in self.options.cmake_option]):
|
||||
cmd.append("-DCMAKE_TOOLCHAIN_FILE='%s'" % self.get_toolchain_file())
|
||||
if self.options.build_doc:
|
||||
cmd.append("-DBUILD_DOCS=ON")
|
||||
else:
|
||||
cmd.append("-DBUILD_DOCS=OFF")
|
||||
|
||||
if self.options.threads:
|
||||
cmd.append("-DWITH_PTHREADS_PF=ON")
|
||||
else:
|
||||
cmd.append("-DWITH_PTHREADS_PF=OFF")
|
||||
|
||||
if self.options.simd:
|
||||
cmd.append("-DCV_ENABLE_INTRINSICS=ON")
|
||||
else:
|
||||
cmd.append("-DCV_ENABLE_INTRINSICS=OFF")
|
||||
|
||||
if self.options.build_wasm_intrin_test:
|
||||
cmd.append("-DBUILD_WASM_INTRIN_TESTS=ON")
|
||||
else:
|
||||
cmd.append("-DBUILD_WASM_INTRIN_TESTS=OFF")
|
||||
|
||||
if self.options.webnn:
|
||||
cmd.append("-DWITH_WEBNN=ON")
|
||||
|
||||
flags = self.get_build_flags()
|
||||
if flags:
|
||||
cmd += ["-DCMAKE_C_FLAGS='%s'" % flags,
|
||||
"-DCMAKE_CXX_FLAGS='%s'" % flags]
|
||||
|
||||
if self.options.extra_modules:
|
||||
cmd.append("-DOPENCV_EXTRA_MODULES_PATH='%s'" % self.options.extra_modules)
|
||||
|
||||
return cmd
|
||||
|
||||
def get_build_flags(self):
|
||||
flags = ""
|
||||
if self.options.build_wasm:
|
||||
flags += "-s WASM=1 "
|
||||
elif self.options.disable_wasm:
|
||||
flags += "-s WASM=0 "
|
||||
if not self.options.disable_single_file:
|
||||
flags += "-s SINGLE_FILE=1 "
|
||||
if self.options.threads:
|
||||
flags += "-s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=4 "
|
||||
else:
|
||||
flags += "-s USE_PTHREADS=0 "
|
||||
if self.options.enable_exception:
|
||||
flags += "-s DISABLE_EXCEPTION_CATCHING=0 "
|
||||
if self.options.simd:
|
||||
flags += "-msimd128 "
|
||||
if self.options.build_flags:
|
||||
flags += self.options.build_flags + " "
|
||||
if self.options.webnn:
|
||||
flags += "-s USE_WEBNN=1 "
|
||||
flags += "-s EXPORTED_FUNCTIONS=\"['_malloc', '_free']\""
|
||||
return flags
|
||||
|
||||
def config(self):
|
||||
cmd = self.get_cmake_cmd()
|
||||
cmd.append(self.opencv_dir)
|
||||
execute(cmd)
|
||||
|
||||
def build_opencvjs(self):
|
||||
execute(["make", "-j", str(multiprocessing.cpu_count()), "opencv.js"])
|
||||
|
||||
def build_test(self):
|
||||
execute(["make", "-j", str(multiprocessing.cpu_count()), "opencv_js_test"])
|
||||
|
||||
def build_perf(self):
|
||||
execute(["make", "-j", str(multiprocessing.cpu_count()), "opencv_js_perf"])
|
||||
|
||||
def build_doc(self):
|
||||
execute(["make", "-j", str(multiprocessing.cpu_count()), "doxygen"])
|
||||
|
||||
def build_loader(self):
|
||||
execute(["make", "-j", str(multiprocessing.cpu_count()), "opencv_js_loader"])
|
||||
|
||||
|
||||
#===================================================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
log.basicConfig(format='%(message)s', level=log.DEBUG)
|
||||
|
||||
opencv_dir = os.path.abspath(os.path.join(SCRIPT_DIR, '../..'))
|
||||
emscripten_dir = None
|
||||
if "EMSDK" in os.environ:
|
||||
emscripten_dir = os.path.join(os.environ["EMSDK"], "upstream", "emscripten")
|
||||
elif "EMSCRIPTEN" in os.environ:
|
||||
emscripten_dir = os.environ["EMSCRIPTEN"]
|
||||
else:
|
||||
log.warning("EMSCRIPTEN/EMSDK environment variable is not available. Please properly activate Emscripten SDK and consider using 'emcmake' launcher")
|
||||
|
||||
parser = argparse.ArgumentParser(description='Build OpenCV.js by Emscripten')
|
||||
parser.add_argument("build_dir", help="Building directory (and output)")
|
||||
parser.add_argument('--opencv_dir', default=opencv_dir, help='Opencv source directory (default is "../.." relative to script location)')
|
||||
parser.add_argument('--emscripten_dir', default=emscripten_dir, help="Path to Emscripten to use for build (deprecated in favor of 'emcmake' launcher)")
|
||||
parser.add_argument('--build_wasm', action="store_true", help="Build OpenCV.js in WebAssembly format")
|
||||
parser.add_argument('--disable_wasm', action="store_true", help="Build OpenCV.js in Asm.js format")
|
||||
parser.add_argument('--disable_single_file', action="store_true", help="Do not merge JavaScript and WebAssembly into one single file")
|
||||
parser.add_argument('--threads', action="store_true", help="Build OpenCV.js with threads optimization")
|
||||
parser.add_argument('--simd', action="store_true", help="Build OpenCV.js with SIMD optimization")
|
||||
parser.add_argument('--build_test', action="store_true", help="Build tests")
|
||||
parser.add_argument('--build_perf', action="store_true", help="Build performance tests")
|
||||
parser.add_argument('--build_doc', action="store_true", help="Build tutorials")
|
||||
parser.add_argument('--build_loader', action="store_true", help="Build OpenCV.js loader")
|
||||
parser.add_argument('--clean_build_dir', action="store_true", help="Clean build dir")
|
||||
parser.add_argument('--skip_config', action="store_true", help="Skip cmake config")
|
||||
parser.add_argument('--config_only', action="store_true", help="Only do cmake config")
|
||||
parser.add_argument('--enable_exception', action="store_true", help="Enable exception handling")
|
||||
# Use flag --cmake option="-D...=ON" only for one argument, if you would add more changes write new cmake_option flags
|
||||
parser.add_argument('--cmake_option', action='append', help="Append CMake options")
|
||||
# Use flag --build_flags="-s USE_PTHREADS=0 -Os" for one and more arguments as in the example
|
||||
parser.add_argument('--build_flags', help="Append Emscripten build options")
|
||||
parser.add_argument('--build_wasm_intrin_test', action="store_true", help="Build WASM intrin tests")
|
||||
# Write a path to modify file like argument of this flag
|
||||
parser.add_argument('--config', help="Specify configuration file with own list of exported into JS functions")
|
||||
parser.add_argument('--webnn', action="store_true", help="Enable WebNN Backend")
|
||||
parser.add_argument("--extra_modules", required=False, help="Path extra modules location (OPENCV_EXTRA_MODULES_PATH)")
|
||||
|
||||
|
||||
transformed_args = ["--cmake_option={}".format(arg) if arg[:2] == "-D" else arg for arg in sys.argv[1:]]
|
||||
args = parser.parse_args(transformed_args)
|
||||
|
||||
log.debug("Args: %s", args)
|
||||
|
||||
if args.config is not None:
|
||||
os.environ["OPENCV_JS_WHITELIST"] = os.path.abspath(args.config)
|
||||
|
||||
if 'EMMAKEN_JUST_CONFIGURE' in os.environ:
|
||||
del os.environ['EMMAKEN_JUST_CONFIGURE'] # avoid linker errors with NODERAWFS message then using 'emcmake' launcher
|
||||
|
||||
if args.emscripten_dir is None:
|
||||
log.error("Cannot get Emscripten path, please use 'emcmake' launcher or specify it either by EMSCRIPTEN/EMSDK environment variable or --emscripten_dir option.")
|
||||
sys.exit(-1)
|
||||
|
||||
builder = Builder(args)
|
||||
|
||||
os.chdir(builder.build_dir)
|
||||
|
||||
if args.clean_build_dir:
|
||||
log.info("=====")
|
||||
log.info("===== Clean build dir %s", builder.build_dir)
|
||||
log.info("=====")
|
||||
builder.clean_build_dir()
|
||||
|
||||
if not args.skip_config:
|
||||
target = "default target"
|
||||
if args.build_wasm:
|
||||
target = "wasm"
|
||||
elif args.disable_wasm:
|
||||
target = "asm.js"
|
||||
log.info("=====")
|
||||
log.info("===== Config OpenCV.js build for %s" % target)
|
||||
log.info("=====")
|
||||
builder.config()
|
||||
|
||||
if args.config_only:
|
||||
sys.exit(0)
|
||||
|
||||
log.info("=====")
|
||||
log.info("===== Building OpenCV.js")
|
||||
log.info("=====")
|
||||
builder.build_opencvjs()
|
||||
|
||||
if args.build_test:
|
||||
log.info("=====")
|
||||
log.info("===== Building OpenCV.js tests")
|
||||
log.info("=====")
|
||||
builder.build_test()
|
||||
|
||||
if args.build_perf:
|
||||
log.info("=====")
|
||||
log.info("===== Building OpenCV.js performance tests")
|
||||
log.info("=====")
|
||||
builder.build_perf()
|
||||
|
||||
if args.build_doc:
|
||||
log.info("=====")
|
||||
log.info("===== Building OpenCV.js tutorials")
|
||||
log.info("=====")
|
||||
builder.build_doc()
|
||||
|
||||
if args.build_loader:
|
||||
log.info("=====")
|
||||
log.info("===== Building OpenCV.js loader")
|
||||
log.info("=====")
|
||||
builder.build_loader()
|
||||
|
||||
log.info("=====")
|
||||
log.info("===== Build finished")
|
||||
log.info("=====")
|
||||
|
||||
opencvjs_path = os.path.join(builder.build_dir, "bin", "opencv.js")
|
||||
if check_file(opencvjs_path):
|
||||
log.info("OpenCV.js location: %s", opencvjs_path)
|
||||
|
||||
if args.build_test:
|
||||
opencvjs_test_path = os.path.join(builder.build_dir, "bin", "tests.html")
|
||||
if check_file(opencvjs_test_path):
|
||||
log.info("OpenCV.js tests location: %s", opencvjs_test_path)
|
||||
|
||||
if args.build_perf:
|
||||
opencvjs_perf_path = os.path.join(builder.build_dir, "bin", "perf")
|
||||
opencvjs_perf_base_path = os.path.join(builder.build_dir, "bin", "perf", "base.js")
|
||||
if check_file(opencvjs_perf_base_path):
|
||||
log.info("OpenCV.js performance tests location: %s", opencvjs_perf_path)
|
||||
|
||||
if args.build_doc:
|
||||
opencvjs_tutorial_path = find_file("tutorial_js_root.html", os.path.join(builder.build_dir, "doc", "doxygen", "html"))
|
||||
if check_file(opencvjs_tutorial_path):
|
||||
log.info("OpenCV.js tutorials location: %s", opencvjs_tutorial_path)
|
||||
|
||||
if args.build_loader:
|
||||
opencvjs_loader_path = os.path.join(builder.build_dir, "bin", "loader.js")
|
||||
if check_file(opencvjs_loader_path):
|
||||
log.info("OpenCV.js loader location: %s", opencvjs_loader_path)
|
||||
@@ -0,0 +1,241 @@
|
||||
# Classes and methods whitelist
|
||||
|
||||
core = {
|
||||
'': [
|
||||
'absdiff', 'add', 'addWeighted', 'bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'cartToPolar',
|
||||
'compare', 'convertScaleAbs', 'copyMakeBorder', 'countNonZero', 'determinant', 'dft', 'divide', 'divSpectrums', 'eigen',
|
||||
'exp', 'flip', 'getOptimalDFTSize','gemm', 'hconcat', 'inRange', 'invert', 'kmeans', 'log', 'magnitude',
|
||||
'max', 'mean', 'meanStdDev', 'merge', 'min', 'minMaxLoc', 'mixChannels', 'multiply', 'norm', 'normalize',
|
||||
'perspectiveTransform', 'polarToCart', 'pow', 'randn', 'randu', 'reduce', 'repeat', 'rotate', 'setIdentity', 'setRNGSeed',
|
||||
'solve', 'solvePoly', 'split', 'sqrt', 'subtract', 'trace', 'transform', 'transpose', 'vconcat',
|
||||
'setLogLevel', 'getLogLevel',
|
||||
'LUT',
|
||||
],
|
||||
'Algorithm': [],
|
||||
}
|
||||
|
||||
imgproc = {
|
||||
'': [
|
||||
'adaptiveThreshold',
|
||||
'applyColorMap',
|
||||
'approxPolyDP',
|
||||
'approxPolyN',
|
||||
'arcLength',
|
||||
'arrowedLine',
|
||||
'bilateralFilter',
|
||||
'blendLinear',
|
||||
'blur',
|
||||
'boundingRect',
|
||||
'boxFilter',
|
||||
'calcBackProject',
|
||||
'calcHist',
|
||||
'Canny',
|
||||
'circle',
|
||||
'clipLine',
|
||||
'compareHist',
|
||||
'connectedComponents',
|
||||
'connectedComponentsWithStats',
|
||||
'contourArea',
|
||||
'convertMaps',
|
||||
'convexHull',
|
||||
'convexityDefects',
|
||||
'cornerHarris',
|
||||
'cornerMinEigenVal',
|
||||
'createCLAHE',
|
||||
'createHanningWindow',
|
||||
'createLineSegmentDetector',
|
||||
'cvtColor',
|
||||
'demosaicing',
|
||||
'dilate',
|
||||
'distanceTransform',
|
||||
'distanceTransformWithLabels',
|
||||
'drawContours',
|
||||
'drawMarker',
|
||||
'ellipse',
|
||||
'ellipse2Poly',
|
||||
'equalizeHist',
|
||||
'erode',
|
||||
'fillConvexPoly',
|
||||
'fillPoly',
|
||||
'filter2D',
|
||||
'findContours',
|
||||
'findContoursLinkRuns',
|
||||
'fitEllipse',
|
||||
'fitEllipseAMS',
|
||||
'fitEllipseDirect',
|
||||
'fitLine',
|
||||
'floodFill',
|
||||
'GaussianBlur',
|
||||
'getAffineTransform',
|
||||
'getFontScaleFromHeight',
|
||||
'getPerspectiveTransform',
|
||||
'getRectSubPix',
|
||||
'getRotationMatrix2D',
|
||||
'getStructuringElement',
|
||||
'goodFeaturesToTrack',
|
||||
'grabCut',
|
||||
'HoughLines',
|
||||
'HoughLinesP',
|
||||
'HoughCircles',
|
||||
'HuMoments',
|
||||
'integral',
|
||||
'integral2',
|
||||
'intersectConvexConvex',
|
||||
'invertAffineTransform',
|
||||
'isContourConvex',
|
||||
'Laplacian',
|
||||
'line',
|
||||
'matchShapes',
|
||||
'matchTemplate',
|
||||
'medianBlur',
|
||||
'minAreaRect',
|
||||
'minEnclosingCircle',
|
||||
'minEnclosingTriangle',
|
||||
'moments',
|
||||
'morphologyEx',
|
||||
'pointPolygonTest',
|
||||
'polylines',
|
||||
'preCornerDetect',
|
||||
'putText',
|
||||
'pyrDown',
|
||||
'pyrUp',
|
||||
'rectangle',
|
||||
'remap',
|
||||
'resize',
|
||||
'rotatedRectangleIntersection',
|
||||
'Scharr',
|
||||
'sepFilter2D',
|
||||
'Sobel',
|
||||
'spatialGradient',
|
||||
'sqrBoxFilter',
|
||||
'stackBlur',
|
||||
'threshold',
|
||||
'warpAffine',
|
||||
'warpPerspective',
|
||||
'warpPolar',
|
||||
'watershed',
|
||||
],
|
||||
'CLAHE': ['apply', 'collectGarbage', 'getClipLimit', 'getTilesGridSize', 'setClipLimit', 'setTilesGridSize'],
|
||||
'segmentation_IntelligentScissorsMB': [
|
||||
'IntelligentScissorsMB',
|
||||
'setWeights',
|
||||
'setGradientMagnitudeMaxLimit',
|
||||
'setEdgeFeatureZeroCrossingParameters',
|
||||
'setEdgeFeatureCannyParameters',
|
||||
'applyImage',
|
||||
'applyImageFeatures',
|
||||
'buildMap',
|
||||
'getContour'
|
||||
],
|
||||
}
|
||||
|
||||
objdetect = {'': ['getPredefinedDictionary', 'extendDictionary',
|
||||
'drawDetectedMarkers', 'generateImageMarker', 'drawDetectedCornersCharuco',
|
||||
'drawDetectedDiamonds'],
|
||||
'GraphicalCodeDetector': ['decode', 'detect', 'detectAndDecode', 'detectMulti', 'decodeMulti', 'detectAndDecodeMulti'],
|
||||
'QRCodeDetector': ['QRCodeDetector', 'decode', 'detect', 'detectAndDecode', 'detectMulti', 'decodeMulti', 'detectAndDecodeMulti', 'decodeCurved', 'detectAndDecodeCurved', 'setEpsX', 'setEpsY'],
|
||||
'aruco_PredefinedDictionaryType': [],
|
||||
'aruco_Dictionary': ['Dictionary', 'getDistanceToId', 'generateImageMarker', 'getByteListFromBits', 'getBitsFromByteList'],
|
||||
'aruco_Board': ['Board', 'matchImagePoints', 'generateImage'],
|
||||
'aruco_GridBoard': ['GridBoard', 'generateImage', 'getGridSize', 'getMarkerLength', 'getMarkerSeparation', 'matchImagePoints'],
|
||||
'aruco_CharucoParameters': ['CharucoParameters'],
|
||||
'aruco_CharucoBoard': ['CharucoBoard', 'generateImage', 'getChessboardCorners', 'getNearestMarkerCorners', 'checkCharucoCornersCollinear', 'matchImagePoints', 'getLegacyPattern', 'setLegacyPattern'],
|
||||
'aruco_DetectorParameters': ['DetectorParameters'],
|
||||
'aruco_RefineParameters': ['RefineParameters'],
|
||||
'aruco_ArucoDetector': ['ArucoDetector', 'detectMarkers', 'refineDetectedMarkers', 'setDictionary', 'setDetectorParameters', 'setRefineParameters'],
|
||||
'aruco_CharucoDetector': ['CharucoDetector', 'setBoard', 'setCharucoParameters', 'setDetectorParameters', 'setRefineParameters', 'detectBoard', 'detectDiamonds'],
|
||||
'QRCodeDetectorAruco_Params': ['Params'],
|
||||
'QRCodeDetectorAruco': ['QRCodeDetectorAruco', 'decode', 'detect', 'detectAndDecode', 'detectMulti', 'decodeMulti', 'detectAndDecodeMulti', 'setDetectorParameters', 'setArucoParameters'],
|
||||
'barcode_BarcodeDetector': ['BarcodeDetector', 'decode', 'detect', 'detectAndDecode', 'detectMulti', 'decodeMulti', 'detectAndDecodeMulti', 'decodeWithType', 'detectAndDecodeWithType'],
|
||||
'mcc_CheckerDetector': ['process', 'getBestColorChecker', 'getListColorChecker', 'create', 'draw', 'getRefColors', 'setDetectionParams', 'getDetectionParams', 'setColorChartType', 'getColorChartType', 'setUseDnnModel', 'getUseDnnModel'],
|
||||
'mcc_DetectorParameters': ['DetectorParametersMCC'],
|
||||
'mcc_Checker': ['setTarget', 'setBox', 'setChartsRGB', 'setChartsYCbCr', 'setCost', 'setCenter', 'getTarget', 'getBox', 'getColorCharts', 'getChartsRGB', 'getChartsYCbCr', 'getCost', 'getCenter'],
|
||||
'FaceDetectorYN': ['setInputSize', 'getInputSize', 'setScoreThreshold', 'getScoreThreshold', 'setNMSThreshold', 'getNMSThreshold',
|
||||
'setTopK', 'getTopK', 'detect', 'create'],
|
||||
}
|
||||
|
||||
video = {
|
||||
'': [
|
||||
'CamShift',
|
||||
'calcOpticalFlowFarneback',
|
||||
'calcOpticalFlowPyrLK',
|
||||
'createBackgroundSubtractorMOG2',
|
||||
'findTransformECC',
|
||||
'meanShift',
|
||||
],
|
||||
'BackgroundSubtractorMOG2': ['BackgroundSubtractorMOG2', 'apply'],
|
||||
'BackgroundSubtractor': ['apply', 'getBackgroundImage'],
|
||||
# issue #21070: 'Tracker': ['init', 'update'],
|
||||
'TrackerMIL': ['create'],
|
||||
'TrackerMIL_Params': [],
|
||||
}
|
||||
|
||||
dnn = {'dnn_Net': ['setInput', 'forward', 'setPreferableBackend','getUnconnectedOutLayersNames'],
|
||||
'': ['readNetFromTensorflow',
|
||||
'readNetFromONNX', 'readNetFromTFLite', 'readNet', 'blobFromImage']}
|
||||
|
||||
features = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptorSize', 'descriptorType', 'defaultNorm', 'empty', 'getDefaultName'],
|
||||
'ORB': ['create', 'setMaxFeatures', 'setScaleFactor', 'setNLevels', 'setEdgeThreshold', 'setFastThreshold', 'setFirstLevel', 'setWTA_K', 'setScoreType', 'setPatchSize', 'getFastThreshold', 'getDefaultName'],
|
||||
'MSER': ['create', 'detectRegions', 'setDelta', 'getDelta', 'setMinArea', 'getMinArea', 'setMaxArea', 'getMaxArea', 'setPass2Only', 'getPass2Only', 'getDefaultName'],
|
||||
'FastFeatureDetector': ['create', 'setThreshold', 'getThreshold', 'setNonmaxSuppression', 'getNonmaxSuppression', 'setType', 'getType', 'getDefaultName'],
|
||||
'GFTTDetector': ['create', 'setMaxFeatures', 'getMaxFeatures', 'setQualityLevel', 'getQualityLevel', 'setMinDistance', 'getMinDistance', 'setBlockSize', 'getBlockSize', 'setHarrisDetector', 'getHarrisDetector', 'setK', 'getK', 'getDefaultName'],
|
||||
'SimpleBlobDetector': ['create', 'setParams', 'getParams', 'getDefaultName'],
|
||||
'SimpleBlobDetector_Params': [],
|
||||
'DescriptorMatcher': ['add', 'clear', 'empty', 'isMaskSupported', 'train', 'match', 'knnMatch', 'radiusMatch', 'clone', 'create'],
|
||||
'BFMatcher': ['isMaskSupported', 'create'],
|
||||
'': ['drawKeypoints', 'drawMatches', 'drawMatchesKnn']}
|
||||
|
||||
photo = {'': ['createAlignMTB', 'createCalibrateDebevec', 'createCalibrateRobertson', \
|
||||
'createMergeDebevec', 'createMergeMertens', 'createMergeRobertson', \
|
||||
'createTonemapDrago', 'createTonemapMantiuk', 'createTonemapReinhard', 'inpaint'],
|
||||
'CalibrateCRF': ['process'],
|
||||
'AlignExposures': ['process'],
|
||||
'AlignMTB' : ['calculateShift', 'shiftMat', 'computeBitmaps', 'getMaxBits', 'setMaxBits', \
|
||||
'getExcludeRange', 'setExcludeRange', 'getCut', 'setCut'],
|
||||
'CalibrateDebevec' : ['getLambda', 'setLambda', 'getSamples', 'setSamples', 'getRandom', 'setRandom'],
|
||||
'CalibrateRobertson' : ['getMaxIter', 'setMaxIter', 'getThreshold', 'setThreshold', 'getRadiance'],
|
||||
'MergeExposures' : ['process'],
|
||||
'MergeDebevec' : ['process'],
|
||||
'MergeMertens' : ['process', 'getContrastWeight', 'setContrastWeight', 'getSaturationWeight', \
|
||||
'setSaturationWeight', 'getExposureWeight', 'setExposureWeight'],
|
||||
'MergeRobertson' : ['process'],
|
||||
'Tonemap' : ['process' , 'getGamma', 'setGamma'],
|
||||
'TonemapDrago' : ['getSaturation', 'setSaturation', 'getBias', 'setBias', \
|
||||
'getSigmaColor', 'setSigmaColor', 'getSigmaSpace','setSigmaSpace'],
|
||||
'TonemapMantiuk' : ['getScale', 'setScale', 'getSaturation', 'setSaturation'],
|
||||
'TonemapReinhard' : ['getIntensity', 'setIntensity', 'getLightAdaptation', 'setLightAdaptation', \
|
||||
'getColorAdaptation', 'setColorAdaptation']
|
||||
}
|
||||
|
||||
_3d = {
|
||||
'': [
|
||||
'findHomography',
|
||||
'calibrateCameraExtended',
|
||||
'drawFrameAxes',
|
||||
'estimateAffine2D',
|
||||
'getDefaultNewCameraMatrix',
|
||||
'initUndistortRectifyMap',
|
||||
'Rodrigues',
|
||||
'solvePnP',
|
||||
'solvePnPRansac',
|
||||
'solvePnPRefineLM',
|
||||
'projectPoints',
|
||||
'undistort',
|
||||
],
|
||||
}
|
||||
|
||||
calib = {
|
||||
'': [
|
||||
|
||||
# cv::fisheye namespace
|
||||
'fisheye_initUndistortRectifyMap',
|
||||
'fisheye_projectPoints',
|
||||
],
|
||||
'UsacParams': ['UsacParams']
|
||||
}
|
||||
|
||||
|
||||
white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features, photo, _3d, calib])
|
||||
|
||||
# namespace_prefix_override['dnn'] = '' # compatibility stuff (enabled by default)
|
||||
# namespace_prefix_override['aruco'] = '' # compatibility stuff (enabled by default)
|
||||
@@ -0,0 +1,4 @@
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
set(GCC_COMPILER_VERSION "" CACHE STRING "GCC Compiler version")
|
||||
set(GNU_MACHINE "aarch64-linux-gnu" CACHE STRING "GNU compiler triple")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/arm.toolchain.cmake")
|
||||
@@ -0,0 +1,3 @@
|
||||
set(GCC_COMPILER_VERSION "" CACHE STRING "GCC Compiler version")
|
||||
set(GNU_MACHINE "arm-linux-gnueabi" CACHE STRING "GNU compiler triple")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/arm.toolchain.cmake")
|
||||
@@ -0,0 +1,88 @@
|
||||
if(COMMAND toolchain_save_config)
|
||||
return() # prevent recursive call
|
||||
endif()
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
if(NOT DEFINED CMAKE_SYSTEM_PROCESSOR)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
else()
|
||||
#message("CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/gnu.toolchain.cmake")
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL arm AND NOT ARM_IGNORE_FP)
|
||||
set(FLOAT_ABI_SUFFIX "")
|
||||
if(NOT SOFTFP)
|
||||
set(FLOAT_ABI_SUFFIX "hf")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT "x${GCC_COMPILER_VERSION}" STREQUAL "x")
|
||||
set(__GCC_VER_SUFFIX "-${GCC_COMPILER_VERSION}")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_C_COMPILER)
|
||||
find_program(CMAKE_C_COMPILER NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-gcc${__GCC_VER_SUFFIX})
|
||||
else()
|
||||
#message(WARNING "CMAKE_C_COMPILER=${CMAKE_C_COMPILER} is defined")
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
find_program(CMAKE_CXX_COMPILER NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-g++${__GCC_VER_SUFFIX})
|
||||
else()
|
||||
#message(WARNING "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} is defined")
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_LINKER)
|
||||
find_program(CMAKE_LINKER NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ld${__GCC_VER_SUFFIX} ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ld)
|
||||
else()
|
||||
#message(WARNING "CMAKE_LINKER=${CMAKE_LINKER} is defined")
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_AR)
|
||||
find_program(CMAKE_AR NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ar${__GCC_VER_SUFFIX} ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ar)
|
||||
else()
|
||||
#message(WARNING "CMAKE_AR=${CMAKE_AR} is defined")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED ARM_LINUX_SYSROOT AND DEFINED GNU_MACHINE)
|
||||
set(ARM_LINUX_SYSROOT /usr/${GNU_MACHINE}${FLOAT_ABI_SUFFIX})
|
||||
endif()
|
||||
|
||||
# == Compiler flags
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mthumb")
|
||||
set(CMAKE_C_FLAGS_INIT "-mthumb")
|
||||
set(common_ld_opt "-Wl,--fix-cortex-a8")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "${common_ld_opt}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_INIT "${common_ld_opt}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "${common_ld_opt} -Wl,-z,nocopyreloc")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/flags-aarch64.cmake")
|
||||
if(COMMAND ocv_set_platform_flags)
|
||||
ocv_set_platform_flags(CMAKE_CXX_FLAGS_INIT)
|
||||
ocv_set_platform_flags(CMAKE_C_FLAGS_INIT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(USE_NEON)
|
||||
message(WARNING "You use obsolete variable USE_NEON to enable NEON instruction set. Use -DENABLE_NEON=ON instead." )
|
||||
set(ENABLE_NEON TRUE)
|
||||
elseif(USE_VFPV3)
|
||||
message(WARNING "You use obsolete variable USE_VFPV3 to enable VFPV3 instruction set. Use -DENABLE_VFPV3=ON instead." )
|
||||
set(ENABLE_VFPV3 TRUE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${ARM_LINUX_SYSROOT})
|
||||
|
||||
if(EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${CUDA_TOOLKIT_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(TOOLCHAIN_CONFIG_VARS ${TOOLCHAIN_CONFIG_VARS}
|
||||
ARM_LINUX_SYSROOT
|
||||
ENABLE_NEON
|
||||
ENABLE_VFPV3
|
||||
CUDA_TOOLKIT_ROOT_DIR
|
||||
)
|
||||
toolchain_save_config()
|
||||
@@ -0,0 +1,22 @@
|
||||
# see https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html#index-march
|
||||
function(ocv_set_platform_flags VAR)
|
||||
unset(flags)
|
||||
if(ENABLE_SVE)
|
||||
set(flags "${flags}+sve")
|
||||
endif()
|
||||
if(ENABLE_BF16)
|
||||
set(flags "${flags}+bf16")
|
||||
endif()
|
||||
if(ENABLE_DOTPROD)
|
||||
set(flags "${flags}+dotprod")
|
||||
endif()
|
||||
if(ENABLE_FP16)
|
||||
set(flags "${flags}+fp16")
|
||||
endif()
|
||||
if(DEFINED ENABLE_NEON AND NOT ENABLE_NEON)
|
||||
set(flags "${flags}+nosimd")
|
||||
endif()
|
||||
if(flags)
|
||||
set(${VAR} "-march=armv8.2-a${flags}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,13 @@
|
||||
# see https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html#index-march-14
|
||||
function(ocv_set_platform_flags VAR)
|
||||
if(ENABLE_RVV_ZVFH OR ENABLE_RVV_FP16)
|
||||
set(flags "-march=rv64gc_v_zvfh")
|
||||
elseif(ENABLE_RVV_ZVFHMIN OR ENABLE_FP16)
|
||||
set(flags "-march=rv64gc_v_zvfhmin")
|
||||
elseif(ENABLE_RVV OR RISCV_RVV_SCALABLE)
|
||||
set(flags "-march=rv64gcv")
|
||||
else()
|
||||
set(flags "-march=rv64gc")
|
||||
endif()
|
||||
set(${VAR} "${flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,134 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
# load settings in case of "try compile"
|
||||
set(TOOLCHAIN_CONFIG_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain.config.cmake")
|
||||
get_property(__IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||
if(__IN_TRY_COMPILE)
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/../toolchain.config.cmake" OPTIONAL) # CMAKE_BINARY_DIR is different
|
||||
macro(toolchain_save_config)
|
||||
# nothing
|
||||
endmacro()
|
||||
else()
|
||||
macro(toolchain_save_config)
|
||||
set(__config "#message(\"Load TOOLCHAIN config...\")\n")
|
||||
get_cmake_property(__variableNames VARIABLES)
|
||||
set(__vars_list ${ARGN})
|
||||
list(APPEND __vars_list
|
||||
${TOOLCHAIN_CONFIG_VARS}
|
||||
CMAKE_SYSTEM_NAME
|
||||
CMAKE_SYSTEM_VERSION
|
||||
CMAKE_SYSTEM_PROCESSOR
|
||||
CMAKE_C_COMPILER
|
||||
CMAKE_CXX_COMPILER
|
||||
CMAKE_C_FLAGS
|
||||
CMAKE_CXX_FLAGS
|
||||
CMAKE_SHARED_LINKER_FLAGS
|
||||
CMAKE_MODULE_LINKER_FLAGS
|
||||
CMAKE_EXE_LINKER_FLAGS
|
||||
CMAKE_SKIP_RPATH
|
||||
CMAKE_FIND_ROOT_PATH
|
||||
GCC_COMPILER_VERSION
|
||||
)
|
||||
foreach(__var ${__variableNames})
|
||||
foreach(_v ${__vars_list})
|
||||
if("x${__var}" STREQUAL "x${_v}")
|
||||
if(${__var} MATCHES " ")
|
||||
set(__config "${__config}set(${__var} \"${${__var}}\")\n")
|
||||
else()
|
||||
set(__config "${__config}set(${__var} ${${__var}})\n")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
if(EXISTS "${TOOLCHAIN_CONFIG_FILE}")
|
||||
file(READ "${TOOLCHAIN_CONFIG_FILE}" __config_old)
|
||||
endif()
|
||||
if("${__config_old}" STREQUAL "${__config}")
|
||||
# nothing
|
||||
else()
|
||||
#message("Update TOOLCHAIN config: ${__config}")
|
||||
file(WRITE "${TOOLCHAIN_CONFIG_FILE}" "${__config}")
|
||||
endif()
|
||||
unset(__config)
|
||||
unset(__config_old)
|
||||
unset(__vars_list)
|
||||
unset(__variableNames)
|
||||
endmacro()
|
||||
endif() # IN_TRY_COMPILE
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
endif()
|
||||
|
||||
macro(__cmake_find_root_save_and_reset)
|
||||
foreach(v
|
||||
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
|
||||
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
|
||||
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
|
||||
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
|
||||
)
|
||||
set(__save_${v} ${${v}})
|
||||
set(${v} NEVER)
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(__cmake_find_root_restore)
|
||||
foreach(v
|
||||
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
|
||||
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
|
||||
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
|
||||
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
|
||||
)
|
||||
set(${v} ${__save_${v}})
|
||||
unset(__save_${v})
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
|
||||
# macro to find programs on the host OS
|
||||
macro(find_host_program)
|
||||
__cmake_find_root_save_and_reset()
|
||||
if(CMAKE_HOST_WIN32)
|
||||
SET(WIN32 1)
|
||||
SET(UNIX)
|
||||
elseif(CMAKE_HOST_APPLE)
|
||||
SET(APPLE 1)
|
||||
SET(UNIX)
|
||||
endif()
|
||||
find_program(${ARGN})
|
||||
SET(WIN32)
|
||||
SET(APPLE)
|
||||
SET(UNIX 1)
|
||||
__cmake_find_root_restore()
|
||||
endmacro()
|
||||
|
||||
# macro to find packages on the host OS
|
||||
macro(find_host_package)
|
||||
__cmake_find_root_save_and_reset()
|
||||
if(CMAKE_HOST_WIN32)
|
||||
SET(WIN32 1)
|
||||
SET(UNIX)
|
||||
elseif(CMAKE_HOST_APPLE)
|
||||
SET(APPLE 1)
|
||||
SET(UNIX)
|
||||
endif()
|
||||
find_package(${ARGN})
|
||||
SET(WIN32)
|
||||
SET(APPLE)
|
||||
SET(UNIX 1)
|
||||
__cmake_find_root_restore()
|
||||
endmacro()
|
||||
|
||||
set(CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries.")
|
||||
@@ -0,0 +1,80 @@
|
||||
# ----------------------------------------------------------------------------------------------
|
||||
# MIPS ToolChanin can be downloaded from https://www.mips.com/develop/tools/codescape-mips-sdk/ .
|
||||
# Toolchains with 'mti' in the name (and install directory) are for MIPS R2-R5 instruction sets.
|
||||
# Toolchains with 'img' in the name are for MIPS R6 instruction sets.
|
||||
# It is recommended to use cmake-gui application for build scripts configuration and generation:
|
||||
# 1. Run cmake-gui
|
||||
# 2. Specify toolchain file for cross-compiling, mips32r5el-gnu.toolchian.cmake or mips64r6el-gnu.toolchain.cmake
|
||||
# can be selected.
|
||||
# 3. Configure and Generate makefiles.
|
||||
# 4. make -j4 & make install
|
||||
# ----------------------------------------------------------------------------------------------
|
||||
|
||||
if(COMMAND toolchain_save_config)
|
||||
return() # prevent recursive call
|
||||
endif()
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
if(NOT DEFINED CMAKE_SYSTEM_PROCESSOR)
|
||||
set(CMAKE_SYSTEM_PROCESSOR mips)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/gnu.toolchain.cmake")
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL mips AND NOT MIPS_IGNORE_FP)
|
||||
set(FLOAT_ABI_SUFFIX "")
|
||||
endif()
|
||||
|
||||
if(NOT "x${GCC_COMPILER_VERSION}" STREQUAL "x")
|
||||
set(__GCC_VER_SUFFIX "-${GCC_COMPILER_VERSION}")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_C_COMPILER)
|
||||
find_program(CMAKE_C_COMPILER NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-gcc${__GCC_VER_SUFFIX})
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
find_program(CMAKE_CXX_COMPILER NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-g++${__GCC_VER_SUFFIX})
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_LINKER)
|
||||
find_program(CMAKE_LINKER NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ld${__GCC_VER_SUFFIX} ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ld)
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_AR)
|
||||
find_program(CMAKE_AR NAMES ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ar${__GCC_VER_SUFFIX} ${GNU_MACHINE}${FLOAT_ABI_SUFFIX}-ar)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED MIPS_LINUX_SYSROOT AND DEFINED GNU_MACHINE)
|
||||
set(MIPS_LINUX_SYSROOT /usr/bin)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_CXX_FLAGS)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mips32r5el")
|
||||
set(CMAKE_C_FLAGS "-march=mips32r5 -EL -mmsa -mhard-float -mfp64 -mnan=2008 -mabs=2008 -O3 -ffp-contract=off -mtune=p5600" CACHE INTERNAL "")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_CXX_FLAGS "-march=mips32r5 -EL -mmsa -mhard-float -mfp64 -mnan=2008 -mabs=2008 -O3 -ffp-contract=off -mtune=p5600" CACHE INTERNAL "")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-lpthread -lrt -ldl -latomic" CACHE INTERNAL "Added for mips cross build error")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "mips64r6el")
|
||||
set(CMAKE_C_FLAGS "-O3 -march=i6500 -EL -mmsa -mabi=64 -mhard-float -mfp64 -mnan=2008" CACHE INTERNAL "")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_CXX_FLAGS "-O3 -march=i6500 -EL -mmsa -mabi=64 -mhard-float -mfp64 -mnan=2008" CACHE INTERNAL "")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-lpthread -lrt -ldl" CACHE INTERNAL "Added for mips cross build error")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
|
||||
endif()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${MIPS_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${MIPS_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${MIPS_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${MIPS_LINUX_SYSROOT})
|
||||
|
||||
set(TOOLCHAIN_CONFIG_VARS ${TOOLCHAIN_CONFIG_VARS}
|
||||
MIPS_LINUX_SYSROOT
|
||||
)
|
||||
toolchain_save_config()
|
||||
@@ -0,0 +1,14 @@
|
||||
# ----------------------------------------------------------------------------------------------
|
||||
# MIPS ToolChanin can be downloaded from https://www.mips.com/develop/tools/codescape-mips-sdk/ .
|
||||
# Toolchains with 'mti' in the name (and install directory) are for MIPS R2-R5 instruction sets.
|
||||
# Toolchains with 'img' in the name are for MIPS R6 instruction sets.
|
||||
# It is recommended to use cmake-gui for build scripts configuration and generation:
|
||||
# 1. Run cmake-gui
|
||||
# 2. Specify toolchain file mips32r5el-gnu.toolchian.cmake for cross-compiling.
|
||||
# 3. Configure and Generate makefiles.
|
||||
# 4. make -j4 & make install
|
||||
# ----------------------------------------------------------------------------------------------
|
||||
set(CMAKE_SYSTEM_PROCESSOR mips32r5el)
|
||||
set(GCC_COMPILER_VERSION "" CACHE STRING "GCC Compiler version")
|
||||
set(GNU_MACHINE "mips-mti-linux-gnu" CACHE STRING "GNU compiler triple")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/mips.toolchain.cmake")
|
||||
@@ -0,0 +1,14 @@
|
||||
# ----------------------------------------------------------------------------------------------
|
||||
# MIPS ToolChanin can be downloaded from https://www.mips.com/develop/tools/codescape-mips-sdk/ .
|
||||
# Toolchains with 'mti' in the name (and install directory) are for MIPS R2-R5 instruction sets.
|
||||
# Toolchains with 'img' in the name are for MIPS R6 instruction sets.
|
||||
# It is recommended to use cmake-gui for build scripts configuration and generation:
|
||||
# 1. Run cmake-gui
|
||||
# 2. Specify toolchain file mips64r6el-gnu.toolchain.cmake for cross-compiling.
|
||||
# 3. Configure and Generate makefiles.
|
||||
# 4. make -j4 & make install
|
||||
# ----------------------------------------------------------------------------------------------
|
||||
set(CMAKE_SYSTEM_PROCESSOR mips64r6el)
|
||||
set(GCC_COMPILER_VERSION "" CACHE STRING "GCC Compiler version")
|
||||
set(GNU_MACHINE "mips-img-linux-gnu" CACHE STRING "GNU compiler triple")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/mips.toolchain.cmake")
|
||||
@@ -0,0 +1,3 @@
|
||||
set(CMAKE_SYSTEM_PROCESSOR ppc64)
|
||||
set(GNU_MACHINE "powerpc64-linux-gnu" CACHE STRING "GNU compiler triple")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/ppcat.toolchain.cmake")
|
||||
@@ -0,0 +1,3 @@
|
||||
set(CMAKE_SYSTEM_PROCESSOR ppc64le)
|
||||
set(GNU_MACHINE "powerpc64le-linux-gnu" CACHE STRING "GNU compiler triple")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/ppcat.toolchain.cmake")
|
||||
@@ -0,0 +1,129 @@
|
||||
if(COMMAND toolchain_save_config)
|
||||
return() # prevent recursive call
|
||||
endif()
|
||||
|
||||
option(AT_PATH "Advance Toolchain directory" "")
|
||||
option(AT_RPATH "Add new directories to runtime search path" "")
|
||||
option(AT_HOST_LINK "Enable/disable Link against host advance toolchain runtime" OFF)
|
||||
option(AT_NO_AUTOVEC "Disable/enable Auto Vectorizer optimization" OFF)
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/gnu.toolchain.cmake")
|
||||
|
||||
if(NOT DEFINED CMAKE_C_COMPILER)
|
||||
string(REGEX REPLACE "/+$" "" AT_PATH "${AT_PATH}")
|
||||
|
||||
if(NOT AT_PATH)
|
||||
message(FATAL_ERROR "'AT_PATH' option is required. Please set it to Advance Toolchain path to get toolchain works")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${AT_PATH})
|
||||
message(FATAL_ERROR "'${AT_PATH}' Advance Toolchain path isn't exist")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER "${AT_PATH}/bin/${GNU_MACHINE}-gcc")
|
||||
|
||||
if(NOT EXISTS ${CMAKE_C_COMPILER})
|
||||
message(FATAL_ERROR "GNU C compiler isn't exist on path '${CMAKE_C_COMPILER}'. Please install Advance Toolchain with ${CMAKE_SYSTEM_PROCESSOR} supports")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "${AT_PATH}/bin/${GNU_MACHINE}-g++")
|
||||
|
||||
if(NOT EXISTS ${CMAKE_CXX_COMPILER})
|
||||
message(FATAL_ERROR "GNU C++ compiler isn't exist. Invalid install of Advance Toolchain")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED AT_GCCROOT_PATH)
|
||||
set(AT_GCCROOT_PATH "${AT_PATH}/${GNU_MACHINE}")
|
||||
|
||||
if(NOT EXISTS ${AT_GCCROOT_PATH})
|
||||
message(FATAL_ERROR "GCC root path '${AT_GCCROOT_PATH}' isn't exist. Invalid install of Advance Toolchain")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED AT_SYSROOT_PATH)
|
||||
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ppc64")
|
||||
set(AT_SYSROOT_PATH "${AT_PATH}/ppc")
|
||||
else()
|
||||
set(AT_SYSROOT_PATH "${AT_PATH}/${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${AT_SYSROOT_PATH})
|
||||
message(FATAL_ERROR "System root path '${AT_SYSROOT_PATH}' isn't exist. Invalid install of Advance Toolchain")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS)
|
||||
set(CMAKE_CXX_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_C_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "" CACHE INTERNAL "")
|
||||
|
||||
if(AT_RPATH)
|
||||
string(REPLACE "," ";" RPATH_LIST ${AT_RPATH})
|
||||
endif()
|
||||
|
||||
if(AT_HOST_LINK)
|
||||
#get 64-bit dynamic linker path
|
||||
file(STRINGS "${AT_SYSROOT_PATH}/usr/bin/ldd" RTLDLIST LIMIT_COUNT 1 REGEX "^RTLDLIST=[\"*\"]")
|
||||
string(REGEX REPLACE "RTLDLIST=|\"" "" RTLDLIST "${RTLDLIST}")
|
||||
string(REPLACE " " ";" RTLDLIST "${RTLDLIST}")
|
||||
|
||||
#RTLDLIST must contains 32 and 64 bit paths
|
||||
list(LENGTH RTLDLIST RTLDLIST_LEN)
|
||||
if(NOT RTLDLIST_LEN GREATER 1)
|
||||
message(FATAL_ERROR "Could not fetch dynamic linker path. Invalid install of Advance Toolchain")
|
||||
endif()
|
||||
|
||||
list (GET RTLDLIST 1 LINKER_PATH)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--dynamic-linker=${AT_SYSROOT_PATH}${LINKER_PATH}")
|
||||
|
||||
list(APPEND RPATH_LIST "${AT_GCCROOT_PATH}/lib64/")
|
||||
list(APPEND RPATH_LIST "${AT_SYSROOT_PATH}/lib64/")
|
||||
list(APPEND RPATH_LIST "${AT_SYSROOT_PATH}/usr/lib64/")
|
||||
list(APPEND RPATH_LIST "${PROJECT_BINARY_DIR}/lib/")
|
||||
endif()
|
||||
|
||||
list(LENGTH RPATH_LIST RPATH_LEN)
|
||||
if(RPATH_LEN GREATER 0)
|
||||
set(AT_LINKER_FLAGS "${AT_LINKER_FLAGS} -Wl")
|
||||
foreach(RPATH ${RPATH_LIST})
|
||||
set(AT_LINKER_FLAGS "${AT_LINKER_FLAGS},-rpath,${RPATH}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${AT_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${AT_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${AT_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
|
||||
if(AT_NO_AUTOVEC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize -fno-tree-slp-vectorize")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-vectorize -fno-tree-slp-vectorize")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${AT_SYSROOT_PATH} ${AT_GCCROOT_PATH})
|
||||
set(CMAKE_SYSROOT ${AT_SYSROOT_PATH})
|
||||
|
||||
# what about ld.gold?
|
||||
if(NOT DEFINED CMAKE_LINKER)
|
||||
find_program(CMAKE_LINKER NAMES ld)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_AR)
|
||||
find_program(CMAKE_AR NAMES ar)
|
||||
endif()
|
||||
|
||||
set(TOOLCHAIN_CONFIG_VARS ${TOOLCHAIN_CONFIG_VARS}
|
||||
CMAKE_SYSROOT
|
||||
AT_SYSROOT_PATH
|
||||
AT_GCCROOT_PATH
|
||||
)
|
||||
toolchain_save_config()
|
||||
@@ -0,0 +1,54 @@
|
||||
if(COMMAND toolchain_save_config)
|
||||
return() # prevent recursive call
|
||||
endif()
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
if(NOT DEFINED CMAKE_SYSTEM_PROCESSOR)
|
||||
set(CMAKE_SYSTEM_PROCESSOR riscv64)
|
||||
else()
|
||||
#message("CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/gnu.toolchain.cmake")
|
||||
|
||||
if(NOT "x${GCC_COMPILER_VERSION}" STREQUAL "x")
|
||||
set(__GCC_VER_SUFFIX "-${GCC_COMPILER_VERSION}")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED GNU_MACHINE)
|
||||
set(GNU_MACHINE riscv64-unknown-linux-gnu CACHE STRING "GNU compiler triple")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED TOOLCHAIN_COMPILER_LOCATION_HINT)
|
||||
set(TOOLCHAIN_COMPILER_LOCATION_HINT PATHS /opt/riscv/bin ENV PATH)
|
||||
endif()
|
||||
|
||||
find_program(CMAKE_C_COMPILER NAMES ${GNU_MACHINE}-gcc${__GCC_VER_SUFFIX} PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
|
||||
find_program(CMAKE_CXX_COMPILER NAMES ${GNU_MACHINE}-g++${__GCC_VER_SUFFIX} PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
|
||||
find_program(CMAKE_LINKER NAMES ${GNU_MACHINE}-ld${__GCC_VER_SUFFIX} ${GNU_MACHINE}-ld PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
|
||||
find_program(CMAKE_AR NAMES ${GNU_MACHINE}-ar${__GCC_VER_SUFFIX} ${GNU_MACHINE}-ar PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
|
||||
|
||||
if(NOT CMAKE_C_COMPILER OR NOT CMAKE_CXX_COMPILER OR NOT CMAKE_LINKER OR NOT CMAKE_AR)
|
||||
message(FATAL_ERROR "\
|
||||
One of RISC-V toolchain components have not been found:
|
||||
CMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
CMAKE_LINKER=${CMAKE_LINKER}
|
||||
CMAKE_AR=${CMAKE_AR}
|
||||
Use PATH environment variable and/or GNU_MACHINE, TOOLCHAIN_COMPILER_LOCATION_HINT and others cmake variables to help CMake find them.")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED RISCV_SYSROOT)
|
||||
get_filename_component(_base_dir ${CMAKE_C_COMPILER} DIRECTORY)
|
||||
get_filename_component(_base_dir ${_base_dir} DIRECTORY)
|
||||
set(RISCV_SYSROOT ${_base_dir}/sysroot CACHE PATH "RISC-V sysroot")
|
||||
endif()
|
||||
|
||||
set(CMAKE_SYSROOT "${RISCV_SYSROOT}")
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${RISCV_SYSROOT})
|
||||
|
||||
set(TOOLCHAIN_CONFIG_VARS ${TOOLCHAIN_CONFIG_VARS}
|
||||
RISCV_SYSROOT
|
||||
)
|
||||
toolchain_save_config()
|
||||
@@ -0,0 +1,57 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR riscv64)
|
||||
|
||||
set(CMAKE_CXX_COMPILER riscv64-unknown-linux-gnu-g++)
|
||||
set(CMAKE_C_COMPILER riscv64-unknown-linux-gnu-gcc)
|
||||
|
||||
# MangoPi MQ Pro - C906FD, C906FDV
|
||||
# Lichee Pi 4A - C910, C910V (?)
|
||||
# CanMV K230 - C908, C908V
|
||||
|
||||
# See https://github.com/T-head-Semi/gcc/blob/xuantie-gcc-10.4.0/gcc/config/riscv/riscv-cores.def
|
||||
|
||||
set(_enable_vector OFF)
|
||||
if(CORE STREQUAL "C906FD")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c906fd -mabi=lp64d -mtune=c906fd")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c906fd -mabi=lp64d -mtune=c906fd")
|
||||
elseif(CORE STREQUAL "C906FDV")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c906fd -mabi=lp64d -mtune=c906fd")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c906fd -mabi=lp64d -mtune=c906fd")
|
||||
# Disabled due to limited 64-bit SEW support
|
||||
# set(_enable_vector ON)
|
||||
elseif(CORE STREQUAL "C908")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c908 -mabi=lp64d -mtune=c908")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c908 -mabi=lp64d -mtune=c908")
|
||||
elseif(CORE STREQUAL "C908V")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c908v -mabi=lp64d -mtune=c908")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c908v -mabi=lp64d -mtune=c908")
|
||||
set(_enable_vector ON) # RVV 1.0
|
||||
elseif(CORE STREQUAL "C910")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c910 -mabi=lp64d -mtune=c910")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c910 -mabi=lp64d -mtune=c910")
|
||||
elseif(CORE STREQUAL "C910V")
|
||||
set(CMAKE_C_FLAGS_INIT "-march=rv64imafdcv0p7xthead -mabi=lp64d")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-march=rv64imafdcv0p7xthead -mabi=lp64d")
|
||||
set(_enable_vector ON) # RVV 0.7.1
|
||||
elseif(CORE STREQUAL "C920")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c920 -mabi=lp64d -mtune=c920")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c920 -mabi=lp64d -mtune=c920")
|
||||
set(_enable_vector ON) # RVV 0.7.1
|
||||
elseif(CORE STREQUAL "C920V2")
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=c920v2 -mabi=lp64d -mtune=c920v2")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=c920v2 -mabi=lp64d -mtune=c920v2")
|
||||
set(_enable_vector ON) # RVV 1.0
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_INIT "-march=rv64imafdc_zihintpause_zfh_zba_zbb_zbc_zbs_xtheadc -mabi=lp64d")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-march=rv64imafdc_zihintpause_zfh_zba_zbb_zbc_zbs_xtheadc -mabi=lp64d")
|
||||
endif()
|
||||
|
||||
if(_enable_vector)
|
||||
set(CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS_INIT} -D__riscv_vector_071 -mrvv-vector-bits=128")
|
||||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} -D__riscv_vector_071 -mrvv-vector-bits=128")
|
||||
endif()
|
||||
|
||||
if(ENABLE_GCOV)
|
||||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} -fprofile-arcs -ftest-coverage")
|
||||
set(CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS_INIT} -fprofile-arcs -ftest-coverage")
|
||||
endif()
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR riscv64)
|
||||
|
||||
message(STATUS "RISCV: $ENV{RISCV}")
|
||||
message(STATUS "RISCV_GCC_INSTALL_ROOT: $ENV{RISCV_GCC_INSTALL_ROOT}")
|
||||
|
||||
set(RISCV_GCC_INSTALL_ROOT $ENV{RISCV} CACHE PATH "Path to GCC for RISC-V cross compiler installation directory")
|
||||
|
||||
set(CMAKE_C_COMPILER ${RISCV_GCC_INSTALL_ROOT}/bin/riscv64-linux-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${RISCV_GCC_INSTALL_ROOT}/bin/riscv64-linux-g++)
|
||||
|
||||
# fix toolchain macro
|
||||
# enable rvp
|
||||
|
||||
set(CMAKE_C_FLAGS_INIT "-march=rv64gc -mext-dsp -D__ANDES=1")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-march=rv64gc -mext-dsp -D__ANDES=1")
|
||||
|
||||
# fix segment address
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-Ttext-segment=0x50000")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-Wl,-Ttext-segment=0x50000")
|
||||
@@ -0,0 +1,32 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR riscv64)
|
||||
|
||||
set(RISCV_CLANG_BUILD_ROOT /opt/rvv-llvm CACHE PATH "Path to CLANG for RISC-V cross compiler build directory")
|
||||
set(RISCV_GCC_INSTALL_ROOT /opt/riscv CACHE PATH "Path to GCC for RISC-V cross compiler installation directory")
|
||||
set(CMAKE_SYSROOT ${RISCV_GCC_INSTALL_ROOT}/sysroot CACHE PATH "RISC-V sysroot")
|
||||
|
||||
set(CLANG_TARGET_TRIPLE riscv64-unknown-linux-gnu)
|
||||
|
||||
set(CMAKE_C_COMPILER ${RISCV_CLANG_BUILD_ROOT}/bin/clang)
|
||||
set(CMAKE_C_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
|
||||
set(CMAKE_CXX_COMPILER ${RISCV_CLANG_BUILD_ROOT}/bin/clang++)
|
||||
set(CMAKE_CXX_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
|
||||
set(CMAKE_ASM_COMPILER ${RISCV_CLANG_BUILD_ROOT}/bin/clang)
|
||||
set(CMAKE_ASM_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
|
||||
|
||||
# Don't run the linker on compiler check
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/flags-riscv64.cmake")
|
||||
if(COMMAND ocv_set_platform_flags)
|
||||
ocv_set_platform_flags(CMAKE_CXX_FLAGS_INIT)
|
||||
ocv_set_platform_flags(CMAKE_C_FLAGS_INIT)
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} --gcc-toolchain=${RISCV_GCC_INSTALL_ROOT} -w")
|
||||
set(CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS_INIT} --gcc-toolchain=${RISCV_GCC_INSTALL_ROOT} -w")
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
@@ -0,0 +1,11 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR riscv64)
|
||||
set(GNU_MACHINE riscv64-unknown-linux-gnu CACHE STRING "GNU compiler triple")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/flags-riscv64.cmake")
|
||||
if(COMMAND ocv_set_platform_flags)
|
||||
ocv_set_platform_flags(CMAKE_CXX_FLAGS_INIT)
|
||||
ocv_set_platform_flags(CMAKE_C_FLAGS_INIT)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/riscv-gnu.toolchain.cmake")
|
||||
@@ -0,0 +1,3 @@
|
||||
**/*.iml
|
||||
.idea/
|
||||
**/*.versionsBackup
|
||||
@@ -0,0 +1,95 @@
|
||||
# Using Maven to build OpenCV
|
||||
|
||||
This page describes the how to build OpenCV using [Apache Maven](http://maven.apache.org/index.html). The Maven build is simply a wrapper around the existing CMake process but has the additional aims of creating Java OSGi-compatible bundles with included native support and also allow the build to be carried out on RaspberryPi (ARM) architecture. There is nothing preventing using the POM on x86 Linux however.
|
||||
|
||||
The following assumes building on Debian-based Linux platform.
|
||||
|
||||
## 1 - Overview
|
||||
The Maven build process aims to:
|
||||
1. Provide a simpler route to build OpenCV and Java bundles.
|
||||
2. Automatically check the required native dependencies.
|
||||
3. Make the Java libraries OSGi compatible.
|
||||
4. Include the native OpenCV native library inside the Java bundle.
|
||||
5. Integration testing of the bundle within an OSGi environment.
|
||||
6. Allow the build to function on x86, x86_64 or amd architectures, Debian-based Linux platform.
|
||||
|
||||
### 2 - Preparing The Build environment
|
||||
To build using the Maven build process both `Maven` and and up-to-date `JDK` (Java Development Kit) need to be installed. If you know you already have these installed then continue to `Environment Variable` otherwise the easiest solution is to install them using the aptitude package manager:
|
||||
|
||||
`sudo aptitude install maven default-jdk`
|
||||
|
||||
Note that installing via `aptitude` you are unlikely to get the latest version of Maven or JDK although if you are not developing Java code this shouldn't matter for this build process.
|
||||
|
||||
### 3 - Starting the build
|
||||
#### 3.1 - Environment variables
|
||||
**Applicability:** All processors.
|
||||
|
||||
The following environment variables must be set otherwise the build will fail and halt:
|
||||
|
||||
* `$JAVA_HOME` (the absolute path to the JDK root directory)
|
||||
* `$ANT_HOME` (the absolute path to the Ant root directory)
|
||||
|
||||
It is recommended that advantage is taken of multiple processor cores to reduce build time. This can be done by setting a MAKEFLAGS environment variable specifying the number of parallel builds e.g.:
|
||||
|
||||
* `$MAKEFLAGS="-j8"`
|
||||
|
||||
However if this flag is not set the build will NOT fail. On a RaspberryPi 2 typical build times are 5 hours with `-j1` (which is the default if `$MAKEFLAGS` is not specified) and a little over 2 hours with `-j4`.
|
||||
|
||||
All of the above environment variables can be set on an ad-hoc basis using 'export'.
|
||||
#### 3.2 - Build Directory
|
||||
**Applicability:** All processors
|
||||
|
||||
By default the following build directories are created.
|
||||
|
||||
`<OpenCV_root_dir>/build`
|
||||
|
||||
`<OpenCV_root_dir>/build/maven/opencv/target`
|
||||
|
||||
`<OpenCV_root_dir>/build/maven/opencv-it/target`
|
||||
|
||||
Under `build` are the standard OpenCV artifacts. Under `build/maven/opencv/target` can be found the OSGi compatible Java bundle. When deploying the bundle into an OSGi framework e.g. [Apache Karaf](http://karaf.apache.org/), loading of the native library is automatically taken care of. An integration testing module is created under the `opencv-it` directory and is only of use during the build but is disabled by fault. The standard Java library as created by the CMake process is also available as specified in the existing OpenCV documentation.
|
||||
|
||||
The Maven build is initiated from the directory contain the `pom.xml` file.
|
||||
#### 3.3 - x86 or x86_64 Architecture:
|
||||
Generally all that is required is the standard Maven command:
|
||||
|
||||
`mvn clean install`
|
||||
|
||||
One of the first things the build will do is check the required native dependencies. The Maven build indicates the status of the required dependencies and will fail at this point if any are missing. Install using the package manager e.g. aptitude or apt-get, and restart the build with the above command.
|
||||
|
||||
Once the build successfully completes the OSGi compatible artifacts are available as described above in 'Build Directory'.
|
||||
|
||||
#### 3.4 - ARM 32-bit Architecture - Raspbian Distribution
|
||||
Similar to the x86 architecture the native dependencies are first checked so install any that are missing, however at the time of writing there are no official `libtbb2` and `libtbb-dev` packages in Raspbian. Version 4.4.3 of Intel's Thread Building Blocks library are available [here](http://www.javatechnics.com/thread-building-blocks-tbb-4-4-3-for-raspbian) as a Raspbian-compatible Debian packages.
|
||||
|
||||
**PLEASE NOTE THESE ARE NOT OFFICIAL RASPBIAN PACKAGES. INSTALL AT YOUR OWN RISK.**
|
||||
|
||||
The build can be started with the following command:
|
||||
|
||||
`mvn clean install`
|
||||
|
||||
Upon a successful build the libraries will be available as described above in 'Build Directory'.
|
||||
|
||||
#### 3.5 CMake
|
||||
**Applicability:** x86 processors
|
||||
|
||||
The CMake Maven plugin is configured to use the native CMake package (recommended) i.e. it will NOT download the latest CMake binary. Should you require CMake download then include the following Maven commandline switch when building:
|
||||
|
||||
`-Ddownload.cmake=true`
|
||||
|
||||
#### 3.6 Integration Tests
|
||||
**Applicability:** All processors
|
||||
|
||||
OSGi integration tests can be run as part of the build by including the following commandline switch to Maven:
|
||||
|
||||
`-Pintegration`
|
||||
|
||||
### 4.0 Maintainer Notes
|
||||
This section is relevant to those maintaining the Maven platform build. If you just want to build the library then you do not need to refer to this section.
|
||||
|
||||
#### 4.1 Updating POM Version to Match Core Version
|
||||
Maven requires the version to be hard-coded in the POM or in otherwords it cannot be changed at runtime. When the core C/C++ code version changes it is easy to forget to update the Maven version. The POM utilises the enforcer plugin to ensure the POM and Core versions match causing the build to fail if they do not.
|
||||
|
||||
Should the POM version require updating then this can be done utilising the Maven 'versions' plugin and this will apply the correct version to all POMs within the project. Execute the following Maven command from the root directory of the Maven project:
|
||||
|
||||
`mvn versions:set -DnewVersion=$(. ./opencv/scripts/functions && cd ./opencv/scripts && extract_version && echo $REPLY)`
|
||||
@@ -0,0 +1,111 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-parent</artifactId>
|
||||
<version>5.0.0</version>
|
||||
</parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-it</artifactId>
|
||||
<name>OpenCV Integration Test</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-container-karaf</artifactId>
|
||||
<version>${pax.exam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-junit4</artifactId>
|
||||
<version>${pax.exam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-atinject_1.0_spec</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.url</groupId>
|
||||
<artifactId>pax-url-aether</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.core</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.compendium</artifactId>
|
||||
<version>4.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.24</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.24</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>org.apache.karaf.log.core</artifactId>
|
||||
<groupId>org.apache.karaf.log</groupId>
|
||||
<version>4.0.6</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.logging</groupId>
|
||||
<artifactId>pax-logging-api</artifactId>
|
||||
<version>1.8.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<directory>../../../build/maven/opencv-it/target</directory>
|
||||
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||
<testOutputDirectory>../../../build/maven/opencv-it/target</testOutputDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.servicemix.tooling</groupId>
|
||||
<artifactId>depends-maven-plugin</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-depends-file</id>
|
||||
<goals>
|
||||
<goal>generate-depends-file</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.15</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.opencv.osgi;
|
||||
|
||||
import java.io.File;
|
||||
import javax.inject.Inject;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.karaf.log.core.LogService;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import static org.ops4j.pax.exam.CoreOptions.maven;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
|
||||
import org.ops4j.pax.exam.karaf.options.LogLevelOption;
|
||||
import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
import org.ops4j.pax.logging.spi.PaxLoggingEvent;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Kerry Billingham <contact@AvionicEngineers.com>
|
||||
*/
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
@RunWith(PaxExam.class)
|
||||
public class DeployOpenCVTest {
|
||||
|
||||
/*
|
||||
The expected string in Karaf logs when the bundle has deployed and native library loaded.
|
||||
*/
|
||||
private static final String OPENCV_SUCCESSFUL_LOAD_STRING = "Successfully loaded OpenCV native library.";
|
||||
|
||||
private static final String KARAF_VERSION = "4.0.6";
|
||||
|
||||
@Inject
|
||||
protected BundleContext bundleContext;
|
||||
|
||||
@Inject
|
||||
private LogService logService;
|
||||
|
||||
/*
|
||||
This service is required to ensure that the native library has been loaded
|
||||
before any test is carried out.
|
||||
*/
|
||||
@Inject
|
||||
private OpenCVInterface openCVInterface;
|
||||
|
||||
@Configuration
|
||||
public static Option[] configuration() throws Exception {
|
||||
MavenArtifactUrlReference karafUrl = maven()
|
||||
.groupId("org.apache.karaf")
|
||||
.artifactId("apache-karaf")
|
||||
.version(KARAF_VERSION)
|
||||
.type("tar.gz");
|
||||
return new Option[]{
|
||||
karafDistributionConfiguration()
|
||||
.frameworkUrl(karafUrl)
|
||||
.unpackDirectory(new File("../../../build/target/exam"))
|
||||
.useDeployFolder(false),
|
||||
keepRuntimeFolder(),
|
||||
mavenBundle()
|
||||
.groupId("org.opencv")
|
||||
.artifactId("opencv")
|
||||
.versionAsInProject(),
|
||||
logLevel(LogLevelOption.LogLevel.INFO)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the OpenCV bundle has been successfully deployed and that the
|
||||
* native library has been loaded.
|
||||
*/
|
||||
@Test
|
||||
public void testOpenCVNativeLibraryLoadSuccess() {
|
||||
|
||||
Iterable<PaxLoggingEvent> loggingEvents = logService.getEvents();
|
||||
boolean loadSuccessful = logsContainsMessage(loggingEvents, OPENCV_SUCCESSFUL_LOAD_STRING);
|
||||
|
||||
TestCase.assertTrue("Could not determine if OpenCV library successfully loaded from the logs.", loadSuccessful);
|
||||
|
||||
}
|
||||
|
||||
private boolean logsContainsMessage(Iterable<PaxLoggingEvent> logEnumeration, final String logMessageString) {
|
||||
boolean contains = false;
|
||||
for (PaxLoggingEvent logEntry : logEnumeration) {
|
||||
if (logEntry.getMessage().contains(logMessageString)) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return contains;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-parent</artifactId>
|
||||
<version>5.0.0</version>
|
||||
</parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>OpenCV</name>
|
||||
|
||||
<properties>
|
||||
<source.path>../../..</source.path>
|
||||
<build.directory>${source.path}/build</build.directory>
|
||||
<nativelibrary.name>libopencv_java${lib.version.string}.so</nativelibrary.name>
|
||||
<resources.directory>${build.directory}/src</resources.directory>
|
||||
</properties>
|
||||
<build>
|
||||
<directory>../../../build/maven/opencv/target</directory>
|
||||
<outputDirectory>../../../build/src</outputDirectory>
|
||||
<sourceDirectory>../../../build/src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>${build.directory}</directory>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>get-opencv-version</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>bash</executable>
|
||||
<workingDirectory>${project.basedir}/scripts</workingDirectory>
|
||||
<arguments>
|
||||
<argument>properties</argument>
|
||||
<argument>${build.directory}</argument>
|
||||
<argument>build.properties</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>setup-environment</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>bash</executable>
|
||||
<workingDirectory>${project.basedir}/scripts</workingDirectory>
|
||||
<arguments>
|
||||
<!-- Optional packages should be placed BEFORE required ones
|
||||
in the following argument list. -->
|
||||
<argument>deb_package_check</argument>
|
||||
<argument>-olibpng-dev|libpng12-dev</argument>
|
||||
<argument>-olibopenjp2-7-dev|libjasper-dev</argument>
|
||||
<argument>-opython-dev</argument>
|
||||
<argument>-opython-numpy</argument>
|
||||
<argument>build-essential</argument>
|
||||
<argument>cmake</argument>
|
||||
<argument>git</argument>
|
||||
<argument>libgtk2.0-dev</argument>
|
||||
<argument>pkg-config</argument>
|
||||
<argument>libavcodec-dev</argument>
|
||||
<argument>libavformat-dev</argument>
|
||||
<argument>libswscale-dev</argument>
|
||||
<argument>libtbb2</argument>
|
||||
<argument>libtbb-dev</argument>
|
||||
<argument>libjpeg-dev</argument>
|
||||
<argument>libtiff5-dev</argument>
|
||||
<argument>libdc1394-22-dev</argument>
|
||||
<argument>execstack</argument>
|
||||
<argument>ant</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>check-execstack</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<workingDirectory>${project.basedir}/scripts</workingDirectory>
|
||||
<executable>bash</executable>
|
||||
<arguments>
|
||||
<argument>execstack_check</argument>
|
||||
<argument>${build.directory}/lib/libopencv_java${lib.version.string}.so</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${resources.directory}</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>set-arch-properties</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>read-project-properties</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<files>
|
||||
<file>${build.directory}/build.properties</file>
|
||||
</files>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>1.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<id>enforce-os</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireOS>
|
||||
<family>unix</family>
|
||||
<message>This POM is written to function on UNIX family of OS.
|
||||
More specifically it should be a Debian flavour of Linux.</message>
|
||||
</requireOS>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>enforce-environment</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireEnvironmentVariable>
|
||||
<level>ERROR</level>
|
||||
<variableName>ANT_HOME</variableName>
|
||||
<message>$ANT_HOME is not set. Build may fail.</message>
|
||||
</requireEnvironmentVariable>
|
||||
<requireEnvironmentVariable>
|
||||
<level>ERROR</level>
|
||||
<variableName>JAVA_HOME</variableName>
|
||||
<message>$JAVA_HOME is not set. Build will fail.</message>
|
||||
</requireEnvironmentVariable>
|
||||
<requireEnvironmentVariable>
|
||||
<level>WARN</level>
|
||||
<variableName>MAKEFLAGS</variableName>
|
||||
<message>No MAKEFLAGS environment variable. Build may be slow.
|
||||
To speed up the build you can try exporting MAKEFLAGS=-jX where X equals the number of parallel builds.</message>
|
||||
</requireEnvironmentVariable>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<phase>process-resources</phase>
|
||||
<id>check-versions-match</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireProperty>
|
||||
<property>project.version</property>
|
||||
<regex>${opencv.version}</regex>
|
||||
<regexMessage>The Maven POM version ${project.version} does not match the extracted OpenCV version ${opencv.version}.
|
||||
To correct this please execute the following Maven command from the Maven root directory:
|
||||
mvn versions:set -DnewVersion=$(. ./opencv/scripts/functions && cd ./opencv/scripts && extract_version && echo $REPLY)</regexMessage>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>2.3.7</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Export-Package>*</Export-Package>
|
||||
<Bundle-NativeCode>${nativelibrary.name};osname=linux;processor=${osgi.processor}</Bundle-NativeCode>
|
||||
<Include-Resource>${build.directory}/lib/${nativelibrary.name}</Include-Resource>
|
||||
</instructions>
|
||||
<manifestLocation>${build.directory}/manifest</manifestLocation>
|
||||
<niceManifest>true</niceManifest>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.googlecode.cmake-maven-project</groupId>
|
||||
<artifactId>cmake-maven-plugin</artifactId>
|
||||
<version>3.4.1-b2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<id>cmake-generate</id>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourcePath>../../..</sourcePath>
|
||||
<targetPath>../../../build</targetPath>
|
||||
<generator>Unix Makefiles</generator>
|
||||
<options>
|
||||
<option>-DBUILD_SHARED_LIBS:BOOL=OFF</option>
|
||||
</options>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<id>cmake-compile</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>opencv_java</target>
|
||||
<projectDirectory>../../../build</projectDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.15</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<blueprint
|
||||
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
||||
xmlns='http://www.osgi.org/xmlns/blueprint/v1.0.0'
|
||||
xsi:schemaLocation='http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd'>
|
||||
|
||||
<bean id="opencvnativeloader" class="org.opencv.osgi.OpenCVNativeLoader" scope="singleton" init-method="init" />
|
||||
|
||||
<service id="opencvtestservice" ref="opencvnativeloader" interface="org.opencv.osgi.OpenCVInterface" />
|
||||
|
||||
</blueprint>
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
##################################################################################################
|
||||
#
|
||||
# This script checks for the required Debian packages are installed
|
||||
# to build OpenCV.
|
||||
# Commandline parameters:
|
||||
# $@ These are the names of the packages to check with 'dpkg'. Multiple values may
|
||||
# be specified per package by using pipe as a delimiter, e.g. libpng-dev|libpng12-dev.
|
||||
# Multiple values are evaluated left-to-right and the first found prevents checking of
|
||||
# the remaining package options.
|
||||
#
|
||||
# -o <package_name> Specifying this switch with a package name marks it as optional
|
||||
# i.e. it is not required to be installed.
|
||||
#
|
||||
# Returns:
|
||||
# 0 - All packages installed (success)
|
||||
# 1 - One or more packages missing (failure)
|
||||
#
|
||||
# Kerry Billingham <contact (at) avionicengineers (d0t) com>
|
||||
# 20 April 2016
|
||||
#
|
||||
##################################################################################################
|
||||
red=$'\e[1;31m'
|
||||
green=$'\e[1;32m'
|
||||
yellow=$'\e[1;33m'
|
||||
end=$'\e[0m'
|
||||
check_message="Checking for "
|
||||
declare -i packageMissing=0
|
||||
declare -i installed=1
|
||||
|
||||
#########################
|
||||
# Function declarations.
|
||||
#########################
|
||||
function check_package() {
|
||||
check_message="Checking for package "
|
||||
dpkg -s $1 &>/dev/null
|
||||
is_installed=$?
|
||||
if [ ${is_installed} -ne 0 ]; then
|
||||
printf "%-80s%s\n" "$2${check_message}${red}$1" " MISSING.${end}"
|
||||
packageMissing=1
|
||||
else
|
||||
printf "%-80s%s\n" "$2${check_message}${green}$1" " INSTALLED.${end}"
|
||||
packageMissing=0
|
||||
fi
|
||||
return $is_installed
|
||||
}
|
||||
|
||||
# Main part of script.
|
||||
ORIGINAL_IFS=$IFS
|
||||
|
||||
dpkg -? &>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "%-80s%s\n" "${check_message} ${red}'dpkg'" " MISSING.${end}"
|
||||
exit 1
|
||||
else
|
||||
printf "%-80s%s\n" "${check_message} ${green}'dpkg'" " INSTALLED.${end}"
|
||||
fi
|
||||
|
||||
while getopts o: option; do
|
||||
case $option in
|
||||
o)
|
||||
IFS="|"
|
||||
packageChoices=( ${OPTARG} )
|
||||
if [ ${#packageChoices[@]} -gt 1 ]; then
|
||||
echo "Optional package. One of ${yellow}${packageChoices[@]}${end} can be installed."
|
||||
for choice in ${packageChoices[@]}; do
|
||||
check_package ${choice} " "
|
||||
if [ $? -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Optional package ${yellow}${packageChoices}${end}"
|
||||
check_package ${OPTARG} " "
|
||||
fi
|
||||
IFS=$ORIGINAL_IFS
|
||||
;;
|
||||
\?)
|
||||
echo "No option found"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND-1))
|
||||
packageArray=( $@ )
|
||||
for package in ${packageArray[@]}; do
|
||||
IFS="|"
|
||||
packageChoices=( ${package} )
|
||||
if [ ${#packageChoices[@]} -gt 1 ]; then
|
||||
echo "Multiple options. One of ${yellow}${packageChoices[@]}${end} must be installed."
|
||||
for choice in ${packageChoices[@]}; do
|
||||
check_package ${choice} " "
|
||||
if [ $? -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
check_package ${package} ""
|
||||
fi
|
||||
done
|
||||
|
||||
exit $packageMissing
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
##################################################################
|
||||
#
|
||||
# This script will clear the executable flag on
|
||||
# the specified library and then check it has
|
||||
# been cleared as a separate operation.
|
||||
#
|
||||
# $1 - The absolute path to the OpenCV native library.
|
||||
#
|
||||
# Returns:
|
||||
# 0 - The executable flag has been cleared
|
||||
# 1 - The executable flag could NOT be cleared (failure).
|
||||
#
|
||||
# Kerry Billingham <contact (at) avionicengineers (d0t) com>
|
||||
# 11 March 2017
|
||||
#
|
||||
##################################################################
|
||||
red=$'\e[1;31m'
|
||||
green=$'\e[1;32m'
|
||||
end=$'\e[0m'
|
||||
echo "${green}[INFO] Checking that the native library executable stack flag is NOT set.${end}"
|
||||
BINARY=execstack
|
||||
$BINARY --help > /dev/null || BINARY=/usr/sbin/execstack
|
||||
$BINARY -c $1
|
||||
$BINARY -q $1 | grep -o ^-
|
||||
if [ $? -ne 0 ]; then
|
||||
echo
|
||||
echo "${red}[ERROR] The Executable Flag could not be cleared on the library $1.${end}"
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
###############################################################
|
||||
#
|
||||
# Defines some common functions.
|
||||
#
|
||||
# Kerry Billingham <contact [At] AvionicEngineers.{com]>
|
||||
#
|
||||
##############################################################
|
||||
majorHashDefine="#define CV_VERSION_MAJOR"
|
||||
minorHashDefine="#define CV_VERSION_MINOR"
|
||||
revisionHashDefine="#define CV_VERSION_REVISION"
|
||||
statusHashDefine="#define CV_VERSION_STATUS"
|
||||
versionHeader="../../../../modules/core/include/opencv2/core/version.hpp"
|
||||
|
||||
function extract_version() {
|
||||
minorVersion=$(grep "${minorHashDefine}" $versionHeader | grep -o ".$")
|
||||
majorVersion=$(grep "${majorHashDefine}" $versionHeader | grep -o ".$")
|
||||
revision=$(grep "${revisionHashDefine}" $versionHeader | grep -o ".$")
|
||||
|
||||
REPLY="${majorVersion}.${minorVersion}.${revision}"
|
||||
}
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
#####################################################################
|
||||
# This script extracts several properties and then writes them to a
|
||||
# to a file, 'build.properties'. These properties include:
|
||||
#
|
||||
# 1. OpenCV version.
|
||||
# 2. OpenCV version as a string for use by Maven.
|
||||
# 3. The CPU binary word size.
|
||||
# 4. Architecture string.
|
||||
# 4. OSGi compatible CPU architecture string.
|
||||
#
|
||||
# There is no need to execute this script directly as it will be
|
||||
# called during the Maven build process.
|
||||
#
|
||||
# Command-line parameters:
|
||||
# $1 - The build directory and where the output file will be written
|
||||
# $2 - The name of the output file to write to.
|
||||
#
|
||||
# Returns:
|
||||
# 0 - Successfully written the properties file.
|
||||
# 1 - Error occurred such as build directory does not exist
|
||||
# or OpenCV version could not be determined or an
|
||||
# unexpected error.
|
||||
#
|
||||
# Kerry Billingham <contact (at) avionicengineers (d0t) com>
|
||||
# 20 April 2016
|
||||
#
|
||||
#####################################################################
|
||||
|
||||
# Include some external functions and variables
|
||||
. ./functions
|
||||
|
||||
#Test build directory exists
|
||||
if [ ! -n "$1" ] || [ ! -d $1 ];then
|
||||
echo "Build directory not specified or does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${versionHeader}" ] && [ -e ${versionHeader} ];then
|
||||
|
||||
extract_version
|
||||
|
||||
bits=$(getconf LONG_BIT)
|
||||
architecture=$(arch)
|
||||
osgiProcessor="Not Set"
|
||||
|
||||
case ${architecture} in
|
||||
x86*)
|
||||
echo "This is x86 (32 | 64) bit"
|
||||
case ${bits} in
|
||||
32)
|
||||
osgiProcessor="x86"
|
||||
;;
|
||||
64)
|
||||
osgiProcessor="x86_64"
|
||||
;;
|
||||
*)
|
||||
osgiProcessor="Unknown"
|
||||
esac
|
||||
;;
|
||||
arm*)
|
||||
echo "This is ARM"
|
||||
byteOrder=$(lscpu | grep -i "byte order")
|
||||
shopt -s nocasematch
|
||||
if [[ "${byteOrder}" == *little* ]]; then
|
||||
osgiProcessor="arm_le"
|
||||
elif [[ "${byteOrder}}" == *big* ]]; then
|
||||
osgiProcessor="arm_be"
|
||||
fi
|
||||
shopt -u nocasematch
|
||||
;;
|
||||
*)
|
||||
echo "This is unknown architecture"
|
||||
esac
|
||||
|
||||
echo "The version number will be ${majorVersion}.${minorVersion}.${revision}"
|
||||
echo "opencv.version=${majorVersion}.${minorVersion}.${revision}" > ${1}/${2}
|
||||
echo "lib.version.string=${majorVersion}${minorVersion}${revision}" >> ${1}/${2}
|
||||
echo "bits=${bits}" >> ${1}/${2}
|
||||
echo "architecture=$(arch)" >> ${1}/${2}
|
||||
echo "osgi.processor=${osgiProcessor}" >> ${1}/${2}
|
||||
exit 0
|
||||
else
|
||||
echo "Could not locate file ${versionHeader} to determine versioning."
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,57 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-parent</artifactId>
|
||||
<version>5.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>OpenCV Parent POM</name>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>License Agreement For Open Source Computer Vision Library (Apache 2.0 License)</name>
|
||||
<url>http://opencv.org/license.html</url>
|
||||
</license>
|
||||
</licenses>
|
||||
<url>http://opencv.org/</url>
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/opencv/opencv.git</connection>
|
||||
<url>https://github.com/opencv/opencv</url>
|
||||
</scm>
|
||||
<contributors>
|
||||
<contributor>
|
||||
<name>Kerry Billingham</name>
|
||||
<email>contact (at) AvionicEngineers (d0t) c(0)m</email>
|
||||
<organization>Java Technics</organization>
|
||||
<url>www.javatechnics.com</url>
|
||||
</contributor>
|
||||
</contributors>
|
||||
|
||||
<properties>
|
||||
<nativelibrary.name>libopencv_java${lib.version.string}.so</nativelibrary.name>
|
||||
<pax.exam.version>4.8.0</pax.exam.version>
|
||||
<maven.compiler.source>1.7</maven.compiler.source>
|
||||
<maven.compiler.target>1.7</maven.compiler.target>
|
||||
<download.cmake>false</download.cmake>
|
||||
</properties>
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>${repo.name}</id>
|
||||
<url>${repo.url}</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<modules>
|
||||
<module>opencv</module>
|
||||
</modules>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>opencv-it</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>${OPENCV_APPLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${OPENCV_APPLE_BUNDLE_ID}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${OPENCV_LIBVERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${OPENCV_LIBVERSION}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Executable
+132
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
The script builds OpenCV.framework for OSX.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import os, os.path, sys, argparse, traceback, multiprocessing
|
||||
|
||||
# import common code
|
||||
sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios'))
|
||||
from build_framework import Builder
|
||||
sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../apple'))
|
||||
from cv_build_utils import print_error, get_cmake_version
|
||||
|
||||
MACOSX_DEPLOYMENT_TARGET='10.12' # default, can be changed via command line options or environment variable
|
||||
|
||||
class OSXBuilder(Builder):
|
||||
|
||||
def checkCMakeVersion(self):
|
||||
assert get_cmake_version() >= (3, 17), "CMake 3.17 or later is required. Current version is {}".format(get_cmake_version())
|
||||
|
||||
def getObjcTarget(self, target):
|
||||
# Obj-C generation target
|
||||
if target == "Catalyst":
|
||||
return 'ios'
|
||||
else:
|
||||
return 'osx'
|
||||
|
||||
def getToolchain(self, arch, target):
|
||||
return None
|
||||
|
||||
def getBuildCommand(self, arch, target):
|
||||
buildcmd = [
|
||||
"xcodebuild",
|
||||
"MACOSX_DEPLOYMENT_TARGET=" + os.environ['MACOSX_DEPLOYMENT_TARGET'],
|
||||
"ARCHS=%s" % arch,
|
||||
"-sdk", "macosx" if target == "Catalyst" else target.lower(),
|
||||
"-configuration", "Debug" if self.debug else "Release",
|
||||
"-parallelizeTargets",
|
||||
"-jobs", str(multiprocessing.cpu_count())
|
||||
]
|
||||
|
||||
if target == "Catalyst":
|
||||
buildcmd.append("-destination 'platform=macOS,arch=%s,variant=Mac Catalyst'" % arch)
|
||||
buildcmd.append("-UseModernBuildSystem=YES")
|
||||
buildcmd.append("SKIP_INSTALL=NO")
|
||||
buildcmd.append("BUILD_LIBRARY_FOR_DISTRIBUTION=YES")
|
||||
buildcmd.append("TARGETED_DEVICE_FAMILY=\"1,2\"")
|
||||
buildcmd.append("SDKROOT=iphoneos")
|
||||
buildcmd.append("SUPPORTS_MAC_CATALYST=YES")
|
||||
|
||||
return buildcmd
|
||||
|
||||
def getInfoPlist(self, builddirs):
|
||||
return os.path.join(builddirs[0], "osx", "Info.plist")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
folder = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
|
||||
parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for OSX.')
|
||||
# TODO: When we can make breaking changes, we should make the out argument explicit and required like in build_xcframework.py.
|
||||
parser.add_argument('out', metavar='OUTDIR', help='folder to put built framework')
|
||||
parser.add_argument('--opencv', metavar='DIR', default=folder, help='folder with opencv repository (default is "../.." relative to script location)')
|
||||
parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
|
||||
parser.add_argument('--without', metavar='MODULE', default=[], action='append', help='OpenCV modules to exclude from the framework. To exclude multiple, specify this flag again, e.g. "--without video --without objc"')
|
||||
parser.add_argument('--disable', metavar='FEATURE', default=[], action='append', help='OpenCV features to disable (add WITH_*=OFF). To disable multiple, specify this flag again, e.g. "--disable tbb --disable openmp"')
|
||||
parser.add_argument('--dynamic', default=False, action='store_true', help='build dynamic framework (default is "False" - builds static framework)')
|
||||
parser.add_argument('--enable_nonfree', default=False, dest='enablenonfree', action='store_true', help='enable non-free modules (disabled by default)')
|
||||
parser.add_argument('--macosx_deployment_target', default=os.environ.get('MACOSX_DEPLOYMENT_TARGET', MACOSX_DEPLOYMENT_TARGET), help='specify MACOSX_DEPLOYMENT_TARGET')
|
||||
parser.add_argument('--build_only_specified_archs', default=False, action='store_true', help='if enabled, only directly specified archs are built and defaults are ignored')
|
||||
parser.add_argument('--archs', default=None, help='(Deprecated! Prefer --macos_archs instead.) Select target ARCHS (set to "x86_64,arm64" to build Universal Binary for Big Sur and later). Default is "x86_64".')
|
||||
parser.add_argument('--macos_archs', default=None, help='Select target ARCHS (set to "x86_64,arm64" to build Universal Binary for Big Sur and later). Default is "x86_64"')
|
||||
parser.add_argument('--catalyst_archs', default=None, help='Select target ARCHS (set to "x86_64,arm64" to build Universal Binary for Big Sur and later). Default is None')
|
||||
parser.add_argument('--debug', action='store_true', help='Build "Debug" binaries (CMAKE_BUILD_TYPE=Debug)')
|
||||
parser.add_argument('--debug_info', action='store_true', help='Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)')
|
||||
parser.add_argument('--framework_name', default='opencv2', dest='framework_name', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
|
||||
parser.add_argument('--legacy_build', default=False, dest='legacy_build', action='store_true', help='Build legacy framework (default: False, equivalent to "--framework_name=opencv2 --without=objc")')
|
||||
parser.add_argument('--run_tests', default=False, dest='run_tests', action='store_true', help='Run tests')
|
||||
parser.add_argument('--doc_hosting_base_path', default=None, dest='hosting_base_path', action='store_true', help='Documentation hosting base path')
|
||||
parser.add_argument('--disable-swift', default=False, dest='swiftdisabled', action='store_true', help='Disable building of Swift extensions')
|
||||
|
||||
args, unknown_args = parser.parse_known_args()
|
||||
if unknown_args:
|
||||
print("The following args are not recognized and will not be used: %s" % unknown_args)
|
||||
|
||||
os.environ['MACOSX_DEPLOYMENT_TARGET'] = args.macosx_deployment_target
|
||||
print('Using MACOSX_DEPLOYMENT_TARGET=' + os.environ['MACOSX_DEPLOYMENT_TARGET'])
|
||||
|
||||
macos_archs = None
|
||||
if args.archs:
|
||||
# The archs flag is replaced by macos_archs. If the user specifies archs,
|
||||
# treat it as if the user specified the macos_archs flag instead.
|
||||
args.macos_archs = args.archs
|
||||
print("--archs is deprecated! Prefer --macos_archs instead.")
|
||||
if args.macos_archs:
|
||||
macos_archs = args.macos_archs.split(',')
|
||||
elif not args.build_only_specified_archs:
|
||||
# Supply defaults
|
||||
macos_archs = ["x86_64"]
|
||||
print('Using MacOS ARCHS=' + str(macos_archs))
|
||||
|
||||
catalyst_archs = None
|
||||
if args.catalyst_archs:
|
||||
catalyst_archs = args.catalyst_archs.split(',')
|
||||
# TODO: To avoid breaking existing CI, catalyst_archs has no defaults. When we can make a breaking change, this should specify a default arch.
|
||||
print('Using Catalyst ARCHS=' + str(catalyst_archs))
|
||||
|
||||
# Prevent the build from happening if the same architecture is specified for multiple platforms.
|
||||
# When `lipo` is run to stitch the frameworks together into a fat framework, it'll fail, so it's
|
||||
# better to stop here while we're ahead.
|
||||
if macos_archs and catalyst_archs:
|
||||
duplicate_archs = set(macos_archs).intersection(catalyst_archs)
|
||||
if duplicate_archs:
|
||||
print_error("Cannot have the same architecture for multiple platforms in a fat framework! Consider using build_xcframework.py in the apple platform folder instead. Duplicate archs are %s" % duplicate_archs)
|
||||
exit(1)
|
||||
|
||||
if args.legacy_build:
|
||||
args.framework_name = "opencv2"
|
||||
if not "objc" in args.without:
|
||||
args.without.append("objc")
|
||||
|
||||
targets = []
|
||||
if not macos_archs and not catalyst_archs:
|
||||
print_error("--macos_archs and --catalyst_archs are undefined; nothing will be built.")
|
||||
sys.exit(1)
|
||||
if macos_archs:
|
||||
targets.append((macos_archs, "MacOSX"))
|
||||
if catalyst_archs:
|
||||
targets.append((catalyst_archs, "Catalyst")),
|
||||
|
||||
b = OSXBuilder(args.opencv, args.contrib, args.dynamic, args.without, args.disable, args.enablenonfree, targets, args.debug, args.debug_info, args.framework_name, args.run_tests, args.hosting_base_path, args.swiftdisabled)
|
||||
b.build(args.out)
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This script runs OpenCV.framework tests for OSX.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import os, os.path, sys, argparse, traceback, multiprocessing
|
||||
|
||||
# import common code
|
||||
sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios'))
|
||||
from run_tests import TestRunner
|
||||
|
||||
MACOSX_DEPLOYMENT_TARGET='10.12' # default, can be changed via command line options or environment variable
|
||||
|
||||
class OSXTestRunner(TestRunner):
|
||||
|
||||
def getToolchain(self):
|
||||
return None
|
||||
|
||||
def getCMakeArgs(self):
|
||||
args = TestRunner.getCMakeArgs(self)
|
||||
args = args + [
|
||||
'-DMACOSX_DEPLOYMENT_TARGET=%s' % os.environ['MACOSX_DEPLOYMENT_TARGET']
|
||||
]
|
||||
return args
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
script_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for OSX.')
|
||||
parser.add_argument('tests_dir', metavar='TEST_DIR', help='folder where test files are located')
|
||||
parser.add_argument('--build_dir', default=None, help='folder where test will be built (default is "../test_build" relative to tests_dir)')
|
||||
parser.add_argument('--framework_dir', default=None, help='folder where OpenCV framework is located')
|
||||
parser.add_argument('--framework_name', default='opencv2', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
|
||||
parser.add_argument('--macosx_deployment_target', default=os.environ.get('MACOSX_DEPLOYMENT_TARGET', MACOSX_DEPLOYMENT_TARGET), help='specify MACOSX_DEPLOYMENT_TARGET')
|
||||
parser.add_argument('--platform', default='macOS,arch=x86_64', help='xcodebuild platform parameter (default is macOS)')
|
||||
|
||||
args = parser.parse_args()
|
||||
os.environ['MACOSX_DEPLOYMENT_TARGET'] = args.macosx_deployment_target
|
||||
arch = "x86_64"
|
||||
target = "macOS"
|
||||
|
||||
r = OSXTestRunner(script_dir, args.tests_dir, args.build_dir if args.build_dir else os.path.join(args.tests_dir, "../test_build"), args.framework_dir, args.framework_name, arch, target, args.platform)
|
||||
r.run()
|
||||
@@ -0,0 +1,3 @@
|
||||
This folder contains toolchains and additional files that are needed for cross compilation.
|
||||
For more information see introduction tutorials for target platform in documentation:
|
||||
https://docs.opencv.org/5.x/df/d65/tutorial_table_of_content_introduction.html
|
||||
@@ -0,0 +1,16 @@
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Disable all to choose the Tests one by one
|
||||
disable=all
|
||||
|
||||
# Tests
|
||||
enable=bad-indentation, # Used when an unexpected number of indentation’s tabulations or spaces has been found.
|
||||
mixed-indentation, # Used when there are some mixed tabs and spaces in a module.
|
||||
unnecessary-semicolon, # Used when a statement is ended by a semi-colon (";"), which isn’t necessary.
|
||||
unused-variable # Used when a variable is defined but not used. (Use _var to ignore var).
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=no
|
||||
@@ -0,0 +1,289 @@
|
||||
{
|
||||
OpenCV-IPP static init
|
||||
Memcheck:Cond
|
||||
fun:ippicvGetCpuFeatures
|
||||
fun:ippicvStaticInit
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getInitializationMutex
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv22getInitializationMutexEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-SingletonBuffer
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv20allocSingletonBufferEm
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-SingletonNewBuffer
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv23allocSingletonNewBufferEm
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getStdAllocator
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3Mat15getStdAllocatorEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getOpenCLAllocator
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl18getOpenCLAllocatorEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getCoreTlsData
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv14getCoreTlsDataEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-TLS-getTlsStorage
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv*L13getTlsStorageEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-TLS-getData()
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:*setData*
|
||||
fun:_ZNK2cv16TLSDataContainer7getDataEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-parallel_for-reconfigure
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv10ThreadPool12reconfigure_Ej
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-parallel_for-instance
|
||||
Memcheck:Leak
|
||||
fun:_Znwm
|
||||
fun:*instance*
|
||||
...
|
||||
fun:_ZN2cv13parallel_for_ERKNS_5RangeERKNS_16ParallelLoopBodyEd
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-parallel_for-setNumThreads()
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv13setNumThreadsEi
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-parallel_for-getNumThreads()
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv13getNumThreadsEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getIPPSingelton
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ippL15getIPPSingeltonEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getGlobalMatOpInitializer
|
||||
Memcheck:Leak
|
||||
fun:_Znwm
|
||||
fun:_ZN2cvL25getGlobalMatOpInitializerEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-CoreTLSData
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZNK2cv7TLSDataINS_11CoreTLSDataEE3getEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getThreadID()
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv5utils11getThreadIDEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ThreadID
|
||||
Memcheck:Leak
|
||||
fun:_Znwm
|
||||
fun:_ZNK2cv7TLSDataINS_12_GLOBAL__N_18ThreadIDEE18createDataInstanceEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ThreadID-TLS
|
||||
Memcheck:Leak
|
||||
fun:_Znwm
|
||||
fun:getThreadIDTLS
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-CoreTLS
|
||||
Memcheck:Leak
|
||||
fun:_Znwm
|
||||
fun:_ZNK2cv7TLSDataINS_11CoreTLSDataEE18createDataInstanceEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-UMatDataAutoLockerTLS
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cvL21getUMatDataAutoLockerEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-haveOpenCL
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl10haveOpenCLEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-DNN-getLayerFactoryMutex
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3dnn*20getLayerFactoryMutexEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ocl::Context
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl7Context10getDefaultEb
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ocl::Device
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl6Device10getDefaultEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ocl::Queue
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl5Queue6createERKNS0_7ContextERKNS0_6DeviceE
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ocl::Program
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl6Kernel6createEPKcRKNS0_7ProgramE
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ocl::ProgramEntry
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZNK2cv3ocl8internal12ProgramEntrycvRNS0_13ProgramSourceEEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ocl::Context::getProg
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv3ocl7Context7getProgERKNS0_13ProgramSourceERKNS_6StringERS5_
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-getTraceManager()
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:getTraceManagerCallOnce
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-ITT
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:__itt_*create*
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-SingletonLogger
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cv5utils7logging8internalL26getGlobalLoggingInitStructEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-gtk_init
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gtk_init
|
||||
fun:gtk_InitSystem
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-FFmpeg-swsscale
|
||||
Memcheck:Addr16
|
||||
...
|
||||
fun:sws_scale
|
||||
fun:_ZN20CvVideoWriter_FFMPEG10writeFrameEPKhiiiii
|
||||
fun:cvWriteFrame_FFMPEG
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-GStreamer-gst_init
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst_init
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-GStreamer-gst_deinit
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst_deinit
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-GStreamer-gst_init_check
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst_init_check
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-GStreamer-gst_parse_launch_full-reachable
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:gst_parse_launch_full
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-OpenEXR-ThreadPool
|
||||
Memcheck:Leak
|
||||
fun:_Znwm
|
||||
fun:_ZN16IlmThread_opencv10ThreadPoolC1Ej
|
||||
fun:_ZN16IlmThread_opencv10ThreadPool16globalThreadPoolEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-test-gapi-thread-tls
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: possible
|
||||
fun:calloc
|
||||
fun:allocate_dtv
|
||||
fun:_dl_allocate_tls
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
{
|
||||
IPP static init
|
||||
Memcheck:Cond
|
||||
fun:ippicvGetCpuFeatures
|
||||
fun:ippicvStaticInit
|
||||
}
|
||||
|
||||
{
|
||||
TBB - allocate_via_handler_v3 issue
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:_ZN3tbb8internal23allocate_via_handler_v3Em
|
||||
}
|
||||
|
||||
{
|
||||
GTest
|
||||
Memcheck:Cond
|
||||
fun:_ZN7testing8internal11CmpHelperLEIddEENS_15AssertionResultEPKcS4_RKT_RKT0_
|
||||
}
|
||||
|
||||
{
|
||||
GTest-RegisterTests
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:RegisterTests
|
||||
...
|
||||
fun:_ZN7testing14InitGoogleTestEPiPPc
|
||||
}
|
||||
|
||||
{
|
||||
OpenCL
|
||||
Memcheck:Cond
|
||||
...
|
||||
obj:**/libOpenCL.so*
|
||||
}
|
||||
|
||||
{
|
||||
OpenCL-Intel
|
||||
Memcheck:Cond
|
||||
...
|
||||
obj:**/libigdrcl.so
|
||||
}
|
||||
|
||||
{
|
||||
OpenCL-Intel
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*/libigdrcl.so*
|
||||
}
|
||||
|
||||
{
|
||||
OpenCL
|
||||
Memcheck:Param
|
||||
ioctl(generic)
|
||||
...
|
||||
fun:clGetPlatformIDs
|
||||
}
|
||||
|
||||
{
|
||||
OpenCL-Init
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:clGetPlatformIDs
|
||||
}
|
||||
|
||||
{
|
||||
GTK-css
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gtk_css_provider*
|
||||
}
|
||||
|
||||
{
|
||||
gcrypt
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*/libgcrypt*
|
||||
}
|
||||
|
||||
{
|
||||
p11-kit
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
obj:*/libp11-kit*
|
||||
}
|
||||
|
||||
{
|
||||
gobject
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
...
|
||||
obj:*/libgobject*
|
||||
}
|
||||
|
||||
{
|
||||
tasn
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
obj:*/libtasn*.so*
|
||||
}
|
||||
|
||||
{
|
||||
dl_init
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_dl_init
|
||||
}
|
||||
|
||||
{
|
||||
dl_open
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_dl_open
|
||||
}
|
||||
|
||||
{
|
||||
GDAL
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
...
|
||||
obj:/usr/lib/libgdal.so.1.17.1
|
||||
}
|
||||
|
||||
{
|
||||
FFMPEG-sws_scale
|
||||
Memcheck:Addr16
|
||||
...
|
||||
fun:sws_scale
|
||||
...
|
||||
fun:cvWriteFrame_FFMPEG
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-orc_program_compile_full
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:orc_program_compile_full
|
||||
...
|
||||
fun:clone
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-orc_program_new_from_static_bytecode
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:orc_program_new_from_static_bytecode
|
||||
...
|
||||
fun:clone
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-matroska-other
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst*
|
||||
obj:*gstmatroska*
|
||||
...
|
||||
obj:*glib*
|
||||
fun:start_thread
|
||||
fun:clone
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-matroska-gst_riff_create_video_caps
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst_riff_create_video_caps
|
||||
obj:*gstmatroska*
|
||||
...
|
||||
fun:clone
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
GStreamer-tls
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: possible
|
||||
fun:calloc
|
||||
fun:allocate_dtv
|
||||
fun:_dl_allocate_tls
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-registry
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst_update_registry
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-plugin_load
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:gst_plugin_load_by_name
|
||||
}
|
||||
|
||||
{
|
||||
GStreamer-separate-threads
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*/libglib*
|
||||
fun:start_thread
|
||||
fun:clone
|
||||
}
|
||||
|
||||
{
|
||||
clone-unknown-leak
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:_Znwm
|
||||
obj:*
|
||||
obj:*
|
||||
fun:start_thread
|
||||
fun:clone
|
||||
}
|
||||
|
||||
{
|
||||
avcodec57-ffv1-16bit-ubuntu18
|
||||
Memcheck:Cond
|
||||
...
|
||||
obj:/usr/lib/x86_64-linux-gnu/libavcodec.so.57.107.100
|
||||
fun:avcodec_default_execute
|
||||
obj:/usr/lib/x86_64-linux-gnu/libavcodec.so.57.107.100
|
||||
fun:avcodec_encode_video2
|
||||
obj:/usr/lib/x86_64-linux-gnu/libavcodec.so.57.107.100
|
||||
fun:avcodec_send_frame
|
||||
...
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# This file is part of OpenCV project.
|
||||
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
# of this distribution and at http://opencv.org/license.html
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR AArch64)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
set(PORT_FILE ${CMAKE_SOURCE_DIR}/platforms/semihosting/include/aarch64_semihosting_port.hpp)
|
||||
|
||||
set(COMMON_FLAGS "--specs=rdimon.specs -DOPENCV_INCLUDE_PORT_FILE=\\\"${PORT_FILE}\\\"")
|
||||
|
||||
set(CMAKE_AR ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-ar${CMAKE_EXECUTABLE_SUFFIX})
|
||||
set(CMAKE_ASM_COMPILER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-gcc${CMAKE_EXECUTABLE_SUFFIX})
|
||||
set(CMAKE_C_COMPILER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-gcc${CMAKE_EXECUTABLE_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-g++${CMAKE_EXECUTABLE_SUFFIX})
|
||||
set(CMAKE_LINKER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-ld${CMAKE_EXECUTABLE_SUFFIX})
|
||||
set(CMAKE_OBJCOPY ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-objcopy${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||
set(CMAKE_RANLIB ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-ranlib${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||
set(CMAKE_SIZE ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-size${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||
set(CMAKE_STRIP ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-strip${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||
set(CMAKE_C_FLAGS ${COMMON_FLAGS} CACHE INTERNAL "")
|
||||
set(CMAKE_CXX_FLAGS ${COMMON_FLAGS} CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
set(OPENCV_SEMIHOSTING ON)
|
||||
set(OPENCV_DISABLE_THREAD_SUPPORT ON)
|
||||
set(OPENCV_DISABLE_FILESYSTEM_SUPPORT ON)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(OPENCV_FORCE_3RDPARTY_BUILD OFF)
|
||||
|
||||
|
||||
# Enable newlib.
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
|
||||
add_definitions(-D_POSIX_PATH_MAX=0)
|
||||
@@ -0,0 +1,42 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef AARCH64_BAREMETAL_PORT_HPP
|
||||
#define AARCH64_BAREMETAL_PORT_HPP
|
||||
|
||||
#include <malloc.h> // Needed for `memalign`.
|
||||
#include <sys/errno.h> // Needed for `ENOMEM`.
|
||||
|
||||
// -std=c++11 is missing the following definitions when targeting
|
||||
// semihosting on aarch64.
|
||||
#if __cplusplus == 201103L
|
||||
#include <cmath>
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
|
||||
namespace std {
|
||||
inline double cbrt(double x) {
|
||||
return ::cbrt(x);
|
||||
}
|
||||
inline double copysign(double mag, double sgn) {
|
||||
return ::copysign(mag, sgn);
|
||||
}
|
||||
} //namespace std
|
||||
#endif // __cplusplus == 201103L
|
||||
|
||||
extern "C" {
|
||||
// Redirect the implementation of `posix_memalign` to `memalign`
|
||||
// as the former is
|
||||
// missing at link time. https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html
|
||||
__attribute__((weak)) int posix_memalign(void **memptr, size_t alignment, size_t size) {
|
||||
void * ptr = memalign(alignment, size);
|
||||
if (ptr != NULL) {
|
||||
*memptr = ptr;
|
||||
return 0;
|
||||
}
|
||||
return ENOMEM;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
if(WINCE)
|
||||
# CommCtrl.lib does not exist in headless WINCE Adding this will make CMake
|
||||
# Try_Compile succeed and therefore also C/C++ ABI Detetection work
|
||||
# https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/Platform/Windows-
|
||||
# MSVC.cmake
|
||||
set(CMAKE_C_STANDARD_LIBRARIES_INIT "coredll.lib oldnames.lib")
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES_INIT ${CMAKE_C_STANDARD_LIBRARIES_INIT})
|
||||
foreach(ID EXE SHARED MODULE)
|
||||
string(APPEND CMAKE_${ID}_LINKER_FLAGS_INIT
|
||||
" /NODEFAULTLIB:libc.lib")
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -0,0 +1,35 @@
|
||||
set(CMAKE_SYSTEM_NAME WindowsCE)
|
||||
|
||||
if(NOT CMAKE_SYSTEM_VERSION)
|
||||
set(CMAKE_SYSTEM_VERSION 8.0)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SYSTEM_PROCESSOR)
|
||||
set(CMAKE_SYSTEM_PROCESSOR armv7-a)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_GENERATOR_TOOLSET)
|
||||
set(CMAKE_GENERATOR_TOOLSET CE800)
|
||||
endif()
|
||||
|
||||
# Needed to make try_compile to succeed
|
||||
if(BUILD_HEADLESS)
|
||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE
|
||||
${CMAKE_CURRENT_LIST_DIR}/arm-wince-headless-overrides.cmake)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
endif()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user