热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linuxtbb安装_Linux环境下配置GoogleTest、TBB、OpenMP和OpenCV

最近逐渐把开发环境从Windows转到Linux下,原因是VisualStudio提供的环境太庞大,总感觉看不到全貌,并且对于C11的支持

最近逐渐把开发环境从Windows转到Linux下,原因是Visual Studio提供的环境太庞大,总感觉看不到全貌,并且对于C++11的支持实在是太慢了。而在Linux下,有非常大的选择空间,编辑器可以选vim或者emacs,两者都是顶级的文本编辑器(不仅仅是文本编辑器)。编译器可以选g++或者clang,两者对于C++11的支持已经几乎完整了。另外还有各种优秀的工具可以选择,可以用autotools或者cmake来build工程,用gdb进行调试,用cppcheck做静态类型检查(也可以配置到VS中),用valgrind对程序进行动态分析。这就是Linux的好处,各种优秀的工具随你组合,VS是个巨无霸,感觉程序员的创造力受到了限制。

这两天把VS上的工程全部移植到Linux上,全部用g++配合makefile进行编译,因为代码规模不是特别大,所以makefile是直接手写的。移植的过程中,一些第三方的库要配置,包括Goolge Test(Google的C++测试框架)、TBB(Intel的C++多线程库)、OpenMP(开放标准的并行程序指导性注释)和OpenCV(一个跨平台的计算机视觉库)。所以把配置的过程记录下来,方便以后查阅,也希望能够给大家提供一些参考。

一、配置Google Test

现在gtest的最新版本是1.6.0,按以下步骤下载和安装:

wget https://googletest.googlecode.com/files/gtest-1.6.0.zip

unzip gtest-1.6.0.zipcd gtest-1.6.0g++ -I./include -I./ -c ./src/gtest-all.cc

ar -rv libgtest.a gtest-all.o

注意:这边其实就是产生了libgtest.a文件,以后需要用的时候,就把这个静态库拷贝到对应的工程下,链接的时候加上它就可以了,如:

g++ –o target source1.o source2.o libgtest.a

另外,把gtest-1.6.0下面的include/gtest目录拷贝到全局头文件目录,如:

cp -r include/gtest/ /usr/local/include/

在用到gtest的文件中,用#include 指令就可以让编译器找到gtest的头文件了。

比如我写了一个比较几个常用排序的算法的测试:

#include //引入gtest头文件

#include"QuickSort.h"#include"InsertionSort.h"#include"HeapSort.h"

using namespaceCodeMood;

TEST(SortingTest, insertion_sort)//用TEST宏定义一个测试用例,括号里的两个参数起标识作用

{

vector vec =generate_random();

TIME_STD(test_sorting(insertion_sort, vec));

EXPECT_TRUE(is_sorted(begin(vec), end(vec)));//待验证的性质

}

TEST(SortingTest, heap_sort)

{

vector vec = generate_random(1);

TIME_STD(test_sorting(heap_sort, vec));

EXPECT_TRUE(is_sorted(begin(vec), end(vec)));

}

TEST(SortingTest, quick_sort)

{

vector vec =generate_random();

TIME_STD(test_sorting(quick_sort, vec));

EXPECT_TRUE(is_sorted(begin(vec), end(vec)));

}

TEST(SortingTest, std_sort)

{

vector vec =generate_random();

TIME_STD(std::sort(begin(vec), end(vec)));

EXPECT_TRUE(is_sorted(begin(vec), end(vec)));

}int main(int argc, char*argv[])

{

::testing::InitGoogleTest(&argc, argv); //初始化gtest

return RUN_ALL_TESTS(); //运行所有测试用例

}

用法很简单,从上面的例子应该就知道怎么用了,这边不具体说明用法,有兴趣的自己Google。运行结果如下:

其中TIME_STD是我自定义的一个记录函数运行时间的一个宏,gtest本身也是带时间统计的,总体来说两者时间还是差不多的。

二、配置TBB

TBB最新版本是4.1,按以下步骤下载安装:

wget http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130314oss_src.tgz

