Ⅰ 如何使用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放在一个地方,就可以给所有工程使用。
Ⅱ cmake 怎么样编译库的时候加其他库
编译mac静态库
这个比较简单,直接Xcode -GXcode,然后用xcodebuild命令即可。
编译Andoird静态库
编译android库我们同样可以引入一个toolchain文件,这里我是从 android-cmake 里面下载的。
在使用这个toolchain文件之前,我们先要使用ndk自带的make-standalone-toolchain.sh脚本来生成对应平台的toolchain.这个脚本位于你的NDK的路径下面的buil/tools目录下。
比如要生成arm平台的toolchain,我们可以使用下列命令:
sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android - $ANDROID_API_LEVEL -- install - dir = . / android - toolchain -- system = darwin - x86_64 -- ndk - dir = /Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = arm - linux - androideabi - 4.8
这里的$ANDROID_NDK为你的NDK的安装路径。这段命令可以生成arm的toolchain,最终可以编译出armeabi和armeabi-v7a静态库。 如果想生成x86的toolchain,指需要使用下列命令:
sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android - $ANDROID_API_LEVEL -- install - dir = . / android - toolchain - x86 -- system = darwin - x86_64 -- ndk - dir= / Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = x86 - 4.8
最后,我们要告诉CMake使用外部toolchain文件,可以使用参数-DCMAKE_TOOLCHAIN_FILE=xxx。此外,我们还需要在导出两个环境变量给此toolchain文件:
export PATH = $ PATH : . / android - toolchain / bin
export ANDROID_STANDALONE_TOOLCHAIN = . / android - toolchain
cmake - DCMAKE_TOOLCHAIN_FILE = . . / android . toolchain . cmake - DANDROID_ABI = "armeabi" . .
Ⅲ Windows平台cmake-gui应用,具体怎么编译求大神帮助
通过‘开始’>‘所有程序’>‘CMake 2.’8>‘CMake’来运行CMake(CMake-GUI)(这里假定在简体中文Windows中运行2.8版本)
在"Where is the source code"文本框中,输入或者“browse”到源代码的根目录
在"Where to build the binaries" 文本框中,输入或者“browse”到输出文件夹。
单击屏幕下方的'Configure'按键。
选择你的目标编译平台,例如"Visual Studio 10 2010"
当系统提示是否创建构建目录的时候选择'Ok'
等待configure执行结束。
屏幕上现在会有一些配置设置,并用红色标记(这是用来指出你是第一次看到他们)。你可以在这里手动配置这些选项,不过现在我们只需要再次选择'Configure'。
等运行结束了选择"Generate"按键。
构建文件将会在你之前选择的文件夹下面产生,这时候就可以退出cmake来进行真正的编译工作。
Ⅳ cmake很简单的故障问题,怎么解决
1.开始的时候着实折腾了好长时间,一直以为是代码的问题,所以就在代码中进行了跟踪,结果怎么都找不到问题,后来就是这份代码,直接make后,替换原有的系统的协议库,发现代码没有问题,排除了代码问题。这个问题花时间很久大概有一天时间。
2.发现是编译方式不同导致的问题后,对两个文件进行了对比,发现使用Cmake编译出来的可执行文件是“no stripped”,以为是这个原因,后来就解决strip可执行文件的问题,在网上又是一顿狂找,最终使用“add_custom_command”定制命令的方式得到了解决,满心欢喜的看到所有应用文件都stripped了,满心以为这下可好了,但是替换以后仍然通讯异常,这个过程大概花了半天时间。
3.问题得不到解决很郁闷,继续对比两个文件的差异,发现即使是stripped以后,使用CMake编译出来的的文件仍然比直接使用Makefile文件make出来的文件要大不少,这些得到了一些启示,去看了下Makefile文件。通过查看Makefile和对比CMakeLists.txt文件发现,Makefile中的编译采用的宏控制,输出的是Release版本,而CMakeLists.txt中默认的输出Debug版本。找到问题所在了以后,直接又从网上找到“SET(CMAKE_BUILD_TYPE Release ON)”的方式进行了Release版本设置。
4.后来还发现CMakeLists.txt中的编译选项也是采用的默认方式,而Makefile中却有使用,所以干脆就直接将编译选项也直接拿过来。
SET(CMAKE_C_FLAGS "-O2 -pipe -fPIC -Wall -fmessage-length=0")
SET(CMAKE_CXX_FLAGS "-O2 -pipe -fPIC -Wall -fmessage-length=0")
5.然后直接进行了编译,看到编译后的应用果然文件大小又小了很多,这下觉得没有问题了,进行整体更换,reboot系统,查看模拟器与设备的通讯情况,正常。ok,这一天算是没有白费,将正常后的CMakeLists.txt都更新到svn中。
Ⅳ 编译器cmake 和g++的区别
Cmake是一个make工具,它可以根据makefile文件来调用你和编译器进行多个文件的编译和链接。用Cmake生成的就是使用你本地的编译器来编译生成那些文件。
Ⅵ 如何使用CMAKE生成makefile文件
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性。只是 CMake 的组态档取名为 CmakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 linux 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。
在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
编写 CmakeLists.txt。
执行命令 “cmake PATH” 或者 “ccmake PATH” 生成 Makefile ( PATH 是 CMakeLists.txt 所在的目录 )。
使用 make 命令进行编译
工程实例:
一. 编写各层CMakeLists.txt
主目录的主程序main.cpp
#include "hello.h"
extern Hello hello;
int main()
{
hello.Print();
return 0;
}
主目录的CMakeLists.txt
# to the root binary directory of the project as ${MAIN_BINARY_DIR}.
project (MAIN)
#version support
cmake_minimum_required(VERSION 2.8)
# Recurse into the "Hello" and "Demo" subdirectories. This does not actually
# cause another cmake executable to run. The same process will walk through
# the project's entire directory structure.
add_subdirectory (Hello)
add_subdirectory (Demo)
# Make sure the compiler can find include files from our Hello library.
include_directories (${MAIN_SOURCE_DIR}/Hello)
# Make sure the linker can find the Hello Demo library once it is built.
link_directories (${HELLO_BINARY_DIR}/Hello)
link_directories (${HELLO_BINARY_DIR}/Demo)
#define the source coedes of current directory as DIR_SRCS
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
# Add executable called "MAIN" that is built from the source files
add_executable (Main ${DIR_SRCS})
# Link the executable to the Hello Demo library.
target_link_libraries (Main Hello Demo)
定义项目名project(MAIN),使得当前目录可以用${MAIN_SOURCE_DIR},由于有2个子目录,所以需要add_subdirectory它们。由于主程序会使用到其他库,因而也需要指定连接库所在目录。
主目录下的作用是利用add_executable将当前目录下的源文件编译成Main程序,然后通过target_link_libraries链接Hello和Demo库。由于主程序文件使用了hello.h文件,所以要include_directories该目录。
---------------------------------------------------------------------------------------------------
子目录Demo的子程序demo.c
#include "hello.h"
Hello hello;
子目录Demo的CMakeLists.txt
# Make sure the compiler can find include files from our Hello library.
include_directories (${MAIN_SOURCE_DIR}/Hello)
#define the source coedes of current directory as DIR_DEMO_SRCS
AUX_SOURCE_DIRECTORY(. DIR_DEMO_SRCS)
# Add library called "Demo" that is built from the source files
add_library (Demo ${DIR_DEMO_SRCS})
Demo目录下的CMakeLists主要作用是利用add_library将当前目录源码编译成Demo库,由于该库使用到hello.h文件,所以要include_directories该目录。
---------------------------------------------------------------------------------------------------
子目录Hello的子程序hello.h
#ifndef _hello_h
#define _hello_h
class Hello
{
public:
void Print();
};
#endif
子目录Hello的子程序hello.c
#include "hello.h"
#include <stdio.h>
void Hello::Print()
{
printf("Hello, World!\n");
}
子目录Hello的CMakeLists.txt
#define the source coedes of current directory as DIR_HELLO_SRCS
AUX_SOURCE_DIRECTORY(. DIR_HELLO_SRCS)
# Add library called "hello" that is built from the source files
add_library (Hello ${DIR_HELLO_SRCS})
Hello目录下的CMakeLists主要作用是利用add_library将当前目录源码编译成Hello库。
---------------------------------------------------------------------------------------------------
二. 执行cmake命令
至此我们完成了项目中所有 CMakeLists.txt 文件的编写,进入目录 step2 中依次执行命令
#cmake .
默认当前目录,生产makefile
#make
最后编译程序
Ⅶ cmake 如何编译成debug版
回复 7# qfmeal 这些参数是make工具的,--debug 只会让make在调用编译器gcc/g++干活的时候打印更多的东西,让你看到它详细的分析和处理指令的过程。
Ⅷ 编译安装cmake时的问题怎么解决
使用opencv需要编译源码,得到库文件。可以用cmake构建项目后编译,也可以直接用官方提供的编译好的版本。 官方提供的编译库一般只是标准版本,没有附加某些库,比如tbb等,要想让opencv使用tbb等库,就只能自己构建项目后编译。 当然,一般使用的话,用官方提供的库即可。OpenCV2.3.1版本就提供编译好的库,可以直接设置使用。
Ⅸ cmake怎么编译visual studio win32
点击"configure"按钮。选择要使用的集成开发环境(IDE)。Windows系统选择"Visual Stud
注释:
即使您不进行交叉编译,也必须规定一个工具链文件。
6
如果某些配置字段为红色,请再次点击"configure"按钮。所有字段都应该为灰色。
点击OK。
Windows系统下,在您的构建目录里会生成一个可打开的.sln文件。
7
编译范例项目。在Linux或Mac里,只需"cd"到构建目录,并键入"make"。
注释:
您可以随时重置项目。操作时,删除构建目录的内容并重新启动CMake。
请勿编辑Visual Studio Project,因为它是实时生成的(详情请参见Cmake的程序说明书)。可以通过编辑Cmake文件来进行配置。