我需要修改下面的makefile来创建一个将在32位Windows和64位Windows环境中运行的dll(SampleNew.dll)。也许创建两个dll(一个用于64,一个用于32)是最好的方法。它需要使用SampleApi.dll(在下面的LIBS声明中)。以下内容不会为Windows创建有效的32位dll。关于如何修改以下内容以使其有效的任何想法?
CMODE=
SWIG = swig
CC = $(PREFIX)gcc
LD = $(CC)
OBJ_DIR = obj
AUTOGEN_DIR = ../src/java
PACKAGE_DIR = $(AUTOGEN_DIR)/com/test/sample
PACKAGE = com.test.sample
INCLUDES = -I$(JAVA_INCLUDE) \
-I$(SAMPLE_DIR)/include \
-I$(JDK_HOME)/include
LIB_INCLUDES = -L$(SAMPLE_DIR)/lib
LIBS = /lib/libssl.so.4 \
/lib/libcrypto.so.4 \
-lSampleApi \
-lm
DIRS = $(PACKAGE_DIR) $(DIST_DIR) $(OBJ_DIR) $(AUTOGEN_DIR)
CFLAGS = $(CMODE) -Wall -fpic $(INCLUDES) -O0 -g3
SFLAGS = -java $(INCLUDES) -package $(PACKAGE) -outdir $(PACKAGE_DIR)
LDFLAGS = -shared $(LIB_INCLUDES) $(LIBS)
OBJECTS = $(OBJ_DIR)/test_wrap.o
TARGET = $(LIB_DIR)/SampleNew.dll
all: $(DIRS) $(TARGET)
%_wrap.c: %.i
$(SWIG) $(SFLAGS) $<
$(OBJ_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(TARGET): $(OBJECTS)
$(LD) $(OBJECTS) $(LDFLAGS) -o $@
$(DIRS):
mkdir -p $@
clean:
rm -rf $(TARGET) $(PACKAGE_DIR)/* $(TARGET) $(AUTOGEN_DIR) $(OBJ_DIR)
例外:
java.lang.UnsatisfiedLinkError c:\test\myDllFile.dll: can't load this .dll (machine code=0x101) on a IA 32-bit platform
更新Makefile:
CMODE=
SWIG = swig
PREFIX=/test/mingw/mingw32/bin/i386-mingw32-
CC = $(PREFIX)gcc
LD = $(CC)
OBJ_DIR = obj
AUTOGEN_DIR = ../src/java
PACKAGE_DIR = $(AUTOGEN_DIR)/com/test/jni
PACKAGE = com.test.jni
INCLUDES = -I$(HEADER_FILES_DIR) # env var that points to a dir with all the .h files
LIB_INCLUDES = -L$(C_API_DIR)/lib # env var that points to a dir with the C libraries (dlls)
LIBS = -lMainApi \ # MainApi.dll
-lm
DIRS = $(PACKAGE_DIR) $(DIST_DIR) $(OBJ_DIR) $(AUTOGEN_DIR) # DIST_DIR is passed in
CFLAGS = $(CMODE) -Wall -fpic $(INCLUDES) -O0 -g3
SFLAGS = -java $(INCLUDES) -package $(PACKAGE) -outdir $(PACKAGE_DIR)
LDFLAGS = -shared $(LIB_INCLUDES) $(LIBS) -leay32 -lws2_32 -lrpcrt4
OBJECTS = $(OBJ_DIR)/test_wrap.o
TARGET = $(LIB_DIR)/SampleJni.dll
all: $(DIRS) $(TARGET)
%_wrap.c: %.i
$(SWIG) $(SFLAGS) $<
$(OBJ_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(TARGET): $(OBJECTS)
$(LD) $(OBJECTS) $(LDFLAGS) -o $@
$(DIRS):
mkdir -p $@
clean:
rm -rf $(TARGET) $(PACKAGE_DIR)/* $(TARGET) $(AUTOGEN_DIR) $(OBJ_DIR)
答案 0 :(得分:1)
您的工具链必须支持两个位;您的编译器和链接器必须能够发出64位和32位代码,或者您可以有两个单独的工具链。假设您的编译器默认处于64位模式,并采用开关来创建32位代码。您可以在make
中使用特定于目标的变量来为32位版本设置此开关
除了编译器之外,您还必须为两个构建设置不同的其他变量。我想到的是OBJ_DIR
和LIB_DIR
,因此输出文件不会混合; LIB_INCLUDES
,因为这两个版本都需要您自己链接的库版本(因此您需要两个版本的SampleApi.dll
)。
你的makefile会看到这些内容:
32bit: CC += -m32
32bit: OBJ_DIR = obj32
32bit: LIB_DIR := $(LIB_DIR)32
32bit: LIB_INCLUDES = -L$(SAMPLE_DIR)/lib32
all: 64bit 32bit
64bit 32bit: $(DIRS) $(TARGET)
(我已经排除了不需要更改的部分。)
答案 1 :(得分:1)
你能做的最简单的事情就是分开建造两者。例如,定义:
CFLAGS = $(CMODE) -Wall -fpic $(INCLUDES) -O0 -g3 -march=$(ARCH)
OBJ_DIR = obj-$(ARCH)
LIB_DIR = lib-$(ARCH)
.PHONY: default
default:
$(MAKE) ARCH=i686 all
$(MAKE) ARCH=x86_64 all
避免-m32
,因为它为x86-64生成32位代码,可能使用x86中不可用的指令。