xref: /OK3568_Linux_fs/yocto/poky/meta/classes/cmake.bbclass (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun# Path to the CMake file to process.
2*4882a593SmuzhiyunOECMAKE_SOURCEPATH ??= "${S}"
3*4882a593Smuzhiyun
4*4882a593SmuzhiyunDEPENDS:prepend = "cmake-native "
5*4882a593SmuzhiyunB = "${WORKDIR}/build"
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun# What CMake generator to use.
8*4882a593Smuzhiyun# The supported options are "Unix Makefiles" or "Ninja".
9*4882a593SmuzhiyunOECMAKE_GENERATOR ?= "Ninja"
10*4882a593Smuzhiyun
11*4882a593Smuzhiyunpython() {
12*4882a593Smuzhiyun    generator = d.getVar("OECMAKE_GENERATOR")
13*4882a593Smuzhiyun    if "Unix Makefiles" in generator:
14*4882a593Smuzhiyun        args = "-G '" + generator +  "' -DCMAKE_MAKE_PROGRAM=" + d.getVar("MAKE")
15*4882a593Smuzhiyun        d.setVar("OECMAKE_GENERATOR_ARGS", args)
16*4882a593Smuzhiyun        d.setVarFlag("do_compile", "progress", "percent")
17*4882a593Smuzhiyun    elif "Ninja" in generator:
18*4882a593Smuzhiyun        args = "-G '" + generator + "' -DCMAKE_MAKE_PROGRAM=ninja"
19*4882a593Smuzhiyun        d.appendVar("DEPENDS", " ninja-native")
20*4882a593Smuzhiyun        d.setVar("OECMAKE_GENERATOR_ARGS", args)
21*4882a593Smuzhiyun        d.setVarFlag("do_compile", "progress", r"outof:^\[(\d+)/(\d+)\]\s+")
22*4882a593Smuzhiyun    else:
23*4882a593Smuzhiyun        bb.fatal("Unknown CMake Generator %s" % generator)
24*4882a593Smuzhiyun}
25*4882a593SmuzhiyunOECMAKE_AR ?= "${AR}"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun# Compiler flags
28*4882a593SmuzhiyunOECMAKE_C_FLAGS ?= "${HOST_CC_ARCH} ${TOOLCHAIN_OPTIONS} ${CFLAGS}"
29*4882a593SmuzhiyunOECMAKE_CXX_FLAGS ?= "${HOST_CC_ARCH} ${TOOLCHAIN_OPTIONS} ${CXXFLAGS}"
30*4882a593SmuzhiyunOECMAKE_C_FLAGS_RELEASE ?= "-DNDEBUG"
31*4882a593SmuzhiyunOECMAKE_CXX_FLAGS_RELEASE ?= "-DNDEBUG"
32*4882a593SmuzhiyunOECMAKE_C_LINK_FLAGS ?= "${HOST_CC_ARCH} ${TOOLCHAIN_OPTIONS} ${CPPFLAGS} ${LDFLAGS}"
33*4882a593SmuzhiyunOECMAKE_CXX_LINK_FLAGS ?= "${HOST_CC_ARCH} ${TOOLCHAIN_OPTIONS} ${CXXFLAGS} ${LDFLAGS}"
34*4882a593Smuzhiyun
35*4882a593Smuzhiyundef oecmake_map_compiler(compiler, d):
36*4882a593Smuzhiyun    args = d.getVar(compiler).split()
37*4882a593Smuzhiyun    if args[0] == "ccache":
38*4882a593Smuzhiyun        return args[1], args[0]
39*4882a593Smuzhiyun    return args[0], ""
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun# C/C++ Compiler (without cpu arch/tune arguments)
42*4882a593SmuzhiyunOECMAKE_C_COMPILER ?= "${@oecmake_map_compiler('CC', d)[0]}"
43*4882a593SmuzhiyunOECMAKE_C_COMPILER_LAUNCHER ?= "${@oecmake_map_compiler('CC', d)[1]}"
44*4882a593SmuzhiyunOECMAKE_CXX_COMPILER ?= "${@oecmake_map_compiler('CXX', d)[0]}"
45*4882a593SmuzhiyunOECMAKE_CXX_COMPILER_LAUNCHER ?= "${@oecmake_map_compiler('CXX', d)[1]}"
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun# clear compiler vars for allarch to avoid sig hash difference
48*4882a593SmuzhiyunOECMAKE_C_COMPILER_allarch = ""
49*4882a593SmuzhiyunOECMAKE_C_COMPILER_LAUNCHER_allarch = ""
50*4882a593SmuzhiyunOECMAKE_CXX_COMPILER_allarch = ""
51*4882a593SmuzhiyunOECMAKE_CXX_COMPILER_LAUNCHER_allarch = ""
52*4882a593Smuzhiyun
53*4882a593SmuzhiyunOECMAKE_RPATH ?= ""
54*4882a593SmuzhiyunOECMAKE_PERLNATIVE_DIR ??= ""
55*4882a593SmuzhiyunOECMAKE_EXTRA_ROOT_PATH ?= ""
56*4882a593Smuzhiyun
57*4882a593SmuzhiyunOECMAKE_FIND_ROOT_PATH_MODE_PROGRAM = "ONLY"
58*4882a593SmuzhiyunOECMAKE_FIND_ROOT_PATH_MODE_PROGRAM:class-native = "BOTH"
59*4882a593Smuzhiyun
60*4882a593SmuzhiyunEXTRA_OECMAKE:append = " ${PACKAGECONFIG_CONFARGS}"
61*4882a593Smuzhiyun
62*4882a593Smuzhiyunexport CMAKE_BUILD_PARALLEL_LEVEL
63*4882a593SmuzhiyunCMAKE_BUILD_PARALLEL_LEVEL:task-compile = "${@oe.utils.parallel_make(d, False)}"
64*4882a593SmuzhiyunCMAKE_BUILD_PARALLEL_LEVEL:task-install = "${@oe.utils.parallel_make(d, True)}"
65*4882a593Smuzhiyun
66*4882a593SmuzhiyunOECMAKE_TARGET_COMPILE ?= "all"
67*4882a593SmuzhiyunOECMAKE_TARGET_INSTALL ?= "install"
68*4882a593Smuzhiyun
69*4882a593Smuzhiyundef map_host_os_to_system_name(host_os):
70*4882a593Smuzhiyun    if host_os.startswith('mingw'):
71*4882a593Smuzhiyun        return 'Windows'
72*4882a593Smuzhiyun    if host_os.startswith('linux'):
73*4882a593Smuzhiyun        return 'Linux'
74*4882a593Smuzhiyun    return host_os
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun# CMake expects target architectures in the format of uname(2),
77*4882a593Smuzhiyun# which do not always match TARGET_ARCH, so all the necessary
78*4882a593Smuzhiyun# conversions should happen here.
79*4882a593Smuzhiyundef map_host_arch_to_uname_arch(host_arch):
80*4882a593Smuzhiyun    if host_arch == "powerpc":
81*4882a593Smuzhiyun        return "ppc"
82*4882a593Smuzhiyun    if host_arch == "powerpc64le":
83*4882a593Smuzhiyun        return "ppc64le"
84*4882a593Smuzhiyun    if host_arch == "powerpc64":
85*4882a593Smuzhiyun        return "ppc64"
86*4882a593Smuzhiyun    return host_arch
87*4882a593Smuzhiyun
88*4882a593Smuzhiyuncmake_do_generate_toolchain_file() {
89*4882a593Smuzhiyun	if [ "${BUILD_SYS}" = "${HOST_SYS}" ]; then
90*4882a593Smuzhiyun		cmake_crosscompiling="set( CMAKE_CROSSCOMPILING FALSE )"
91*4882a593Smuzhiyun	fi
92*4882a593Smuzhiyun	cat > ${WORKDIR}/toolchain.cmake <<EOF
93*4882a593Smuzhiyun# CMake system name must be something like "Linux".
94*4882a593Smuzhiyun# This is important for cross-compiling.
95*4882a593Smuzhiyun$cmake_crosscompiling
96*4882a593Smuzhiyunset( CMAKE_SYSTEM_NAME ${@map_host_os_to_system_name(d.getVar('HOST_OS'))} )
97*4882a593Smuzhiyunset( CMAKE_SYSTEM_PROCESSOR ${@map_host_arch_to_uname_arch(d.getVar('HOST_ARCH'))} )
98*4882a593Smuzhiyunset( CMAKE_C_COMPILER ${OECMAKE_C_COMPILER} )
99*4882a593Smuzhiyunset( CMAKE_CXX_COMPILER ${OECMAKE_CXX_COMPILER} )
100*4882a593Smuzhiyunset( CMAKE_C_COMPILER_LAUNCHER ${OECMAKE_C_COMPILER_LAUNCHER} )
101*4882a593Smuzhiyunset( CMAKE_CXX_COMPILER_LAUNCHER ${OECMAKE_CXX_COMPILER_LAUNCHER} )
102*4882a593Smuzhiyunset( CMAKE_ASM_COMPILER ${OECMAKE_C_COMPILER} )
103*4882a593Smuzhiyunfind_program( CMAKE_AR ${OECMAKE_AR} DOC "Archiver" REQUIRED )
104*4882a593Smuzhiyun
105*4882a593Smuzhiyunset( CMAKE_C_FLAGS "${OECMAKE_C_FLAGS}" CACHE STRING "CFLAGS" )
106*4882a593Smuzhiyunset( CMAKE_CXX_FLAGS "${OECMAKE_CXX_FLAGS}" CACHE STRING "CXXFLAGS" )
107*4882a593Smuzhiyunset( CMAKE_ASM_FLAGS "${OECMAKE_C_FLAGS}" CACHE STRING "ASM FLAGS" )
108*4882a593Smuzhiyunset( CMAKE_C_FLAGS_RELEASE "${OECMAKE_C_FLAGS_RELEASE}" CACHE STRING "Additional CFLAGS for release" )
109*4882a593Smuzhiyunset( CMAKE_CXX_FLAGS_RELEASE "${OECMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Additional CXXFLAGS for release" )
110*4882a593Smuzhiyunset( CMAKE_ASM_FLAGS_RELEASE "${OECMAKE_C_FLAGS_RELEASE}" CACHE STRING "Additional ASM FLAGS for release" )
111*4882a593Smuzhiyunset( CMAKE_C_LINK_FLAGS "${OECMAKE_C_LINK_FLAGS}" CACHE STRING "LDFLAGS" )
112*4882a593Smuzhiyunset( CMAKE_CXX_LINK_FLAGS "${OECMAKE_CXX_LINK_FLAGS}" CACHE STRING "LDFLAGS" )
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun# only search in the paths provided so cmake doesnt pick
115*4882a593Smuzhiyun# up libraries and tools from the native build machine
116*4882a593Smuzhiyunset( CMAKE_FIND_ROOT_PATH ${STAGING_DIR_HOST} ${STAGING_DIR_NATIVE} ${CROSS_DIR} ${OECMAKE_PERLNATIVE_DIR} ${OECMAKE_EXTRA_ROOT_PATH} ${EXTERNAL_TOOLCHAIN} ${HOSTTOOLS_DIR})
117*4882a593Smuzhiyunset( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY )
118*4882a593Smuzhiyunset( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ${OECMAKE_FIND_ROOT_PATH_MODE_PROGRAM} )
119*4882a593Smuzhiyunset( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
120*4882a593Smuzhiyunset( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
121*4882a593Smuzhiyunset( CMAKE_PROGRAM_PATH "/" )
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun# Use qt.conf settings
124*4882a593Smuzhiyunset( ENV{QT_CONF_PATH} ${WORKDIR}/qt.conf )
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun# We need to set the rpath to the correct directory as cmake does not provide any
127*4882a593Smuzhiyun# directory as rpath by default
128*4882a593Smuzhiyunset( CMAKE_INSTALL_RPATH ${OECMAKE_RPATH} )
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun# Use RPATHs relative to build directory for reproducibility
131*4882a593Smuzhiyunset( CMAKE_BUILD_RPATH_USE_ORIGIN ON )
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun# Use our cmake modules
134*4882a593Smuzhiyunlist(APPEND CMAKE_MODULE_PATH "${STAGING_DATADIR}/cmake/Modules/")
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun# add for non /usr/lib libdir, e.g. /usr/lib64
137*4882a593Smuzhiyunset( CMAKE_LIBRARY_PATH ${libdir} ${base_libdir})
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun# add include dir to implicit includes in case it differs from /usr/include
140*4882a593Smuzhiyunlist(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES ${includedir})
141*4882a593Smuzhiyunlist(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES ${includedir})
142*4882a593Smuzhiyun
143*4882a593SmuzhiyunEOF
144*4882a593Smuzhiyun}
145*4882a593Smuzhiyun
146*4882a593Smuzhiyunaddtask generate_toolchain_file after do_patch before do_configure
147*4882a593Smuzhiyun
148*4882a593SmuzhiyunCONFIGURE_FILES = "CMakeLists.txt"
149*4882a593Smuzhiyun
150*4882a593Smuzhiyundo_configure[cleandirs] = "${@d.getVar('B') if d.getVar('S') != d.getVar('B') else ''}"
151*4882a593Smuzhiyun
152*4882a593Smuzhiyuncmake_do_configure() {
153*4882a593Smuzhiyun	if [ "${OECMAKE_BUILDPATH}" ]; then
154*4882a593Smuzhiyun		bbnote "cmake.bbclass no longer uses OECMAKE_BUILDPATH.  The default behaviour is now out-of-tree builds with B=WORKDIR/build."
155*4882a593Smuzhiyun	fi
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun	if [ "${S}" = "${B}" ]; then
158*4882a593Smuzhiyun		find ${B} -name CMakeFiles -or -name Makefile -or -name cmake_install.cmake -or -name CMakeCache.txt -delete
159*4882a593Smuzhiyun	fi
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun	# Just like autotools cmake can use a site file to cache result that need generated binaries to run
162*4882a593Smuzhiyun	if [ -e ${WORKDIR}/site-file.cmake ] ; then
163*4882a593Smuzhiyun		oecmake_sitefile="-C ${WORKDIR}/site-file.cmake"
164*4882a593Smuzhiyun	else
165*4882a593Smuzhiyun		oecmake_sitefile=
166*4882a593Smuzhiyun	fi
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun	cmake \
169*4882a593Smuzhiyun	  ${OECMAKE_GENERATOR_ARGS} \
170*4882a593Smuzhiyun	  $oecmake_sitefile \
171*4882a593Smuzhiyun	  ${OECMAKE_SOURCEPATH} \
172*4882a593Smuzhiyun	  -DCMAKE_INSTALL_PREFIX:PATH=${prefix} \
173*4882a593Smuzhiyun	  -DCMAKE_INSTALL_BINDIR:PATH=${@os.path.relpath(d.getVar('bindir'), d.getVar('prefix') + '/')} \
174*4882a593Smuzhiyun	  -DCMAKE_INSTALL_SBINDIR:PATH=${@os.path.relpath(d.getVar('sbindir'), d.getVar('prefix') + '/')} \
175*4882a593Smuzhiyun	  -DCMAKE_INSTALL_LIBEXECDIR:PATH=${@os.path.relpath(d.getVar('libexecdir'), d.getVar('prefix') + '/')} \
176*4882a593Smuzhiyun	  -DCMAKE_INSTALL_SYSCONFDIR:PATH=${sysconfdir} \
177*4882a593Smuzhiyun	  -DCMAKE_INSTALL_SHAREDSTATEDIR:PATH=${@os.path.relpath(d.getVar('sharedstatedir'), d.  getVar('prefix') + '/')} \
178*4882a593Smuzhiyun	  -DCMAKE_INSTALL_LOCALSTATEDIR:PATH=${localstatedir} \
179*4882a593Smuzhiyun	  -DCMAKE_INSTALL_LIBDIR:PATH=${@os.path.relpath(d.getVar('libdir'), d.getVar('prefix') + '/')} \
180*4882a593Smuzhiyun	  -DCMAKE_INSTALL_INCLUDEDIR:PATH=${@os.path.relpath(d.getVar('includedir'), d.getVar('prefix') + '/')} \
181*4882a593Smuzhiyun	  -DCMAKE_INSTALL_DATAROOTDIR:PATH=${@os.path.relpath(d.getVar('datadir'), d.getVar('prefix') + '/')} \
182*4882a593Smuzhiyun	  -DPYTHON_EXECUTABLE:PATH=${PYTHON} \
183*4882a593Smuzhiyun	  -DPython_EXECUTABLE:PATH=${PYTHON} \
184*4882a593Smuzhiyun	  -DPython3_EXECUTABLE:PATH=${PYTHON} \
185*4882a593Smuzhiyun	  -DLIB_SUFFIX=${@d.getVar('baselib').replace('lib', '')} \
186*4882a593Smuzhiyun	  -DCMAKE_INSTALL_SO_NO_EXE=0 \
187*4882a593Smuzhiyun	  -DCMAKE_TOOLCHAIN_FILE=${WORKDIR}/toolchain.cmake \
188*4882a593Smuzhiyun	  -DCMAKE_NO_SYSTEM_FROM_IMPORTED=1 \
189*4882a593Smuzhiyun	  -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON \
190*4882a593Smuzhiyun	  -DFETCHCONTENT_FULLY_DISCONNECTED=ON \
191*4882a593Smuzhiyun	  ${EXTRA_OECMAKE} \
192*4882a593Smuzhiyun	  -Wno-dev
193*4882a593Smuzhiyun}
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun# To disable verbose cmake logs for a given recipe or globally config metadata e.g. local.conf
196*4882a593Smuzhiyun# add following
197*4882a593Smuzhiyun#
198*4882a593Smuzhiyun# CMAKE_VERBOSE = ""
199*4882a593Smuzhiyun#
200*4882a593Smuzhiyun
201*4882a593SmuzhiyunCMAKE_VERBOSE ??= "VERBOSE=1"
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun# Then run do_compile again
204*4882a593Smuzhiyuncmake_runcmake_build() {
205*4882a593Smuzhiyun	bbnote ${DESTDIR:+DESTDIR=${DESTDIR} }${CMAKE_VERBOSE} cmake --build '${B}' "$@" -- ${EXTRA_OECMAKE_BUILD}
206*4882a593Smuzhiyun	eval ${DESTDIR:+DESTDIR=${DESTDIR} }${CMAKE_VERBOSE} cmake --build '${B}' "$@" -- ${EXTRA_OECMAKE_BUILD}
207*4882a593Smuzhiyun}
208*4882a593Smuzhiyun
209*4882a593Smuzhiyuncmake_do_compile()  {
210*4882a593Smuzhiyun	cmake_runcmake_build --target ${OECMAKE_TARGET_COMPILE}
211*4882a593Smuzhiyun}
212*4882a593Smuzhiyun
213*4882a593Smuzhiyuncmake_do_install() {
214*4882a593Smuzhiyun	DESTDIR='${D}' cmake_runcmake_build --target ${OECMAKE_TARGET_INSTALL}
215*4882a593Smuzhiyun}
216*4882a593Smuzhiyun
217*4882a593SmuzhiyunEXPORT_FUNCTIONS do_configure do_compile do_install do_generate_toolchain_file
218