Create a DLL using the Makefile for Windows XP (32-bit) and Windows 7 (64-bit)

I need to modify the makefile below to create a dll (SampleNew.dll) that will run in 32-bit windows and in a 64-bit Windows environment. Perhaps creating two dlls (one for 64 and one for 32) is the best approach. It should use SampleApi.dll (in the LIBS declaration below). The following is not a valid 32-bit dll for Windows. Any ideas on how to modify the following to make it work?

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) 

An exception:

 java.lang.UnsatisfiedLinkError c:\test\myDllFile.dll: can't load this .dll (machine code=0x101) on a IA 32-bit platform 

update 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) 
+4
source share
2 answers

The simplest thing you can do is build it separately. For example, defining:

 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 

Avoid -m32 as it generates 32-bit code for x86-64, which may use instructions not available on x86.

+1
source

Your tool chain should support both bits; your compiler and linker should be able to emit both 64-bit and 32-bit code, or you can have two separate toolchains. Suppose your compiler is set to 64-bit by default and accepts a switch to create 32-bit code. You can use target variables in make to set this switch for a 32-bit build.
Besides the compiler, you will also have to set other variables differently for the two assemblies. The things that come to mind are OBJ_DIR and LIB_DIR , so the output files do not mix; LIB_INCLUDES , because both collectors require their own versions of the libraries that you reference (so you will need two versions of SampleApi.dll ).

Your makefile will look something like this:

 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) 

(I excluded parts that do not need to be changed.)

+1
source

Source: https://habr.com/ru/post/1387657/


All Articles