mkdir -p /opt/intel

cd/opt/inteltar zxvf ~/tbb41_20130314oss_src.tgz

cd tbb41_20130314oss

gmake

上面的操作之所以放在/opt下面,是因为想把TBB装在/opt/intel目录下,然后用环境变量的方式让编译器找到这个位置,这是TBB推荐的做法。

以上这些步骤完成之后,会在tbb41_20130314oss目录下产生build目录,里面是编译出来的结果,然后:

cd build

看到里面有两个目录:linux_ia32_gcc_cc4.8.1_libc2.12_kernel2.6.32_debug和linux_ia32_gcc_cc4.8.1_libc2.12_kernel2.6.32_release,分别是debug和release版本。

如何让编译器找到这个位置呢?推荐的做法是在~/.bashrc中添加这么几行:

如果使用release版本:

source /opt/intel/tbb41_20130314oss/build/linux_ia32_gcc_cc4.8.1_libc2.12_kernel2.6.32_release/tbbvars.shexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

如果使用debug版本:

source /opt/intel/tbb41_20130314oss/build/linux_ia32_gcc_cc4.8.1_libc2.12_kernel2.6.32_debug/tbbvars.shexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

关键在于tbbvars.sh,里面其实就是设置环境变量的过程,包括CPATH、LIBRARY_PATH和LD_LIBRARY_PATH,但是这个脚本直接将这三个环境变量设置为tbb的编译目录,而不是添加到当前的环境变量之后,所以需要注意一下。

在使用的时候,加上必要的头文件#include ,并且需要通过-ltbb选项进行链接。下面是我用TBB里面的parallel_sort进行排序的的代码:

#include #include#include#include#include#include#include#include#includeusing namespace std;

constint SIZE = 10000000;#define TIME_STD(X) { \auto t0=chrono::high_resolution_clock::now(); \

{X;} \

auto t1=chrono::high_resolution_clock::now(); \

cout<(t1-t0).count() / (double)1000000000 <<"ms" <<#X <

}int main(int argc, char*argv[])

{

vectorvec_int(SIZE);

iota(begin(vec_int), end(vec_int),0);

srand(0);

random_shuffle(begin(vec_int), end(vec_int));//TIME_STD(sort(begin(vec_int), end(vec_int)));

TIME_STD(tbb::task_scheduler_init _; tbb::parallel_sort(begin(vec_int), end(vec_int)));

assert(is_sorted(begin(vec_int), end(vec_int)));

return0;

}

