创建linux make/build文件

Elp*_*rto 10 c++ linux boost makefile

我正在将一个C++项目从Windows迁移到Linux,现在我需要创建一个build/make文件.我以前从未创建过build/make文件.我还需要包含Boost库以使其更复杂.它也必须是一个makefile,我还需要学习如何创建makefile,所以CMake和SCON都出来了.由于使用了Boost,IDE也出局了,我的所有IDE(Eclipse,VS等)都只在Windows上运行.我必须从头开始生成一个makefile.

那么创建Linux c ++ make文件的基础知识是什么?如何将Boost库合并到其中以使其正确链接?

到目前为止,我的makefile看起来像这样.我认为CFLAGS并且LDFLAGS是编译器和优化选项,但不完全确定.

CC = g++
CFLAGS = -wall -o3 - c
LDFLAGS = -03 -mfp-rounding-mode=n
Run Code Online (Sandbox Code Playgroud)

我提供赏金,因为我仍然非常迷失.如果有人喜欢冒险,我需要在linux中编译以下内容

  • simple_ls.h
  • simple_ls.cpp
  • 2dquicksort.h
  • rawr.h
  • rawr.cpp
  • converter.cpp

simple_ls.h中的标题:

#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include "boost/lexical_cast.hpp"

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
Run Code Online (Sandbox Code Playgroud)

2dquicksort.h中的标题:

#include <stdio.h>
#include <ctype.h>
#include <iostream>
Run Code Online (Sandbox Code Playgroud)

rawr.h中的标头:

#include <iostream> // not required by most systems
#include <fstream>
#include <iomanip>
#include <cstdlib> // or (stdlib.h) for exit()

#include <cmath> 
#include <vector>
#include <limits>
#include <string>
Run Code Online (Sandbox Code Playgroud)

一个可接受的答案是逐步解释makefile如何工作以及如何在没有IDE的Linux中使用Boost构建它们.

Bil*_*nch 19

一个非常简单的GNU makefile如下:

CPPFLAGS += -Isome_include_path
CXXFLAGS += -O3
LDFLAGS  += -Lsome_link_path -lsome_lib -lboost_filesystem

all: binary_name
binary_name: foo.o bar.o john.o
Run Code Online (Sandbox Code Playgroud)
  • CPPFLAGS是应用于C预处理器的标志.包括路径在内的东西.
  • CXXFLAGS是应用于C++编译器的标志.像优化级别的东西.
  • LDFLAGS是应用于链接器的标志.外部库(boost_filesystem)和其他库之类的东西.此外,这些库的路径.
  • 公约说应该有一个make all规则,这是默认规则.在make中,第一个规则是默认规则.
  • binary_name 是二进制文件的名称.
  • binary_name依赖于3个文件:foo.o,bar.o,john.o.
  • 我们不包含规则,*.o因为gnu make对这些规则有隐含的规则.

要使用make,您将创建一个以Makefile上面列出的内容命名的文件.要构建,您将make在该目录中运行.

作为旁白(和其他人一样),如果可能的话,我建议远离make.那里有更好的系统.make的主要好处在于无处不在.但是,如果管理层要求,那么管理层就需要它.

(请注意,GNU Make +=notation并不总是可以移植到其他版本的Make.但是,make在Linux上是GNU Make.)


鉴于您的编辑,这里是您注意的文件的示例.一个警告是以$(CXX)开头的行应该以TAB字符开头!

LDFLAGS  := -lboost_filesystem
CXXFLAGS := -O3 -Wall
CPPFLAGS :=

all: program
program: simple_ls.o converter.o rawr.o
    $(CXX) -o $< $^ $(LDFLAGS)

simple_ls.o: simple_ls.cpp rawr.h simple_ls.h 2dquicksort.h
converter.o: converter.cpp rawr.h simple_ls.h 2dquicksort.h
rawr.o: rawr.cpp rawr.h simple_ls.h 2dquicksort.h
Run Code Online (Sandbox Code Playgroud)


lev*_*vif 19

什么是Makefile(适用于Boost项目)

Makefile背后的根递归思想是:

要构建目标,我们需要先决条件(其他目标!)和构建指令

先决条件

