Permalink
Browse files

Port leveldb to MinGW32

Several changes to make the native windows leveldb code compile
with mingw32 and run on 32-bit Windows:
* Remove -std=c++0x dependency (modified code to use NULL instead of
  nullptr)
* Link with -lshlwapi
* Only #define snprintf/etc if compiling with Visual Studio
* Do not link against DbgHelp.lib (wrote a CreateDir instead of using
  DbgHelp's MakeSureDirectoryPathExists
* Define WINVER=0x0500 so MinGW32 can use the 64-bit-filesystem Windows
  api calls
* Define __USE_MINGW_ANSI_STDIO=1 to use MinGW's printf (which supports
  %ll)

I also cleaned up makefile.mingw, assuming that dependencies would be in
the standard /usr/local/{include,lib} by default but allowing overriding
with make DEPSDIR=... etc
  • Loading branch information...
1 parent 1ded43c commit e21a778c0a38d874c6d52ecc840dd1f786895fd4 @gavinandresen gavinandresen committed with Pieter Wuille Dec 21, 2012
View
@@ -97,14 +97,15 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) {
}
INCLUDEPATH += src/leveldb/include src/leveldb/helpers
-LIBS += $$PWD/src/leveldb/libleveldb.a $$PWD/src/leveldb/libmemenv.a -lshlwapi -ldbghelp
+LIBS += $$PWD/src/leveldb/libleveldb.a $$PWD/src/leveldb/libmemenv.a
!windows {
genleveldb.commands = cd $$PWD/src/leveldb && $(MAKE) libleveldb.a libmemenv.a
} else {
# make an educated guess about what the ranlib command is called
isEmpty(QMAKE_RANLIB) {
QMAKE_RANLIB = $$replace(QMAKE_STRIP, strip, ranlib)
}
+ LIBS += -lshlwapi
genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) libleveldb.a libmemenv.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libleveldb.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libmemenv.a
}
genleveldb.target = $$PWD/src/leveldb/libleveldb.a
@@ -390,7 +391,6 @@ LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX
# -lgdi32 has to happen after -lcrypto (see #681)
windows:LIBS += -lws2_32 -lshlwapi -lmswsock -lole32 -loleaut32 -luuid -lgdi32
LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX
-windows:LIBS += -lboost_chrono$$BOOST_LIB_SUFFIX
contains(RELEASE, 1) {
!windows:!macx {
@@ -129,11 +129,9 @@ case "$TARGET_OS" in
;;
OS_WINDOWS_CROSSCOMPILE | NATIVE_WINDOWS)
PLATFORM=OS_WINDOWS
- COMMON_FLAGS="-fno-builtin-memcmp -D_REENTRANT -DOS_WINDOWS -DLEVELDB_PLATFORM_WINDOWS"
- PLATFORM_SHARED_CFLAGS=""
+ COMMON_FLAGS="-fno-builtin-memcmp -D_REENTRANT -DOS_WINDOWS -DLEVELDB_PLATFORM_WINDOWS -DWINVER=0x0500 -D__USE_MINGW_ANSI_STDIO=1"
PLATFORM_SOURCES="util/env_win.cc"
- PLATFORM_CXXFLAGS="-std=c++0x"
- PLATFORM_LIBS="-lshlwapi -ldbghelp"
+ PLATFORM_LIBS="-lshlwapi"
PORT_FILE=port/port_win.cc
CROSS_COMPILE=true
;;
@@ -37,7 +37,7 @@ namespace leveldb {
namespace port {
Mutex::Mutex() :
- cs_(nullptr) {
+ cs_(NULL) {
assert(!cs_);
cs_ = static_cast<void *>(new CRITICAL_SECTION());
::InitializeCriticalSection(static_cast<CRITICAL_SECTION *>(cs_));
@@ -48,7 +48,7 @@ Mutex::~Mutex() {
assert(cs_);
::DeleteCriticalSection(static_cast<CRITICAL_SECTION *>(cs_));
delete static_cast<CRITICAL_SECTION *>(cs_);
- cs_ = nullptr;
+ cs_ = NULL;
assert(!cs_);
}
@@ -128,7 +128,7 @@ void InitOnce(OnceType* once, void (*initializer)()) {
}
void* AtomicPointer::Acquire_Load() const {
- void * p = nullptr;
+ void * p = NULL;
InterlockedExchangePointer(&p, rep_);
return p;
}
@@ -31,9 +31,11 @@
#ifndef STORAGE_LEVELDB_PORT_PORT_WIN_H_
#define STORAGE_LEVELDB_PORT_PORT_WIN_H_
+#ifdef _MSC_VER
#define snprintf _snprintf
#define close _close
#define fread_unlocked _fread_nolock
+#endif
#include <string>
#include <stdint.h>
@@ -120,7 +122,7 @@ class AtomicPointer {
private:
void * rep_;
public:
- AtomicPointer() : rep_(nullptr) { }
+ AtomicPointer() : rep_(NULL) { }
explicit AtomicPointer(void* v);
void* Acquire_Load() const;
@@ -20,9 +20,7 @@
#include <stdio.h>
#include <errno.h>
#include <io.h>
-#include <dbghelp.h>
#include <algorithm>
-#pragma comment(lib,"DbgHelp.lib")
#ifdef max
#undef max
@@ -908,18 +906,34 @@ uint64_t Win32Env::NowMicros()
return (uint64_t)(GetTickCount64()*1000);
}
-Status Win32Env::CreateDir( const std::string& dirname )
+static Status CreateDirInner( const std::string& dirname )
{
Status sRet;
+ DWORD attr = ::GetFileAttributes(dirname.c_str());
+ if (attr == INVALID_FILE_ATTRIBUTES) { // doesn't exist:
+ std::size_t slash = dirname.find_last_of("\\");
+ if (slash != std::string::npos){
+ sRet = CreateDirInner(dirname.substr(0, slash));
+ if (!sRet.ok()) return sRet;
+ }
+ BOOL result = ::CreateDirectory(dirname.c_str(), NULL);
+ if (result == FALSE) {
+ sRet = Status::IOError(dirname, "Could not create directory.");
+ return sRet;
+ }
+ }
+ return sRet;
+}
+
+Status Win32Env::CreateDir( const std::string& dirname )
+{
std::string path = dirname;
if(path[path.length() - 1] != '\\'){
path += '\\';
}
ModifyPath(path);
- if(!::MakeSureDirectoryPathExists( path.c_str() ) ){
- sRet = Status::IOError(dirname, "Could not create directory.");
- }
- return sRet;
+
+ return CreateDirInner(path);
}
Status Win32Env::DeleteDir( const std::string& dirname )
View
@@ -90,11 +90,11 @@ OBJS= \
all: bitcoind.exe
-LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -lshlwapi -ldbghelp
+LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -lshlwapi
DEFS += -I"$(CURDIR)/leveldb/include"
DEFS += -I"$(CURDIR)/leveldb/helpers"
leveldb/libleveldb.a:
- @echo "Building LevelDB ..." && cd leveldb && CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ TARGET_OS=OS_WINDOWS_CROSSCOMPILE" $(MAKE) libleveldb.a libmemenv.a && i686-w64-mingw32-ranlib libleveldb.a && i686-w64-mingw32-ranlib libmemenv.a && cd ..
+ @echo "Building LevelDB ..." && cd leveldb && CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) libleveldb.a libmemenv.a && i686-w64-mingw32-ranlib libleveldb.a && i686-w64-mingw32-ranlib libmemenv.a && cd ..
obj/leveldb.o: leveldb/libleveldb.a
obj/build.h: FORCE
@@ -123,5 +123,6 @@ clean:
-rm -f obj-test/*.o
-rm -f test_bitcoin.exe
-rm -f obj/build.h
+ cd leveldb && TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) clean && cd ..
FORCE:
View
@@ -2,32 +2,48 @@
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-USE_UPNP:=0
+# Makefile for the MinGW g++ compiler/toolchain
+#
+# Assumes Berkeley DB, Boost, and OpenSSL have all been compiled and installed
+# into /usr/local (/usr/local/include, /usr/local/lib).
+#
+# If dependencies are somewhere else, run 'make DEPSDIR=/path/'
+#
+# Boost libraries are given wacky names that include the particular version of
+# boost you're using; set BOOST_SUFFIX appropriately.
+#
+# 'make clean' assumes it is running inside a MSYS shell, and uses 'rm'
+# to remove files.
+
+USE_UPNP:=-
USE_IPV6:=1
+DEPSDIR?=/usr/local
+BOOST_SUFFIX?=-mgw46-mt-sd-1_52
+
INCLUDEPATHS= \
- -I"C:\boost-1.50.0-mgw" \
- -I"C:\db-4.8.30.NC-mgw\build_unix" \
- -I"C:\openssl-1.0.1c-mgw\include"
+ -I"$(CURDIR)" \
+ -I"$(DEPSDIR)/include"
LIBPATHS= \
- -L"C:\boost-1.50.0-mgw\stage\lib" \
- -L"C:\db-4.8.30.NC-mgw\build_unix" \
- -L"C:\openssl-1.0.1c-mgw"
+ -L"$(CURDIR)/leveldb" \
+ -L"$(DEPSDIR)/lib"
LIBS= \
- -l boost_system-mgw45-mt-s-1_50 \
- -l boost_filesystem-mgw45-mt-s-1_50 \
- -l boost_program_options-mgw45-mt-s-1_50 \
- -l boost_thread-mgw45-mt-s-1_50 \
- -l boost_chrono-mgw45-mt-s-1_50 \
+ -l leveldb \
+ -l memenv \
+ -l boost_system$(BOOST_SUFFIX) \
+ -l boost_filesystem$(BOOST_SUFFIX) \
+ -l boost_program_options$(BOOST_SUFFIX) \
+ -l boost_thread$(BOOST_SUFFIX) \
+ -l boost_chrono$(BOOST_SUFFIX) \
-l db_cxx \
-l ssl \
-l crypto
DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
-DEBUGFLAGS=-g
-CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+DEBUGFLAGS=-g -ggdb
+CFLAGS=-mthreads -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
@@ -36,8 +52,6 @@ ifndef USE_UPNP
override USE_UPNP = -
endif
ifneq (${USE_UPNP}, -)
- INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw"
- LIBPATHS += -L"C:\miniupnpc-1.6-mgw"
LIBS += -l miniupnpc -l iphlpapi
DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
endif
@@ -93,12 +107,12 @@ test check: test_bitcoin.exe FORCE
#
# LevelDB support
#
-LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a
DEFS += $(addprefix -I,$(CURDIR)/leveldb/include)
DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers)
-# TODO: If this fails, try adding a ranlib libleveldb.a && ranlib libmemenv.a
+
leveldb/libleveldb.a:
- cd leveldb && $(MAKE) libleveldb.a libmemenv.a && cd ..
+ cd leveldb && $(MAKE) OPT="$(DEBUGFLAGS)" TARGET_OS=NATIVE_WINDOWS libleveldb.a libmemenv.a && cd ..
+
obj/leveldb.o: leveldb/libleveldb.a
obj/%.o: %.cpp $(HEADERS)
@@ -113,11 +127,12 @@ obj-test/%.o: test/%.cpp $(HEADERS)
g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $<
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
- g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS)
+ g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework$(BOOST_SUFFIX) $(LIBS)
clean:
- -del /Q bitcoind test_bitcoin
- -del /Q obj\*
- -del /Q obj-test\*
+ rm -f bitcoind.exe test_bitcoin.exe
+ rm -f obj/*
+ rm -f obj-test/*
+ cd leveldb && $(MAKE) TARGET_OS=NATIVE_WINDOWS clean && cd ..
FORCE:

0 comments on commit e21a778

Please sign in to comment.