cmake編譯qt5
1. Qt執行Cmake時Cmake出現這種情況時為什麼
在Qt Creator中使用OpenCV庫 (Windows 7系統下編譯成功)
編譯OpenCV2.0
1 下載tdm-mingw-1.908.0-4.4.1-2並安裝,安裝完畢添加bin到系統路徑。
2 安裝Opencv2.0 windows版本
3 安裝CMake
4 打開CMake,配置源碼與目標路徑,選擇MinGW Makefiles,生成目標Makefile
5 進入設置好的目標路徑,make,直至生成所有的庫
配置Qt Creator
Qt開發的程序一般需要藉助qmake生成makefile文件。由於qmake在解析路徑的時候不能識別空格, 因此需要確保OpenCV的安裝路徑中不能包含空格(C:/Program Files/OpenCV是不行的)。
在創建工程文件的時候(這里假設為hello.pro,後綴為pro),向工程中添加以下語句:
INCLUDEPATH+=D:/Qt/OpenCV-2.0.0/include/opencv
LIBS+=D:/Qt/OpenCV-2.0.0/lib/libcv200.dll.a/
D:/Qt/OpenCV-2.0.0/lib/libcxcore200.dll.a/
D:/Qt/OpenCV-2.0.0/lib/libml200.dll.a/
D:/Qt/OpenCV-2.0.0/lib/libcvaux200.dll.a/
D:/Qt/OpenCV-2.0.0/lib/libhighgui200.dll.a
這樣,在Qt中就可以使用Opencv 2.0 了
打開CMake,試一下,發現沒法完成configure!原因是CMAKE_MAKE_PROGRAM沒找到,這個簡單,修改該項為D:/Qt/2010.04/mingw/bin(您自個看著改)。
繼續Configure,什麼還出錯?彈出一大堆什麼dll找不到!!
好吧,我直接把D:/Qt/2010.04/mingw/bin放到環境變數中去。
Delete Catch以後再來一次,這下好了,連CMAKE_MAKE_PROGRAM都不用改了,自動找到。成功configure。
然後Generate一下。
2. 如何使用CMake進行交叉編譯
cmake交叉編譯配置
很多時候,我們在開發的時候是面對嵌入式平台,因此由於資源的限制需要用到相關的交叉編譯。即在你host宿主機上要生成target目標機的程序。裡面牽扯到相關頭文件的切換和編譯器的選擇以及環境變數的改變等,我今天僅僅簡單介紹下相關CMake在面對交叉編譯的時候,需要做的一些准備工作。
CMake給交叉編譯預留了一個很好的變數CMAKE_TOOLCHAIN_FILE,它定義了一個文件的路徑,這個文件即toolChain,裡面set了一系列你需要改變的變數和屬性,包括C_COMPILER,CXX_COMPILER,如果用Qt的話需要更改QT_QMAKE_EXECUTABLE以及如果用BOOST的話需要更改的BOOST_ROOT(具體查看相關Findxxx.cmake裡面指定的路徑)。CMake為了不讓用戶每次交叉編譯都要重新輸入這些命令,因此它帶來toolChain機制,簡而言之就是一個cmake腳本,內嵌了你需要改變以及需要set的所有交叉環境的設置。
toolChain腳本中設置的幾個重要變數
1.CMAKE_SYSTEM_NAME:
即你目標機target所在的操作系統名稱,比如ARM或者linux你就需要寫"Linux",如果Windows平台你就寫"Windows",如果你的嵌入式平台沒有相關OS你即需要寫成"Generic",只有當CMAKE_SYSTEM_NAME這個變數被設置了,CMake才認為此時正在交叉編譯,它會額外設置一個變數CMAKE_CROSSCOMPILING為TRUE.
2. CMAKE_C_COMPILER:
顧名思義,即C語言編譯器,這里可以將變數設置成完整路徑或者文件名,設置成完整路徑有一個好處就是CMake會去這個路徑下去尋找編譯相關的其他工具比如linker,binutils等,如果你寫的文件名帶有arm-elf等等前綴,CMake會識別到並且去尋找相關的交叉編譯器。
3. CMAKE_CXX_COMPILER:
同上,此時代表的是C++編譯器。
4. CMAKE_FIND_ROOT_PATH:
指定了一個或者多個優先於其他搜索路徑的搜索路徑。比如你設置了/opt/arm/,所有的Find_xxx.cmake都會優先根據這個路徑下的/usr/lib,/lib等進行查找,然後才會去你自己的/usr/lib和/lib進行查找,如果你有一些庫是不被包含在/opt/arm裡面的,你也可以顯示指定多個值給CMAKE_FIND_ROOT_PATH,比如
set(CMAKE_FIND_ROOT_PATH /opt/arm /opt/inst)
該變數能夠有效地重新定位在給定位置下進行搜索的根路徑。該變數默認為空。當使用交叉編譯時,該變數十分有用:用該變數指向目標環境的根目錄,然後CMake將會在那裡查找。
5. CMAKE_FIND_ROOT_PATH_MODE_PROGRAM:
對FIND_PROGRAM()起作用,有三種取值,NEVER,ONLY,BOTH,第一個表示不在你CMAKE_FIND_ROOT_PATH下進行查找,第二個表示只在這個路徑下查找,第三個表示先查找這個路徑,再查找全局路徑,對於這個變數來說,一般都是調用宿主機的程序,所以一般都設置成NEVER
6. CMAKE_FIND_ROOT_PATH_MODE_LIBRARY:
對FIND_LIBRARY()起作用,表示在鏈接的時候的庫的相關選項,因此這里需要設置成ONLY來保證我們的庫是在交叉環境中找的.
7. CMAKE_FIND_ROOT_PATH_MODE_INCLUDE:
對FIND_PATH()和FIND_FILE()起作用,一般來說也是ONLY,如果你想改變,一般也是在相關的FIND命令中增加option來改變局部設置,有NO_CMAKE_FIND_ROOT_PATH,ONLY_CMAKE_FIND_ROOT_PATH,BOTH_CMAKE_FIND_ROOT_PATH
8. BOOST_ROOT:
對於需要boost庫的用戶來說,相關的boost庫路徑配置也需要設置,因此這里的路徑即ARM下的boost路徑,裡面有include和lib。
9. QT_QMAKE_EXECUTABLE:
對於Qt用戶來說,需要更改相關的qmake命令切換成嵌入式版本,因此這里需要指定成相應的qmake路徑(指定到qmake本身)
toolChain demo
# this is required
SET(CMAKE_SYSTEM_NAME Linux)
# specify the cross compiler
SET(CMAKE_C_COMPILER /opt/arm/usr/bin/ppc_74xx-gcc)
SET(CMAKE_CXX_COMPILER /opt/arm/usr/bin/ppc_74xx-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /opt/arm/ppc_74xx /home/rickk/arm_inst)
# search for programs in the build host directories (not necessary)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# configure Boost and Qt
SET(QT_QMAKE_EXECUTABLE /opt/qt-embedded/qmake)
SET(BOOST_ROOT /opt/boost_arm)
這樣就完成了相關toolChain的編寫,之後,你可以靈活的選擇到底採用宿主機版本還是開發機版本,之間的區別僅僅是一條-DCMAKE_TOOLCHAIN_FILE=./toolChain.cmake,更爽的是,如果你有很多程序需要做轉移,但目標平台是同一個,你僅僅需要寫一份toolChain放在一個地方,就可以給所有工程使用。
3. Cmake動態編譯VTK庫(QVtkwidget)
在版本問題上大費周章之後,得到如下的成功嘗試
軟體版本說明:
PCl1.8.1 + VS2017 + Qt5.9.6 + Cmake + Vtk8.0.0
點擊Configure後對條目進行處理:(修改完成繼續Configure直到沒有錯誤)
1.點擊Add Entry添加
Name: CMAKE_DEBUG_POSTFIX 、Type: STRING 、Value:-gd、Description:空
讓vtk的lib最後分為debug版本跟release版本。Debug版本帶-gd。Release版本不帶-gd,方便區分.
2.勾選BUILD_SHARED_LIBS,這樣最後生成的vtk才會有dll跟lib
3.CMAKE_INSTALL_PREFIX設置為你清空的VTK文件夾(為了方便,這里選擇的路徑為PCL集成的VTK路徑)
4.勾選VTK_Group_Qt,這樣以後方便在qt裡面使用
5.修改Qt5_DIR路徑為PATH=D:/Qt/Qt5.12.0/5.12.0/msvc2017_64/lib/cmake/Qt5
6.修改VTK_QT_VERSION:STRING=5,使用Qt5修改相應版本號
7.如出現qmake路徑則修改QT_QMAKE_EXECUTABLE:FILEPATH=D:/Qt/Qt5.12.0/5.12.0/msvc2017_64/bin/qmake.exe
完成Configure,不出意外就不再顯示紅色,接著點Generate
接著以管理員身份運行VS2017,打開構建目錄下的VTK.sln
選擇Debug,x64,然後右鍵解決方案窗口的ALL_BUILD --> 生成。
漫長等待...ing
然後右鍵install --> 僅生成install
Release版本同理,先ALL_BUILD --> 生成 再 右鍵install --> 僅生成install
至此完成編譯VTK操作,接下來提取所需的QVtkwidget插件
4. Yocto編譯傑發或MTK的linux或android時的幾個問題
編譯問題1(audiomanager_7.0.bb的do_configure報錯):
錯誤:CMake Error at Plugins/PluginCommandInterfaceCAPI/cmake/CommonAPI.cmake:352 (message):
| Failed to generate files from FIDL:
手動執行一下:
$ commonapi-generator-linux-x86 -ll verbose -sk Default -d . /data/linux/hz_rs28_bm/sources/build/tmp/work/armv7a-vfp-neon-poky-linux-gnueabi/audiomanager/7.0-r1/audiomanager-7.0/Plugins/PluginCommandInterfaceCAPI/fidl/CommandInterface.fidl
-bash: /data/linux/hz_rs28_bm/sources/src/build/tools/commonapi_tool/commonapi-generator/commonapi-generator-linux-x86: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
解決(需要安裝32位的glibc庫和32位java jre環境):
$ sudo yum install glibc.i686
$ sudo yum install java-1.8.0-openjdk.i686
$ sudo ln -s /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.i386/jre/bin/java /bin/java
$ java -version (保證是32位的java)
編譯問題2(perl_5.20.0.bb的do_package報錯):
錯誤:ERROR: obj failed with exit code 256 (cmd was 『arm-poky-linux-gnueabi-obj』 –only-keep-debug
… generate_uudmap: File format not recognized
解決(tar在1.29版本之後需要exclude在路徑的前面):
sources/meta/poky/bitbake/lib/bb/fetch2/bzr.py
tar_flags = 「–exclude 『.bzr』 –exclude 『.bzrtags'」
修改成:
tar_flags = 「–exclude=』.bzr』 –exclude=』.bzrtags'」
sources/meta/poky/bitbake/lib/bb/fetch2/cvs.py
tar_flags = 「–exclude 『CVS'」
修改成:
tar_flags = 「–exclude=』CVS'」
sources/meta/poky/bitbake/lib/bb/fetch2/repo.py
tar_flags = 「–exclude 『.repo』 –exclude 『.git'」
修改成:
tar_flags = 「–exclude=』.repo』 –exclude=』.git'」
sources/meta/poky/bitbake/lib/bb/fetch2/svn.py
tar_flags = 「–exclude 『.svn'」
修改成:
tar_flags = 「–exclude=』.svn'」
sources/meta/poky/meta/recipes-devtools/quilt/quilt-0.63.inc
tar -cf – bin/ –exclude \*.in | ( cd ${D}${PTEST_PATH} && tar -xf – )
tar -cf – compat/ –exclude \*.in | ( cd ${D}${PTEST_PATH} && tar -xf – )
tar -cf – quilt/ –exclude \*.in | ( cd ${D}${PTEST_PATH} && tar -xf – )
tar -cf – test/ –exclude mail.test –exclude delete.test | ( cd ${D}${PTEST_PATH} && tar -xf – )
修改成:
tar -c –exclude=\*.in bin/ | ( cd ${D}${PTEST_PATH} && tar -xf – )
tar -c –exclude=\*.in compat/ | ( cd ${D}${PTEST_PATH} && tar -xf – )
tar -c –exclude=\*.in quilt/ | ( cd ${D}${PTEST_PATH} && tar -xf – )
tar -c –exclude=mail.test –exclude=delete.test test/ | ( cd ${D}${PTEST_PATH} && tar -xf – && chmod 777 test)
sources/meta/poky/meta/recipes-extended/sed/sed-4.2.2/sed-add-ptest.patch
+ cd $(BUILDDIR); tar -cf – $(TESTDIR) –exclude *.o | ( cd $(DESTDIR) && tar -xf – )
修改成:
+ cd $(BUILDDIR); tar -c –exclude=*.o $(TESTDIR) | ( cd $(DESTDIR) && tar -xf – )
sources/meta/poky/meta/recipes-support/attr/acl.inc
tar -cf – test/ –exclude nfs | ( cd ${D}${PTEST_PATH} && tar -xf – )
修改成:
tar -c –exclude=nfs test/ | ( cd ${D}${PTEST_PATH} && tar -xf – )
sources/meta/poky/meta/recipes-support/attr/attr.inc
tar -cf – test/ –exclude ext | ( cd ${D}${PTEST_PATH} && tar -xf – )
修改成:
tar -c –exclude=ext test/ | ( cd ${D}${PTEST_PATH} && tar -xf – )
sources/meta/poky/meta/recipes-devtools/perl/perl-ptest.inc
tar -cf – * –exclude \*.o –exclude libperl.so –exclude Makefile –exclude makefile –exclude hostperl \
–exclude miniperl –exclude generate_uudmap –exclude patches | ( cd ${D}${PTEST_PATH} && tar -xf – )
修改成:
tar -c –exclude=\*.o –exclude=libperl.so –exclude=Makefile –exclude=makefile –exclude=hostperl \
–exclude=miniperl –exclude=generate_uudmap –exclude=patches * | ( cd ${D}${PTEST_PATH} && tar -x )
編譯問題3(libunwind_1.1.bb的do_compile報錯):
錯誤:make[1]: latex2man: Command not found
解決:
$ sudo yum install texlive-tetex
$ sudo rpm -ivh ~/latex2man-1.18-2.noarch.rpm
編譯問題3(qt5-app_1.0.bb的do_compile報錯):
錯誤(有一批類似的錯誤):ld: cannot find -lgtest
解決:
$ vi atc_linux/application/btate/btate.pro
equals(MY_BUILD_SYSTEM, atc) {
LIBS += -L $(DA_LIBDIR)/lib -lgtest -lpthread -lbluetoothclient -lglobalbus -lappobj -lapputils
} else {
LIBS += -L$(DA_TOP)/application/lib -L$(DA_TOP)/../../sources/build/tmp/work/armv7a-vfp-neon-poky-linux-gnueabi/atc-binarys/1.0-r0/image/usr/lib -lgtest -lpthread -lbluetoothclient -l
globalbus -lappobj -lapputils
}
$ vi atc_linux/application/gps/gps_bin.pro
equals(MY_BUILD_SYSTEM, atc) {
LIBS += -L $(DA_LIBDIR)/lib -lapputils -lglobalbus -lappobj -lgps
} else {
LIBS += -L$(DA_TOP)/application/lib -L$(DA_TOP)/../../sources/build/tmp/work/armv7a-vfp-neon-poky-linux-gnueabi/gpsd/3.10-r0/gpsd-3.10/ -lapputils -lglobalbus -lappobj -lgps
}
$ vi atc_linux/application/dvr/dvr_bin.pro
equals(MY_BUILD_SYSTEM, atc) {
LIBS += -L${DA_TOP}/lib/lib/ -ldvr -ludev -lsurface_atc -lglobalbus -lappobj -lapputils -lstorage_atc -lgps
} else {
LIBS += -L${DA_TOP}/application/lib -L$(DA_TOP)/../../sources/build/tmp/work/armv7a-vfp-neon-poky-linux-gnueabi/gpsd/3.10-r0/gpsd-3.10/ -ldvr -ludev -lsurface_atc -lglobalbus –
lappobj -lapputils -lstorage_atc -lgps
}
$ vi atc_linux/application/dvr/dvr_bin.pro
INCLUDEPATH += ${DA_TOP}/kernel/kernel-3.18/drivers/ \
../common/ \
../utils/ \
../appobj/include/ \
../globalbus/include/ \
../appcommon/include/ \
../storage_atc/ \
../dvr/gps/ \
../gps/include/ \
../gps/includeex/ \
編譯問題4(makall報錯):
報錯:./makall: line 169: mkisofs: command not found
解決:$ sudo yum install mkisofs
編譯問題5(修改ac83xx_systemd_defconfig再編譯時報錯):
報錯:Applying patch remove-selinux-android.patch
patching file system/extras/ext4_utils/make_ext4fs.c
Hunk #1 FAILED at 62.
1 out of 1 hunk FAILED — rejects in file system/extras/ext4_utils/make_ext4fs.c
解決:
$ vi sources/meta/meta-atc/recipes-devtools/android-tools/android-tools_5.1.1.r37.bb
在裡面做個假的do_patch(),bitbake會優先使用本bb文件的do_patch()函數。
do_patch(){
}
編譯問題6(修改ac83xx_systemd_defconfig再編譯時報錯):
報錯:sources/build/tmp/work/armv7a-vfp-neon-poky-linux-gnueabi/qtbase/5.5.0+gitAUTOINC+c619d2daac-r0/git/src/corelib/tools/qregexp.cpp:3947:1: internal compiler error: in add_stores, at var-tracking.c:6000
解決:
$ cd sources/meta/poky/meta/recipes-devtools/gcc/gcc-4.9/
$ wget http://openlinux.windriver.com/overc/sources/core2_64/gcc-4.9.2-r0.1/0062-gcc-var-tracking.c-backport-from-gcc-trunk-r212178.patch
$ vi sources/meta/poky/meta/recipes-devtools/gcc/gcc-4.9.inc
file://0058-gcc-r212171.patch \
file://0059-gcc-PR-rtl-optimization-63348.patch \
file://target-gcc-includedir.patch \
file://0062-gcc-var-tracking.c-backport-from-gcc-trunk-r212178.patch \
其實就是這個文件:
$ cat 0062-gcc-var-tracking.c-backport-from-gcc-trunk-r212178.patch
From Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20M=C3=BCller-Klieser?= <[email protected]>
Date: Tue, 7 Apr 2015 16:15:11 +0200
Subject: [PATCH] gcc/var-tracking.c: backport from gcc trunk r212178
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
resolves a bug seen on cortexa8 building qt5 libraries.
2014-06-30 Joseph Myers <[email protected]>
* var-tracking.c (add_stores): Return instead of asserting if old
and new values for conditional store are the same.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212178 138bc75d-0d04-0410-961f-82ee72b054a4
Signed-off-by: Stefan Müller-Klieser <[email protected]>
---
gcc/var-tracking.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 65d8285..7c38910 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -5997,7 +5997,8 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
{
cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode);
- gcc_assert (oval != v);
+ if (oval == v)
+ return;
gcc_assert (REG_P (oloc) || MEM_P (oloc));
if (oval && !cselib_preserved_value_p (oval))
--
1.9.1
編譯問題7(修改ac83xx_systemd_defconfig再編譯時報錯):
報錯:libevdev/1.2.2-r0/libevdev-1.2.2/test/test-main.c:24:19: fatal error: check.h: No such file or directory
解決:
$ vi meta/poky/meta/recipes-support/libevdev/libevdev_1.2.2.bb
LIC_FILES_CHKSUM = 「file://COPYING;md5= \
file://libevdev/libevdev.h;endline=21;md5=″
DEPENDS += 「libcheck」
SRC_URI = 「 http://www.freedesktop.org/software/libevdev/ ${BP}.tar.xz」
編譯問題8(修改ac83xx_systemd_defconfig再編譯時報錯):
報錯:python報錯: 『do_rootfs』, lineno: 17, function
Exception: CalledProcessError: Command 『[『』, 『-ks』, …
解決: 沒有實際問題,重新編譯一次即可,可能是機器太忙導致超時,或者某個命令執行不成功。
編譯問題9(preuboot編譯工具問題):
報錯:make: armv7a-mediatek451_001_vfp-linux-gnueabi-gcc: Command not found
解決:
$ vi atc_linux/bootloader/preuboot/Makefile
#CROSS_COMPILE :=armv7a-mediatek451_001_vfp-linux-gnueabi-
CROSS_COMPILE :=arm-poky-linux-gnueabi-
$ vi ../../atc_linux/bootloader/preuboot/driver/mmc/include/linux/list.h
#ifndef NULL
#define NULL 0
#endif