它们是文件,文件夹或虚假目标(通常在.PHONY).测试文件/文件夹的存在和修改日期.

如果目标没有先决条件,或者任何先决条件更旧,则需要重建目标.

指令

指令是shell命令,从一个选项卡开始.每条指令行都是一个shell实例.当前命令以反斜杠结束时,可以在下一行继续执行shell命令\.

目标定义

目标是依赖项规则.

相关性:

target : prerequisite1 prerequisite2 prerequisiteN
Run Code Online (Sandbox Code Playgroud)

规则:

target : prerequisite1 prerequisite2 prerequisiteN
    instructions1
    @hidden_batch1 ; \
  hidden_batch2  
Run Code Online (Sandbox Code Playgroud)

在指令开始前有选项卡.

调试

调试Makefile会成为一个真正令人头痛的问题.在Makefile中尝试以下操作以显示跟踪(包含文件和行位置warning):

$(info Shell: $(SHELL))
$(warning CXX: $(CXX))
Run Code Online (Sandbox Code Playgroud)

当Makefile包含大量嵌套if/else/endif并且您不确定当前路径是什么时,这很有用.

Makefile结构

理想的makefile结构是:

  1. 变量设置
  2. 目标/依赖声明

一旦理解了整个Makefile及其包含文件(存储在make内部数据库中),就会启动真正的目标指令处理.

最后,使用Boost将理论应用于此特定示例并创建假源文件来说明.

rawr.cpp

#include "rawr.h"
Run Code Online (Sandbox Code Playgroud)

simple_ls.cpp

#include "rawr.h"
Run Code Online (Sandbox Code Playgroud)

converter.cpp

#include <iostream>

#include "rawr.h"
#include "simple_ls.h"
#include "2dquicksort.h"

#include <boost/array.hpp>   // Boost! 

int main(int argc, char **argv)
{
    boost::array<int,4> a = { { 1, 2, 3, 4} };
    std::cout << a[1] << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Makefile文件

如果您Makefile从*stack***overflow**复制源,请不要忘记用真正的Tabs替换空格:

sed -i~ -e 's/^    /\t/' Makefile
Run Code Online (Sandbox Code Playgroud)

Makefile源码:

## Makefile for C++ project using Boost
#
# @author Cedric "levif" Le Dillau
#
# Some notes:
# - Using ':=' instead of '=' assign the value at Makefile parsing time,
#   others are evaluated at usage time. This discards
# - Use ':set list' in Vi/Vim to show tabs (Ctrl-v-i force tab insertion)
#

# List to '.PHONY' all fake targets, those that are neither files nor folders.
# "all" and "clean" are good candidates.
.PHONY: all, clean

# Define the final program name
PROGNAME := converter

# Pre-processor flags to be used for includes (-I) and defines (-D) 
CPPFLAGS := -DUSE_BOOST

# CFLAGS is used for C compilation options.
CFLAGS := -Wall -O0

# CXXFLAGS is used for C++ compilation options.
CXXFLAGS += -Wall -O0

# LDFLAGS is used for linker (-g enables debug symbols)
LDFLAGS  += -g

# Which Boost modules to use (all)
BOOST_MODULES = \
  date_time     \
  filesystem    \
  graph         \
  iostreams     \
  math_c99      \
  system        \
  serialization \
  regex

# Boost libraries' type (a suffix)
BOOST_MODULES_TYPE := -mt

# Define library names with their type
BOOST_MODULES_LIBS := $(addsuffix $(BOOT_MODULES_TYPE),$(BOOST_MODULES))

# Define the linker argument to use the Boost libraries.
BOOST_LDFLAGS := $(addprefix -lboost_,$(BOOST_MODULES_LIBS))

# Feed compiler/linker flags with Boost's
CPPFLAGS += $(BOOST_CPPFLAGS)
LDFLAGS += $(BOOST_LDFLAGS)

# List the project' sources to compile or let the Makefile recognize
# them for you using 'wildcard' function.
#
#SOURCES = simple_ls.cpp rawr.cpp converter.cpp
SOURCES = $(wildcard *.cpp)

# List the project' headers or let the Makefile recognize
# them for you using 'wildcard' function.
#
#HEADERS = simple_ls.h 2dquicksort.h rawr.h
HEADERS = $(wildcard %.h)

# Construct the list of object files based on source files using
# simple extension substitution.
OBJECTS = $(SOURCES:%.cpp=%.o)

#
# Now declare the dependencies rules and targets
#
# Starting with 'all' make it  becomes the default target when none 
# is specified on 'make' command line.
all : $(PROGNAME)

# Declare that the final program depends on all objects and the Makfile
$(PROGNAME) : $(OBJECTS) Makefile
    $(CXX) -o $@ $(LDFLAGS) $(OBJECTS)

# Now the choice of using implicit rules or not (my choice)...
#
# Choice 1: use implicit rules and then we only need to add some dependencies
#           to each object.
#
## Tells make that each object file depends on all headers and this Makefile.
#$(OBJECTS) : $(HEADERS) Makefile
#
# Choice 2: don't use implicit rules and specify our will
%.o: %.cpp $(HEADERS) Makefile
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<

# Simple clean-up target
# notes:
# - the '@' before 'echo' informs make to hide command invocation.
# - the '-' before 'rm' command to informs make to ignore errors.
clean :
    @echo "Clean."
    -rm -f *.o $(PROGNAME)
Run Code Online (Sandbox Code Playgroud)

文件列表

2dquicksort.h
converter.cpp
Makefile
rawr.cpp
rawr.h
simple_ls.cpp
simple_ls.h
Run Code Online (Sandbox Code Playgroud)

汇编

make clean all
Clean.
rm -f *.o converter
g++ -Wall -O0 -DUSE_BOOST  -c -o converter.o converter.cpp
g++ -Wall -O0 -DUSE_BOOST  -c -o rawr.o rawr.cpp
g++ -Wall -O0 -DUSE_BOOST  -c -o simple_ls.o simple_ls.cpp
g++ -o converter -g -lboost_date_time -lboost_filesystem -lboost_graph -lboost_iostreams -lboost_math_c99 -lboost_system -lboost_serialization -lboost_regex converter.o rawr.o simple_ls.o
Run Code Online (Sandbox Code Playgroud)

结果

现在,几乎是最小的Boost计划的结果:

./converter
2
Run Code Online (Sandbox Code Playgroud)

没有理由不使用它!Boost真的是一个特色的C++工具箱:)


