Make & CMake 进阶

引言

当下流行的IDE,将源代码生成可执行文件的过程都封装起来,对于开发着来说方便使用。
但是对于初学者来说,蒙蔽了源代码到可执行文件过程。源代码预处理,编译,打包,链接等步骤,
才能形成IDE中的一步到位的可执行文件target。而Makefile是直白的描述一个源代码如何被操作
才能成为target的一种文件格式。而CMake是一种可以通过配置的方式生成Makefile的脚本.
如果只是简单的开发一个.cpp进行测试,Makefile是首选。
本文中不对Makefile的基本语法进行介绍,要学习基本语法可以参看陈皓老师的Makefile中文教程进行学习。

Makefile

ifeqifneq之后要有个空格,否则不识别

ifeq ($(UNAME), linux)
     $(info "")
else
      $(warning "")
     $(error $(HAVE_SSHSERVER))
endif 

定义变量

HAVE_THE_VALUE := # 新定义一个变量
HAVE_THE_VALUE ?= # 如果没有定义,则定义一个新变量
HAVE_THE_VALUE += # 往变量中append数据

这个地方有点像pascal,不要与shell中混淆了

变量赋值

后面一定不要有空格,回车之类的空白符号,否则可能会将你整疯了的。
就拿caffe中的Makefile.config中

USE_LEVELDB := 1

USE_LEVELDB := 1

这两行的区别在于,第二行赋值操作后面有一个空格。在Makefile中通过如下代码进行添加编译需要的宏。


ifeq ($(USE_LEVELDB), 1)
  CXX_FLAGS += -DUSE_LEVELDB
endif

结果编译的时候打开的开关会与设想的不一样。

Makefile案例

#! Makefile

SRCS := PAPI_flops.c
OBJECTS := $(patsubst %.c, %.o, $(SRCS))
STATIC_LIB := /usr/local/lib/libpapi.a
INCLUDE_DIR := -I/usr/local/include
CC := gcc


all: PAPI_flops

PAPI_flops: $(OBJECTS)
     $(CC) -O0 $< $(STATIC_LIB) -o $@

$(OBJECTS): $(SRCS)
     $(CC) $(INCLUDE_DIR) -O0 -c $<

test:
     echo "----Running the PAPI_flops-----"
     @./PAPI_flops

clean:
     rm -rf PAPI_flops
     rm -rf *.o

makefile中调用.a库的编写

#!Makefile
CC = g++

TINYCV_DIR = /home/cwl/TinyCV
TINYCV_INCLUDE_DIR = $(TINYCV_DIR)/include
LIB_DIR = $(TINYCV_DIR)/build

CXX_FLAG = -O3 -std=c++11 -Wall -Werror -fPIC

all: main

main: main.o
  $(CC) $< $(CXX_FLAG) -I$(TINYCV_INCLUDE_DIR) -L$(LIB_DIR) -ltinycv -o $@

main.o: main.cpp
  $(CC) $(CXX_FLAG) -I$(TINYCV_INCLUDE_DIR) -c $<

clean:
  rm -f *.o main

需要注意的是下面这句中$<是指输入文件main.o,此处紧跟gcc

main: main.o
  $(CC) $< $(CXX_FLAG) -I$(TINYCV_INCLUDE_DIR) -L$(LIB_DIR) -ltinycv -o $@

但是如果变为如下情形,就会出现后面中的错误

main: main.o
  $(CC) $(CXX_FLAG) -I$(TINYCV_INCLUDE_DIR) -L$(LIB_DIR) -ltinycv -o $@  $<

错误:

caowenlong@Server-NF5280M3:~/Test$ make
g++ -O3 -std=c++11 -Wall -Werror -fPIC -I/home/cwl/TinyCV/include -c main.cpp
g++ -O3 -std=c++11 -Wall -Werror -fPIC -I/home/cwl/TinyCV/include -L/home/cwl/TinyCV/build -ltinycv -o main main.o
main.o:在函数‘main’中:
main.cpp:(.text.startup+0x3b):对‘tinycv::imread(std::string const&, int)’未定义的引用
main.cpp:(.text.startup+0x43):对‘tinycv::Mat<unsigned char>::Mat()’未定义的引用
main.cpp:(.text.startup+0x63):对‘double tinycv::threshold<unsigned char>(tinycv::Mat<unsigned char> const&, tinycv::Mat<unsigned char>&, double, double, int)’未定义的引用
collect2: error: ld returned 1 exit status
make: *** [main] 错误 1

makefile中的全局自变量

$@目标文件名
@^所有前提名,除副本
@+所有前提名,含副本
@<一个前提名
@?所有新于目标文件的前提名
@*目标文件的基名称

是否输出执行过程

#! Makefile
SAMPLE_ENABLE ?= 1

ifeq ($(SAMPLE_ENABLE), 1)
	EXEC ?= @echo "[@]"
endif

target: target2
	echo "hehe, this is target"

target2:
	echo "this is target2"
clean:
	rm -rf out.o

CMake

CMake 入门案例

PROJECT(sdk_common_samples)
cmake_minimum_required(VERSION 3.0)

# 查找已经安装的包
FIND_PACKAGE(OpenCV 2)

# SET 指令的语法是:
# SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

SET(
	SDK_COMMON_INCLUDE_D
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值