我正在将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是编译器和优化选项,但不能完全确定。
CFLAGS
LDFLAGS
CC = g++ CFLAGS = -wall -o3 - c LDFLAGS = -03 -mfp-rounding-mode=n
我提供赏金是因为我仍然很失落。万一有人冒险,我需要在linux中编译以下内容
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>
2dquicksort.h中的标头:
#include <stdio.h> #include <ctype.h> #include <iostream>
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>
可以接受的答案是逐步说明makefile的工作方式以及如何在没有IDE的Linux中使用Boost构建它们。
Makefile背后的根 递归 思想是:
要建立目标,我们需要 先决条件 (其他目标!)和建立 指示
它们是文件,文件夹或伪造的目标(通常在中.PHONY)。测试文件/文件夹的存在和修改日期。
.PHONY
如果目标没有任何先决条件或比任何先决条件还旧,则需要重新构建目标。
指令是 shell命令 ,从一个选项卡开始。每条指令行都是一个shell实例。当当前命令以反斜杠结尾时,可以在下一行继续执行shell命令\。
\
目标是 依赖关系 或 规则 。
依赖关系:
target : prerequisite1 prerequisite2 prerequisiteN
规则:
target : prerequisite1 prerequisite2 prerequisiteN instructions1 @hidden_batch1 ; \ hidden_batch2
在说明开始前带有选项卡。
调试Makefile可能会让人头疼。尝试在Makefile中执行以下操作以显示跟踪(带有的文件和行位置warning):
warning
$(info Shell: $(SHELL)) $(warning CXX: $(CXX))
当您的Makefile包含很多嵌套if/else/endif并且您不确定当前路径是什么时,这将很有用。
if/else/endif
理想的makefile结构为:
一旦了解了整个Makefile及其包含文件(存储在make内部数据库中),便开始真正的目标指令处理。
make
最后,使用Boost将理论应用于该特定示例,并创建伪造的源文件进行说明。
#include "rawr.h"
#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; }
如果您Makefile从 stack overflow 复制源,请不要忘记用真实的Tab代替空格:
Makefile
sed -i~ -e 's/^ /\t/' Makefile
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)
2dquicksort.h converter.cpp Makefile rawr.cpp rawr.h simple_ls.cpp simple_ls.h
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
现在,几乎是最小的Boost程序的结果:
./converter 2
没有理由不使用它! Boost 实际上是功能强大的C ++工具箱:)