我目前正在Linux和Win32下开发一个C项目。 ‘deliverrable’是一个共享库,所有开发都是在Linux下使用GNU工具链完成的。 我正在使用Makefile来编译共享库。
我不得不在同一个src下在Win32下构建一个.dll。
我已经在Win32盒子上安装了MinGW,这样我就可以使用make并从编译器中获得更少的投诉(与MSVC相比)。 我正处于src代码在两个平台上编译的阶段
但是Linux Makefile和Win32 Makefile是不同的。 我很好奇如何最好地处理这个 – 我应该:
使用单个make文件并将特定于平台的内容放在条件中 ,例如
ifeq ($(OS),Windows_NT) DLLEXT := .dll else DLLEXT := .so endif DLL := libfoo$(DLLEXT) lib : $(DLL)
我在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
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 $@' => output file => $@ = libhello.so or hello.dll # ' $^' => no options => Link all depended files => $^ = hello.o # '-shared' => generate shared library %.o: %.c gcc -o $@ -c $< -fPIC # '-o $@' => output file => $@ = the target file (main.o) # '-c $<' => compile the first depended file (main.cpp) # '-fPIC' => Position-Independent Code (required for shared lib) clean: rm -f *.o *.so *.dll *.exe
源代码
app/main.c
#include "hello.h" //hello() #include //puts() 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
两个平台上的run命令行和输出相同:
> app/app.exe hello
几年前我遇到过类似的问题,发现cmake更容易进行跨平台编译,并且会使用该系统的任何编译器。 语法更清晰,抽象大部分都不需要的细节(有时会妨碍,但通常有一种解决方法)
作为使用过autotools和CMake的人,我建议使用CMake滚动你自己的Makefile并使用autotools。 即使是一个简单的项目,CMake也有许多有用且易于使用的好处。 例如,CMake将创建一个NSIS安装程序,管理生产与调试编译,并有一个很好的测试框架。 我遇到的一个问题是,很难找到如何使用它的真实例子。 这么多开源软件使用自动工具,很容易找到它的真实世界的例子。 但是,如果您下载CMake源,那么Example目录和Test目录中有很多示例。
换句话说,Juice值得挤压。
作为主要建议,我建议使用libtool,autoconf和automake; 它们使交叉编译非常容易,并且比CMake更容易。
如果你要进行手工制作的路线,我建议选择不同的目标。 在makefile之间切换往往会隐藏Makefile中明显的错误,例如,具有不同规则的重复使用的对象。 示例:对象foo.o是针对DLL目标和.so目标编译的,但具有不同的标志。 如果有人切换Makefile,则使用带有错误标志的现有.o文件,从而破坏构建。 如果您使用的是一个Makefile,这将通过规则冲突变得明显。
需要了解更多c/c++开发分享使用make进行跨平台编译,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享使用make进行跨平台编译相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979895.html