File: test_cmake_build.py

package info (click to toggle)
opencv 4.5.1%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 268,248 kB
  • sloc: cpp: 969,170; xml: 682,525; python: 36,732; lisp: 30,170; java: 25,155; ansic: 7,927; javascript: 5,643; objc: 2,041; sh: 935; cs: 601; perl: 494; makefile: 145
file content (154 lines) | stat: -rw-r--r-- 5,842 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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 2.8)

# Enable C++11
set(CMAKE_CXX_STANDARD 11)
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)