makefile入门:制作动态库与多makefile编译模板

目录

1.制作动态库

实验1

文件目录树

helloworld.hpp

hello.cpp

world.cpp

main.cpp

makefile

测试结果

-Wl,-rpath的解释

2.多makefile编译

实验2

文件目录树

max.hpp

max.cpp

main.cpp

max目录下的makefile

主目录下的makefile

测试结果


1.制作动态库

在Makefile中,您可以使用以下方式来指定头文件路径和库文件路径:

1. 指定头文件路径:您可以使用 `-I` 标志来指定头文件的搜索路径。例如,假设您的头文件位于 `./inc` 目录下,您可以这样指定头文件路径:

makefile
INC = -I ./inc

这将告诉编译器在 `./inc` 目录中搜索头文件。

2. 指定库文件路径:您可以使用 `-L` 标志来指定库文件的搜索路径。例如,假设您的库文件位于 `./` 目录下,您可以这样指定库文件路径:

makefile
LIB_SEARCH_PATH = -L ./

这将告诉链接器在 `./` 目录中搜索库文件。

3. 指定库文件名:您可以使用 `-l` 标志来指定要链接的库文件。例如,如果您要链接名为 `libhelloworld` 的库文件,您可以这样指定库文件名:

makefile
LIB = -lhelloworld

这将告诉链接器链接 `libhelloworld` 库文件。

实验1

        按照如下文件目录树创建文件

文件目录树

makefile入门:制作动态库与多makefile编译模板_第1张图片

helloworld.hpp

#include 
void world(void);
void hello(void);

hello.cpp

#include "helloworld.hpp"
void hello() { 
    std::cout << "hello "; 
    world(); 
} 

world.cpp

#include "helloworld.hpp"
void world() { 
    std::cout << "world!" << std::endl; 
} 

main.cpp

#include "helloworld.hpp"
int main(void)
{
    hello();
    return 0;
}

makefile

#INCLUDE
INC = -I ./inc

#C++ SOURCE
CPP_SRC = ./src/hello.cpp \
	      ./src/world.cpp

#LIBRARY
LIB = -lhelloworld

#LIB_PATH
RPATH_SEARCH_PATH = -Wl,-rpath ./

LIB_SEARCH_PATH = -L ./

#C++ FLAGS
CXXFLAGS = -c -Wall -g -fPIC


#-fPIC 选项表示生成位置无关的代码(Position Independent Code),这样生成的代码可以在不同的内#存位置加载和执行,例如用于共享库。 
#-shared 选项表示生成共享库。使用此选项,链接器将生成一个共享库文件,可以在运行时被动态加载。 
#LINK FLAGS
LKFLAGS = -fPIC -shared

#CXX
CXX = g++

#TARGET
TARGET = libhelloworld.so 

#TARGET_TEST
TARGET_TEST = helloworld

#C++ OBJECT
OBJS = $(CPP_SRC:.cpp=.o)

$(TARGET) : $(OBJS)
	$(CXX) $(LKFLAGS) $(INC) $^ -o $@

%.o : %.cpp	
	$(CXX) $(CXXFLAGS) $(INC) $< -o $@

.PHONY: $(TARGET_TEST)

$(TARGET_TEST): ./test/main.cpp
	$(CXX) $(INC) $< $(RPATH_SEARCH_PATH) $(LIB_SEARCH_PATH) $(LIB) -o $@	

clean :
	rm -rf $(OBJS) $(TARGET) $(TARGET_TEST)

测试结果

makefile入门:制作动态库与多makefile编译模板_第2张图片

-Wl,-rpath的解释

`-Wl,-rpath` 是GCC编译器的一个选项,用于指定在运行时(可以理解为运行可执行文件时)动态链接库时搜索库文件的路径。注意:区别于LIB_SEARCH_PATH = -L ./,LIB_SEARCH_PATH = -L ./是编译链接时的,不包含运行时。

GCC编译器将 `-Wl` 选项用于将后续的参数传递给链接器。而 `-rpath` 选项是链接器的一个选项,用于指定运行时搜索共享库的路径。

具体来说, `-Wl,-rpath` 的使用方式是将路径作为参数传递给链接器。例如,假设您希望在当前目录中搜索共享库,可以使用以下方式设置 `-Wl,-rpath` 选项:

makefile
RPATH_SEARCH_PATH = -Wl,-rpath ./

这将告诉链接器在当前目录中搜索共享库。

2.多makefile编译

实验2

         按照如下文件目录树创建文件

文件目录树

makefile入门:制作动态库与多makefile编译模板_第3张图片

max.hpp

#ifndef MAX_HPP
#define MAX_HPP

int max(int a, int b);

#endif

max.cpp

#include "max.hpp"

int max(int a, int b) {
    return (a > b) ? a : b;
}

main.cpp

#include 
#include "max.hpp"

int main() {
    int a = 10;
    int b = 5;
    int result = max(a, b);
    std::cout << "The maximum of " << a << " and " << b << " is " << result << std::endl;
    return 0;
}

max目录下的makefile

#INCLUDE
INC = -I ./inc

#C++ SOURCE
CPP_SRC = ./src/max.cpp 

#LIBRARY
LIB = -lmax

#LIB_PATH
RPATH_SEARCH_PATH = -Wl,-rpath ./

LIB_SEARCH_PATH = -L ./

#C++ FLAGS
CXXFLAGS = -c -Wall -g -fPIC

#-fPIC 是 g++ 编译器的选项,用于生成位置无关代码(Position Independent Code)。
#LINK FLAGS
LKFLAGS = -fPIC -shared

#CXX
CXX = g++

#TARGET
TARGET = libmax.so 

#TARGET_TEST
TARGET_TEST = max

#C++ OBJECT
OBJS = $(CPP_SRC:.cpp=.o)

$(TARGET) : $(OBJS)
	$(CXX) $(LKFLAGS) $(INC) $^ -o $@

%.o : %.cpp	
	$(CXX) $(CXXFLAGS) $(INC) $< -o $@

.PHONY: $(TARGET_TEST)

$(TARGET_TEST): ./test/main.cpp
	$(CXX) $(INC) $< $(RPATH_SEARCH_PATH) $(LIB_SEARCH_PATH) $(LIB) -o $@	

clean :
	rm -rf $(OBJS) $(TARGET) $(TARGET_TEST)

主目录下的makefile

SUBDIRS = helloworld max

ALL : all 
 
all :
	@list='$(SUBDIRS)'; \
	for sudir in $$list; \
		do \
			cd $$sudir; \
			make; \
			cd ..; \
		done 

.PHONY : clean
clean :
	@list='$(SUBDIRS)'; \
	for sudir in $$list; \
		do \
			cd $$sudir; \
			make clean; \
			cd ..; \
		done

测试结果

makefile入门:制作动态库与多makefile编译模板_第4张图片

makefile入门:制作动态库与多makefile编译模板_第5张图片

makefile入门:制作动态库与多makefile编译模板_第6张图片

你可能感兴趣的:(学习,编辑器,vscode,c++,开发语言)