C++:
编译单个文件:
Hello.cpp:
#include <stdio.h>
int main(void) {
printf("Hello, world!\n");
return 0;
}
编译:
g++ -g -Wall hello.cpp -o hello
编译多个文件:
定义三个文件 hello.cpp, hello_fn.cpp, hello.h
hello.h:
void hello(const char* name);
hello_fn.cpp
#include <stdio.h>
#include "hello.h"
void hello(const char* name) {
printf("Hello, %s!\n", name);
}
hello.cpp
#include "hello.h"
int main(void) {
hello("Gintama");
return 0;
}
编译:
g++ -Wall hello.cpp hello_fn.cpp -o hello2
链接外部库
extlib.cpp(使用了 math.h, /usr/lib/libm.a)
#include <math.h>
#include <stdio.h>
int main(void) {
double x = 1.0;
double y = cos(x);
printf("Cos(1.0) is: %f\n", y);
return 0;
}
编译:
g++ -Wall extlib.cpp /usr/lib/libm.a -o extlib
或者
g++ -Wall extlib.c -lm -o extlib
-lm = /usr/lib/libm.a
-l 代表连接, m 代表 lib(m).a 中的 m
Makefile:
基本格式:
target1 ... : prerequisites ...
command
target2 ... : prerequisites ...
command
其中第一个 target 为默认执行。
上述示例转换成 makefile
CC=g++
CFLAGS=-Wall
hello:hello.o hello_fn.o
clean:
rm -f hello hello.o hello_fn.o
使用 VPATH 搜索路径
比如工程目录下,将CPP文件放置在 src 目录下,H文件放在 header下,则makefile可以这样写
CC = g++
OBJ = main_fn.o main.o
CFLAGS = -I include
vpath %.cpp src
vpath %.h include
main:$(OBJ)
$(CC) -o $@ $(OBJ)
%.o:%.cpp
$(CC) $(CFLAGS) -c $<
.PHONY:clean
clean:
-rm -f main $(OBJ)
其中,vpath 是搜索文件通配符和搜索路径
CFLAGS = -I include 是必须得,因为
include/main.h
#ifndef __MAIN_H
#define __MAIN_H
extern void echo(void);
#endif
src/main_fn.cpp
#include <iostream>
#include "main.h"
void echo(void)
{
std::cout << "echo ..." << std::endl;
}
src/main.cpp
#include <iostream>
#include "main.h"
int main() {
std::cout<< "helloworld" << std::endl;
echo();
return 0;
}
makefile 中有三个变量
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。
加入有以下 TARGET
main:main.o foo.o
gcc -o $@ $^
等价于
gcc -o main main.o foo.o
常见错误:
1.
现象:Makefile:1: *** missing separator. Stop.
办法:Makefile中只有命令行需要以 TAB 开头
2.
现象:*** recipe commences before first target. Stop.
办法:Makefile的Target声明开头都不能用空白字符