linux多文件,多目录的嵌套编译

本文介绍了一种使用Makefile进行多文件、多子目录编译的方法,并解决了由编码和制表符引起的编译问题。

将mongo-cxx-driver-legacy编进工程,虽然设置了-I, 但是mongo实现中那些相对包含路径的头文件找不到。
尝试将相对包含路径的相对路径,改成相对本文件的相对路径。
无奈文件太多了,实在改不过来。
还是做了一个实验,将-I指定好,编译过了。
这工作量就降下来了, mongo-cxx-driver-legacy代码中都是相对于包含路径的相对路径,确实有道理.
一会对一下,正式工程和测试工程的区别.

实验环境

debianX64-8.8.8

工程结构

D:\testcase\case1cpy>tree /f
卷 dat_a 的文件夹 PATH 列表
卷序列号为 0000000E 66A6:68F9
D:.
│  const_define.cpp
│  const_define.h
│  Makefile
│
├─3rd
│  ├─3rd1
│  │  │  3rd1.cpp
│  │  │  3rd1.h
│  │  │
│  │  └─3rd1a
│  │          3rd1a.cpp
│  │          3rd1a.h
│  │
│  └─3rd2
│          3rd2.cpp3rd2.h
│
└─main
        main.cpp

测试工程

# ==============================================================================
# Makefile for testcase1
#   lostspeed 2017-05-13
#   command list:
#       make clean
#       make
# ==============================================================================
# root@debianx64:/home/ls/prj/case1# make clean
# rm -f testcase1.out const_define.o 3rd/3rd1/3rd1a/3rd1a.o 3rd/3rd1/3rd1.o 3rd/3rd2/3rd2.o main/main.o
# ==============================================================================
# root@debianx64:/home/ls/prj/case1# make
# g++ -c -Wall -g const_define.cpp -o const_define.o -I. -I./3rd -L/usr/local/lib -lstdc++ -pthread
# g++ -c -Wall -g 3rd/3rd1/3rd1a/3rd1a.cpp -o 3rd/3rd1/3rd1a/3rd1a.o -I. -I./3rd -L/usr/local/lib -lstdc++ -pthread
# g++ -c -Wall -g 3rd/3rd1/3rd1.cpp -o 3rd/3rd1/3rd1.o -I. -I./3rd -L/usr/local/lib -lstdc++ -pthread
# g++ -c -Wall -g 3rd/3rd2/3rd2.cpp -o 3rd/3rd2/3rd2.o -I. -I./3rd -L/usr/local/lib -lstdc++ -pthread
# g++ -c -Wall -g main/main.cpp -o main/main.o -I. -I./3rd -L/usr/local/lib -lstdc++ -pthread
# g++ -Wall -g -o testcase1.out const_define.o 3rd/3rd1/3rd1a/3rd1a.o 3rd/3rd1/3rd1.o 3rd/3rd2/3rd2.o main/main.o
# ==============================================================================

# 必须用g++, 不能用 gcc + -lstdc++
# 否则 undefined reference to `std::allocator<char>::allocator()'
CC = g++
CFLAGS = -Wall -g
BIN = testcase1.out

INC = -I. -I./3rd

LIBS = -lstdc++ -pthread

LIBPATH = /usr/local/lib

SUBDIR = $(shell ls -d */)
ROOTSRC = $(wildcard *.cpp)
ROOTOBJ = $(ROOTSRC:.cpp=.o)
SUBSRC = $(shell find $(SUBDIR) -name '*.cpp')
SUBOBJ = $(SUBSRC:.cpp=.o)

.PHNOY:$(BIN)

$(BIN) : $(ROOTOBJ) $(SUBOBJ)
    $(CC) $(CFLAGS) -o $@ $^

.cpp.o:
    $(CC) -c $(CFLAGS) $^ -o $@ $(INC) -L$(LIBPATH) $(LIBS)

clean:
    clear
    rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)
// @file main.cpp
// @brief 测试多文件,多子目录编译

#include <stdlib.h>
#include <stdio.h>
#include <string>

#include "const_define.h"
#include "3rd1/3rd1.h"
#include "3rd2/3rd2.h"

int main(int argc, char** argv)
{
    int i = 0;
    printf("%s %s\n", PROG_VER, BUILD_TIME);

    i = fn1() + fn2();
    printf("fn2() = %d\n", i);

    return 0;
}

