我在我的Makefile中使用
UNAME := $(shell uname)
来检测平台(Linux或MS-Windows)。
下面提供了一个基于
make
和
gcc
的完整示例,用于构建共享库:
*.so
或
*.dll
,具体取决于平台。
该示例非常基本/简单/愚蠢,以便更易于理解 :-)
要在MS-Windows上使用
make
和
gcc
,可以安装
Cygwin或
MinGW。
该示例使用五个文件:
├── app
│ └── Makefile
│ └── main.c
└── lib
└── Makefile
└── hello.h
└── hello.c
The Makefiles
app/Makefile
app.exe: main.o
gcc -o $@ $^ -L../lib -lhello
# '-o $@' => output file => $@ = the target file (app.exe)
# ' $^' => no options => Link all depended files
# => $^ = main.o and other if any
# '-L../lib' => look for libraries in directory ../lib
# '-lhello => use shared library hello (libhello.so or hello.dll)
%.o: %.c
gcc -o $@ -c $< -I ../lib
# '-o $@' => output file => $@ = the target file (main.o)
# '-c $<' => COMPILE the first depended file (main.cpp)
# '-I ../lib' => look for headers (*.h) in directory ../lib
clean:
rm -f *.o *.so *.dll *.exe
lib/Makefile
UNAME := $(shell uname)
ifeq ($(UNAME), Linux)
TARGET = libhello.so
else
TARGET = hello.dll
endif
$(TARGET): hello.o
gcc -o $@ $^ -shared
%.o: %.c
gcc -o $@ -c $< -fPIC
clean:
rm -f *.o *.so *.dll *.exe
源代码
app/main.c
#include "hello.h"
#include <stdio.h>
int main()
{
const char* str = hello();
puts(str);
}
lib/hello.h
#ifndef __HELLO_H__
#define __HELLO_H__
const char* hello();
#endif
lib/hello.c
#include "hello.h"
const char* hello()
{
return "hello";
}
编译
修复Makefiles
的复制粘贴问题(将前导空格替换为制表符)。
> sed -i 's/^ */\t/' */Makefile
make
命令在两个平台上都相同。给出的输出是针对 MS-Windows 的(已删除不必要的行)。
> cd lib
> make clean
> make
gcc -o hello.o -c hello.c -fPIC
gcc -o hello.dll hello.o -shared
> cd ../app
> make clean
> make
gcc -o main.o -c main.c -I ../lib
gcc -o app.exe main.o -L../lib -lhello
运行
该应用程序需要知道共享库的位置。
在MS-Windows上,简单/基本/愚蠢的方法是将库复制到应用程序所在的位置:
> cp -v lib/hello.dll app
`lib/hello.dll' -> `app/hello.dll'
在Linux上,使用
LD_LIBRARY_PATH
环境变量:
> export LD_LIBRARY_PATH=lib
在两个平台上,运行命令行和输出结果都是相同的:
> app/app.exe
hello
make
调用上重新运行特征检测),但我认为它们对您的使用情况并不重要;此外,GNU make足够强大,可以在其上构建配置系统(例如,您可以自动生成要include
和通过$(shell)
运行任意代码的makefile片段,通过$(info)
和$(error)
生成诊断信息等)。 - Christoph