makefile是这样的(本文中其它地方的例子的makefile和这个大体类似&#xff0c;所以只在这个地方贴出来)&#xff1a;

OBJS &#61;ParallelSort.o

CPPFLAGS&#61; -Wall -std&#61;c&#43;&#43;11 -O2

LDFLAGS&#61; -ltbb

ParallelSort: ${OBJS}

g&#43;&#43; ${LDFLAGS} -o $&#64; ${OBJS}

ParallelSort.o: ParallelSort.cppg&#43;&#43; ${CPPFLAGS} -c ParallelSort.cpp -o $&#64;

clean:rm -f ParallelSort ${OBJS}

parallel_sort的效率显然比std::sort高&#xff0c;根据核心数的多少略有不同&#xff0c;大家可以自己试一试。

三、配置OpenMP

OpenMP其实并不需要配置&#xff0c;多数C&#43;&#43;编译器都是内在支持了&#xff0c;要注意的是&#xff0c;如果程序使用OpenMP指令&#xff0c;在源程序里面要加上#include &#xff0c;编译和链接的时候要加上-fopenmp选项&#xff0c;否则会有警告甚至是错误&#xff0c;比如&#xff1a;undefined reference to &#96;omp_get_num_threads&#39;。

四、配置OpenCV

因为OpenCV是图形库(视觉库)&#xff0c;所以依赖于很多包&#xff0c;包括&#xff1a;

GCC 4.4.x or later&#xff1b;

CMake 2.6 or higher&#xff0c;cmake相当于autotools&#xff0c;但是易用性和友好性更佳&#xff1b;

GTK&#43;2.x or higher&#xff1b;

Git(如果用git方式下载源码的话)&#xff1b;

pkgconfig&#xff1b;

Python 2.6 or later&#xff1b;

ffmpeg&#xff1b;

还有可选的libjpeg&#xff0c;libpng&#xff0c;libtiff等。

依赖包都装好了以后&#xff1a;

wget http://superb-dca3.dl.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.5/opencv-2.4.5.tar.gz

tar zxvf opencv-2.4.5.tar.gz

cd opencv-2.4.5

mkdirrelease

cd release

cmake-D CMAKE_BUILD_TYPE&#61;RELEASE -D CMAKE_INSTALL_PREFIX&#61;/usr/local ..make

make install

这样opencv就编译安装好了。

要注意的是要确保LD_LIBRARY_PATH中包含了/usr/local/lib&#xff0c;这样编译器才能连接到动态库。编译链接的时候&#xff0c;还需要加上这样的选项&#xff1a;

编译时&#xff1a;&#96;pkg-config opencv --cflags opencv&#96;

链接时&#xff1a;&#96;pkg-config opencv --libs opencv&#96;

如果编译和链接放在一起&#xff1a;&#96;pkg-config opencv --libs --cflags opencv&#96;。

贴出一段很有意思的代码&#xff1a;

#include #include#include#include#include

using namespacestd;#define NUMBER 100

#define DELAY 5

char wndname[] &#61; "Drawing Demo";

CvScalar random_color(CvRNG*rng)

{int icolor &#61;cvRandInt(rng);return CV_RGB(icolor&255, (icolor>>8)&255, (icolor>>16)&255);

}inttest()

{int line_type &#61; CV_AA; //change it to 8 to see non-antialiased graphics

inti;

CvPoint pt1,pt2;doubleangle;

CvSize sz;

CvPoint ptt[6];

CvPoint* pt[2];int arr[2];

CvFont font;

CvRNG rng;int width &#61; 1000, height &#61; 700;int width3 &#61; width*3, height3 &#61; height*3;

CvSize text_size;int ymin &#61; 0;//Load the source image

IplImage* image &#61; cvCreateImage( cvSize(width,height), 8, 3);

IplImage*image2;//Create a window

cvNamedWindow(wndname, 1);

cvZero( image );

cvShowImage(wndname,image);

cvWaitKey(DELAY);

rng&#61; cvRNG((unsigned)-1);

pt[0] &#61; &(ptt[0]);

pt[1] &#61; &(ptt[3]);

arr[0] &#61; 3;

arr[1] &#61; 3;for (i &#61; 0; i

{

pt1.x&#61;cvRandInt(&rng) % width3 -width;

pt1.y&#61;cvRandInt(&rng) % height3 -height;

pt2.x&#61;cvRandInt(&rng) % width3 -width;

pt2.y&#61;cvRandInt(&rng) % height3 -height;

cvLine( image, pt1, pt2, random_color(&rng), cvRandInt(&rng)%10, line_type, 0);

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}for (i &#61; 0; i

{

pt1.x&#61;cvRandInt(&rng) % width3 -width;

pt1.y&#61;cvRandInt(&rng) % height3 -height;

pt2.x&#61;cvRandInt(&rng) % width3 -width;

pt2.y&#61;cvRandInt(&rng) % height3 -height;

cvRectangle( image,pt1, pt2, random_color(&rng), cvRandInt(&rng)%10-1, line_type, 0);

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}for (i &#61; 0; i

{

pt1.x&#61;cvRandInt(&rng) % width3 -width;

pt1.y&#61;cvRandInt(&rng) % height3 -height;

sz.width&#61;cvRandInt(&rng)%200;

sz.height&#61;cvRandInt(&rng)%200;

angle&#61; (cvRandInt(&rng)%1000)*0.180;

cvEllipse( image, pt1, sz, angle, angle- 100, angle &#43; 200,

random_color(&rng), cvRandInt(&rng)%10-1, line_type, 0);

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}for (i &#61; 0; i

{

pt[0][0].x&#61;cvRandInt(&rng) % width3 -width;

pt[0][0].y&#61;cvRandInt(&rng) % height3 -height;

pt[0][1].x&#61;cvRandInt(&rng) % width3 -width;

pt[0][1].y&#61;cvRandInt(&rng) % height3 -height;

pt[0][2].x&#61;cvRandInt(&rng) % width3 -width;

pt[0][2].y&#61;cvRandInt(&rng) % height3 -height;

pt[1][0].x&#61;cvRandInt(&rng) % width3 -width;

pt[1][0].y&#61;cvRandInt(&rng) % height3 -height;

pt[1][1].x&#61;cvRandInt(&rng) % width3 -width;

pt[1][1].y&#61;cvRandInt(&rng) % height3 -height;

pt[1][2].x&#61;cvRandInt(&rng) % width3 -width;

pt[1][2].y&#61;cvRandInt(&rng) % height3 -height;

cvPolyLine( image, pt, arr,2, 1, random_color(&rng), cvRandInt(&rng)%10, line_type, 0);

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}for (i &#61; 0; i

{

pt[0][0].x&#61;cvRandInt(&rng) % width3 -width;

pt[0][0].y&#61;cvRandInt(&rng) % height3 -height;

pt[0][1].x&#61;cvRandInt(&rng) % width3 -width;

pt[0][1].y&#61;cvRandInt(&rng) % height3 -height;

pt[0][2].x&#61;cvRandInt(&rng) % width3 -width;

pt[0][2].y&#61;cvRandInt(&rng) % height3 -height;

pt[1][0].x&#61;cvRandInt(&rng) % width3 -width;

pt[1][0].y&#61;cvRandInt(&rng) % height3 -height;

pt[1][1].x&#61;cvRandInt(&rng) % width3 -width;

pt[1][1].y&#61;cvRandInt(&rng) % height3 -height;

pt[1][2].x&#61;cvRandInt(&rng) % width3 -width;

pt[1][2].y&#61;cvRandInt(&rng) % height3 -height;

cvFillPoly( image, pt, arr,2, random_color(&rng), line_type, 0);

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}for (i &#61; 0; i

{

pt1.x&#61;cvRandInt(&rng) % width3 -width;

pt1.y&#61;cvRandInt(&rng) % height3 -height;

cvCircle( image, pt1, cvRandInt(&rng)%300, random_color(&rng),

cvRandInt(&rng)%10-1, line_type, 0);

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}for (i &#61; 1; i

{

pt1.x&#61;cvRandInt(&rng) % width3 -width;

pt1.y&#61;cvRandInt(&rng) % height3 -height;

cvInitFont(&font, cvRandInt(&rng) % 8,

(cvRandInt(&rng)%100)*0.05&#43;0.1, (cvRandInt(&rng)%100)*0.05&#43;0.1,

(cvRandInt(&rng)%5)*0.1, cvRound(cvRandInt(&rng)%10), line_type );

cvPutText( image,"Testing text rendering!", pt1, &font, random_color(&rng));

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}

cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 3, 3, 0.0, 5, line_type );

cvGetTextSize("OpenCV forever!", &font, &text_size, &ymin );

pt1.x&#61; (width - text_size.width)/2;

pt1.y&#61; (height &#43; text_size.height)/2;

image2&#61;cvCloneImage(image);for( i &#61; 0; i <255; i&#43;&#43;)

{

cvSubS( image2, cvScalarAll(i), image,0);

cvPutText( image,"OpenCV forever!", pt1, &font, CV_RGB(255,i,i));

cvShowImage(wndname,image);if(cvWaitKey(DELAY) >&#61; 0) return 0;

}//Wait for a key stroke; the same function arranges events processing

cvWaitKey(0);

cvReleaseImage(&image);

cvReleaseImage(&image2);

cvDestroyWindow(wndname);return 0;

}int main(int argc, char*argv[])

{

test();return 0;

}

运行效果&#xff1a;

怎么样&#xff0c;很酷吧&#xff1f;

OK&#xff0c;四个环境的配置就写完了&#xff01;吃饭去~



推荐阅读
  • Ceph API微服务实现RBD块设备的高效创建与安全删除
    本文旨在实现Ceph块存储中RBD块设备的高效创建与安全删除功能。开发环境为CentOS 7,使用 IntelliJ IDEA 进行开发。首先介绍了 librbd 的基本概念及其在 Ceph 中的作用,随后详细描述了项目 Gradle 配置的优化过程,确保了开发环境的稳定性和兼容性。通过这一系列步骤,我们成功实现了 RBD 块设备的快速创建与安全删除,提升了系统的整体性能和可靠性。 ... [详细]
  • 在CentOS上部署和配置FreeSWITCH
    在CentOS系统上部署和配置FreeSWITCH的过程涉及多个步骤。本文详细介绍了从源代码安装FreeSWITCH的方法,包括必要的依赖项安装、编译和配置过程。此外,还提供了常见的配置选项和故障排除技巧,帮助用户顺利完成部署并确保系统的稳定运行。 ... [详细]
  • 探讨 `org.openide.windows.TopComponent.componentOpened()` 方法的应用及其代码实例分析 ... [详细]
  • Go语言实现Redis客户端与服务器的交互机制深入解析
    在前文对Godis v1.0版本的基础功能进行了详细介绍后,本文将重点探讨如何实现客户端与服务器之间的交互机制。通过具体代码实现,使客户端与服务器能够顺利通信,赋予项目实际运行的能力。本文将详细解析Go语言在实现这一过程中的关键技术和实现细节,帮助读者深入了解Redis客户端与服务器的交互原理。 ... [详细]
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • 在进行网络编程时,准确获取本地主机的IP地址是一项基本但重要的任务。Winsock作为20世纪90年代初由Microsoft与多家公司共同制定的Windows平台网络编程接口,为开发者提供了一套高效且易用的工具。通过Winsock,开发者可以轻松实现网络通信功能,并准确获取本地主机的IP地址,从而确保应用程序在网络环境中的稳定运行。此外,了解Winsock的工作原理及其API函数的使用方法,有助于提高开发效率和代码质量。 ... [详细]
  • Spring Boot 实战(一):基础的CRUD操作详解
    在《Spring Boot 实战(一)》中,详细介绍了基础的CRUD操作,涵盖创建、读取、更新和删除等核心功能,适合初学者快速掌握Spring Boot框架的应用开发技巧。 ... [详细]
  • 开发心得:深入探讨Servlet、Dubbo与MyBatis中的责任链模式应用
    开发心得:深入探讨Servlet、Dubbo与MyBatis中的责任链模式应用 ... [详细]
  • 本文首先对信息漏洞的基础知识进行了概述,重点介绍了几种常见的信息泄露途径。具体包括目录遍历、PHPINFO信息泄露以及备份文件的不当下载。其中,备份文件下载涉及网站源代码、`.bak`文件、Vim缓存文件和`DS_Store`文件等。目录遍历漏洞的详细分析为后续深入研究奠定了基础。 ... [详细]
  • 本题库精选了Java核心知识点的练习题,旨在帮助学习者巩固和检验对Java理论基础的掌握。其中,选择题部分涵盖了访问控制权限等关键概念,例如,Java语言中仅允许子类或同一包内的类访问的访问权限为protected。此外,题库还包括其他重要知识点,如异常处理、多线程、集合框架等,全面覆盖Java编程的核心内容。 ... [详细]
  • 在Linux环境下编译安装Heartbeat时,常遇到依赖库缺失的问题。为确保顺利安装,建议预先通过yum安装必要的开发库,如glib2-devel、libtool-ltdl-devel、net-snmp-devel、bzip2-devel和ncurses-devel等。这些库是编译过程中不可或缺的组件,能够有效避免编译错误,确保Heartbeat的稳定运行。 ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • Python数据分析入门指南:全面了解Python在数据科学中的应用 ... [详细]
  • C#编程指南:实现列表与WPF数据网格的高效绑定方法 ... [详细]
author-avatar
just_roshinn5
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有