/** run result
root@debianx64:/home/ls/prj/case1# ls
3rd  const_define.cpp  const_define.h  const_define.o  main  Makefile  testcase1.out
root@debianx64:/home/ls/prj/case1# ./testcase1.out
0.0.0.9 2017-5-13 14:57
fn2() = 5000
*/
// const_define.h: interface for the const_define class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CONST_DEFINE_H__0B552D25_4F64_42FF_B907_97F722A033EE__INCLUDED_)
#define AFX_CONST_DEFINE_H__0B552D25_4F64_42FF_B907_97F722A033EE__INCLUDED_

#define PROG_VER "0.0.0.9"
#define BUILD_TIME "2017-5-13 14:57"

#endif // !defined(AFX_CONST_DEFINE_H__0B552D25_4F64_42FF_B907_97F722A033EE__INCLUDED_)
// const_define.cpp: implementation of the const_define class.
//
//////////////////////////////////////////////////////////////////////

#include "const_define.h"

// @file 3rd1.h

#ifndef __3RD1_H__
#define __3RD1_H__
int fn1();
#endif // #ifndef __3RD1_H__
// @file 3rd1.cpp
#include "3rd/3rd1/3rd1.h"

int fn1()
{
    return 1000;
}
// @file 3rd1.h

#ifndef __3RD1A_H__
#define __3RD1A_H__
int fn1a();
#endif // #ifndef __3RD1A_H__
// @file 3rd1a.cpp
#include "3rd/3rd1/3rd1a/3rd1a.h"
#include "3rd/3rd1/3rd1.h"

int fn1a()
{
    return (fn1() + 1000);
}
// @file 3rd2.h

#ifndef __3RD2_H__
#define __3RD2_H__
int fn2();
#endif // #ifndef __3RD2_H__
// @file 3rd1.cpp
#include "3rd/3rd2/3rd2.h"
#include "3rd/3rd1/3rd1.h"
#include "3rd/3rd1/3rd1a/3rd1a.h"

int fn2()
{
    return (1000 + fn1() + fn1a());
}

2017-05-21

发现个问题, 我新建一个工程,需要Makefile.
用sourceInsight直接在工程中建立一个Makefile, 将博客中备好的Makefile内容直接贴进去。
编译时,居然编译不过。估计是文件保存时的编码问题。正在找这个问题。
又整理了一个Makefile,准备也新建Makefile, 粘贴博客中Makefile内容的备份。
如果还有问题,用文件比较工具比对一下。

# ==============================================================================
# makefile
#   lostspeed 2017-05-21
#   command list:
#       make clean
#       make
# ==============================================================================
#
# 必须用g++, 不能用 gcc + -lstdc++
# 否则 undefined reference to `std::allocator<char>::allocator()'
#
# $@ is the label
# $< is x.cpp
# $^ is x.cpp y.cpp ...
#
# show cur dir's all files
# find .
#
# echo show somthing by echo off
# @echo xx
#
# ------------------------------------------------------------------------------

CC = g++
CFLAGS = -Wall -g
BIN = testcase1.out

INC = -I. -I./3rd

LIBS = -lstdc++ -pthread

LIBPATH = /usr/local/lib

SUBDIR = $(shell ls -d */)
ROOTSRC = $(wildcard *.cpp)
ROOTOBJ = $(ROOTSRC:.cpp=.o)
SUBSRC = $(shell find $(SUBDIR) -name '*.cpp')
SUBOBJ = $(SUBSRC:.cpp=.o)

help:
    clear
    @echo make help
    @echo command list:
    @echo   make clean
    @echo   make all

clean:
    clear
    @echo make clean
    rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)

all:$(BIN)
    @echo make all
    find . -name "*.o"
    find . -name $(BIN)

$(BIN) : $(ROOTOBJ) $(SUBOBJ)
    $(CC) $(CFLAGS) -o $@ $^

.cpp.o:
    $(CC) -c $(CFLAGS) $^ -o $@ $(INC) -L$(LIBPATH) $(LIBS)

从博客粘贴Makefile不生效的原因

经过svn比对,知道原因了。
从博客粘贴的Makefile内容所有的Tab键都变成4个空格,每行末尾都编程了\r\n. 就是这2个原因使Makefile不好使了。
解决方法:
step1: 将Makefile传到debian环境中,用vi打开,将光标移动到每行结尾,按x键删掉\r\n
step2: 将sourceInsight的文件格式改为回车为Unix格式,文件格式为Windows(Ansi).
step3: 在sourceInsight中,将每一行有Tab键的地方都重新收入一遍。
step4: 将改过的Makefile传到debian环境中,make一下,Makefile已经生效了:)

感觉博客粘贴Makefile内容导致Makefile不生效的BUG, 好大坑啊…
第一次遇到,有点懵逼:P

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值