首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用make进行跨平台编译

使用make进行跨平台编译
EN

Stack Overflow用户
提问于 2012-03-20 16:41:50
回答 6查看 27.6K关注 0票数 34

我目前正在Linux和Win32下开发一个C项目。“可交付”是一个共享库,所有的开发都是在Linux下使用GNU工具链完成的。我正在使用Makefile来编译共享库。

有时,我必须从同一个src在Win32下构建一个Win32。

我已经在MinGW盒上安装了Win32,这样我就可以使用make,并且得到编译器的抱怨要少得多(与MSVC相比)。我所处的阶段是src代码在这两个平台上编译

但是Linux和Win32 Makefile是不同的。我很好奇如何最好地处理这件事--我应该:

  1. 有两个Makefile,例如用于linux和Makefile.WIN32的Makefile,然后在Windows上运行make -f Makefile.WIN32
  2. 我是否应该在单个Makefile中设置一个不同的目标,并在Windows上执行类似make WIN32的操作
  3. 我是否应该放弃制作和使用CMake (对于这样一个简单的项目(即一个共享库)来说,这是值得的吗?
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-03-20 21:09:36

使用单个make文件,并将平台的具体内容放在条件词中,例如

代码语言:javascript
复制
ifeq ($(OS),Windows_NT)
    DLLEXT := .dll
else
    DLLEXT := .so
endif

DLL := libfoo$(DLLEXT)

lib : $(DLL)
票数 32
EN

Stack Overflow用户

发布于 2013-02-08 16:55:53

我在Makefile中使用Makefile来检测平台(Linux或MS)。

下面是一个基于makegcc构建共享库的完整示例:*.so*.dll (取决于平台)。

这个例子是基本的/简单的/愚蠢的,更容易理解:)

若要在MS上使用makegcc,可以安装西格温MinGW .

该示例使用五个文件:

代码语言:javascript
复制
 ├── app
 │   └── Makefile
 │   └── main.c
 └── lib
     └── Makefile
     └── hello.h
     └── hello.c

The Makefiles

app/Makefile

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
#include "hello.h" //hello()
#include <stdio.h> //puts()

int main()
{
    const char* str = hello();
    puts(str);
}

lib/hello.h

代码语言:javascript
复制
#ifndef __HELLO_H__
#define __HELLO_H__

const char* hello();

#endif

lib/hello.c

代码语言:javascript
复制
#include "hello.h"

const char* hello()
{
    return "hello";
}

建筑

修复Makefiles的复制粘贴(用制表替换前导空格)。

代码语言:javascript
复制
> sed  -i  's/^  */\t/'  */Makefile

在两个平台上,make命令都是相同的。给定的输出用于MS(删除不必要的行)。

代码语言:javascript
复制
> 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上,简单/基本/愚蠢的方法是复制应用程序所在的库:

代码语言:javascript
复制
> cp -v lib/hello.dll app
`lib/hello.dll' -> `app/hello.dll'

在Linux上,使用LD_LIBRARY_PATH环境变量:

代码语言:javascript
复制
> export LD_LIBRARY_PATH=lib

在两个平台上,run命令行和输出是相同的:

代码语言:javascript
复制
> app/app.exe
hello
票数 18
EN

Stack Overflow用户

发布于 2012-03-21 03:32:28

作为既使用过autotools又使用过CMake的人,我建议您使用CMake而不是滚动自己的Makefiles和使用autotools。CMake有许多有用的、易于使用的好处,即使它是一个简单的项目。例如,CMake将创建一个NSIS安装程序,管理生产和调试编译,并有一个很好的测试框架。我遇到的一个问题是,很难找到如何使用它的真正例子。如此多的开放源码软件使用自动工具,因此很容易找到现实世界的例子。但是,如果下载CMake源代码,示例目录和Test目录中有很多示例。

换句话说,榨汁是值得的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9791127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档