Job*_*Job 8

我不建议你自己写Makefile.相反,使用像CMakeSCons这样的构建系统.

值得注意的是,这些工具是跨平台的.因此,您可以在Linux和Windows上使用相同的构建系统.


Nik*_*chi 5

当然你应该阅读精细手册(特别是gcc和make).但是,以下是gcc的基础知识:

要编译源文件:

g++ -c file.cpp
Run Code Online (Sandbox Code Playgroud)

这将创建file.o. 然后你可能想要链接它们:

g++ -o app_name file.o main.o other_file.o
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为app_name的可执行文件.但是由于您使用的是boost并且可能在整个地方都有头文件,因此您可能需要其他选项.在编译期间使用-I将目录添加到包含路径:

g++ -I/usr/local/more_includes/ -c file.cpp
Run Code Online (Sandbox Code Playgroud)

您可能还需要链接到某些库.链接期间:

g++ -L/usr/local/more_libraries/ file.o main.o other_file.o -lsome_library
Run Code Online (Sandbox Code Playgroud)

现在进入makefile.makefile的基础是:

target: dependencies
    command
Run Code Online (Sandbox Code Playgroud)

例如:

my_app: file.o
    g++ -o my_app file.o

file.o: file.cpp file.h
    g++ -o file.cpp

clean:
    rm file.o my_app
Run Code Online (Sandbox Code Playgroud)

如果您输入'make',则默认尝试创建第一个目标.my_app依赖于目标file.o,因此它将检查自上次修改my_app以来file.o是否已被修改.如果是这样,它将重新链接.在检查file.o时,它注意到file.o依赖于file.cpp和file.h. 如果自上次创建file.o以来修改了其中任何一个文件,它将重新编译该文件.

目标也不一定都是实际文件.最后一个名为clean,它不依赖于任何东西,只删除file.o和my_app.如果输入'make clean',它将运行该命令.

当然有很多其他选择,但这应该让你开始.