Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,60 @@ Notes
-----

* This will build `multichaind.exe`, `multichain-cli.exe` and `multichain-util.exe` in the `src` directory.


Mac Build Notes (on MacOS Sierra)
================

Install dependencies
--------------------

Install XCode and XCode command line tools
Install git from git-scm
Install brew (follow instructions on brew.sh)
brew install autoconf automake berkeley-db4 libtool boost openssl pkg-config rename

Prepare for static linking
--------------------------
Apple does not support statically linked binaries as [documented here](https://developer.apple.com/library/content/qa/qa1118/_index.html), however, it is convenient for end-users to launch a binary without having to first install brew, a third-party system designed for developers.

To create a statically linked MultiChain which only depends on default MacOS dylibs, the following steps are taken:

1. Hide the brew boost dylibs from the build system:
rename -e 's/.dylib/.dylib.hidden/' /usr/local/opt/boost/lib/*.dylib

2. Hide the brew berekley-db dylibs from the build system:
rename -e 's/.dylib/.dylib.hidden/' /usr/local/opt/berkeley-db\@4/lib/*.dylib

3. Hide the brew openssl dylibs from the build system:
rename -e 's/.dylib/.dylib.hidden/' /usr/local/opt/openssl/lib/*.dylib

The default brew cookbook for berkeley-db and boost builds static libraries, but the default cookbook for openssl only builds dylibs.

3. Tell brew to build openssl static libraries:
brew edit openssl
In 'def configure_args' change 'shared' to 'no-shared'
brew install openssl --force

Compile MultiChain for Mac (64-bit)
--------------------------

export LDFLAGS=-L/usr/local/opt/openssl/lib
export CPPFLAGS=-I/usr/local/opt/openssl/include
./configure --with-gui=no --with-libs=no --with-miniupnpc=no
make

Clean up
--------

rename -e 's/.dylib.hidden/.dylib/' /usr/local/opt/berkeley-db\@4/lib/*.dylib.hidden
rename -e 's/.dylib.hidden/.dylib/' /usr/local/opt/boost/lib/*.dylib.hidden
rename -e 's/.dylib.hidden/.dylib/' /usr/local/opt/openssl/lib/*.dylib.hidden
brew edit openssl
In 'def configure_args' change 'no-shared' to 'shared'

Notes
-----

* This will build `multichaind`, `multichain-cli` and `multichain-util` in the `src` directory.

4 changes: 3 additions & 1 deletion src/leveldb/port/atomic_pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ namespace port {
// Mac OS
#elif defined(OS_MACOSX)
inline void MemoryBarrier() {
OSMemoryBarrier();
// OSMemoryBarrier() deprecated in macOS 10.12.
// Apply patch from: https://github.com/google/leveldb/pull/422
atomic_thread_fence(std::memory_order_seq_cst);
}
#define LEVELDB_HAVE_MEMORY_BARRIER

Expand Down
4 changes: 4 additions & 0 deletions src/utils/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <time.h>
#include <sys/time.h>

#ifdef MAC_OSX
#define lseek64 lseek
#endif

#ifndef WIN32

#include <unistd.h>
Expand Down
25 changes: 24 additions & 1 deletion src/utils/systemdependent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,32 @@ void* __US_SemCreate()

lpsem=NULL;

#ifdef MAC_OSX
// Create a unique name for the named semaphore
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int namelen = 20;
char name[namelen + 1];
for (int i = 0; i < namelen; ++i) {
name[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
name[namelen] = 0;

// Create named semaphore as unnamed semaphores are deprecated on OS X.
lpsem = sem_open(name, O_CREAT | O_EXCL, 0666, 1);
if (lpsem == SEM_FAILED) {
return NULL;
}
#else
lpsem=new sem_t;
if(sem_init(lpsem,0666,1))
{
delete lpsem;
return NULL;
}

#endif
return (void*)lpsem;
}

Expand All @@ -150,12 +169,16 @@ void __US_SemPost(void* sem)

void __US_SemDestroy(void* sem)
{
#ifndef MAC_OSX
sem_t *lpsem;
#endif
if(sem)
{
sem_close((sem_t*)sem);
#ifndef MAC_OSX
lpsem=(sem_t*)sem;
delete lpsem;
#endif
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/utils/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ void mc_MemoryDump(void *ptr,

for(i=0;i<n;i++)
{
#ifdef MAC_OSX
printf("%4d %08X: ",k,(unsigned int)(size_t)dptr);
#else
printf("%4d %08X: ",k,(unsigned int)(unsigned int64_t)dptr);
#endif
for(j=0;j<4;j++)
{
if(k<len)
Expand Down
47 changes: 33 additions & 14 deletions src/utils/utilwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,30 +280,22 @@ int64_t mc_Params::HasOption(const char* strArg)

boost::filesystem::path mc_GetDefaultDataDir()
{
// Windows < Vista: C:\Documents and Settings\Username\Application Data\Bitcoin
// Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin
// Mac: ~/Library/Application Support/Bitcoin
// Unix: ~/.bitcoin
// Windows < Vista: C:\Documents and Settings\Username\Application Data\MultiChain
// Windows >= Vista: C:\Users\Username\AppData\Roaming\MultiChain
// Mac and Unix: ~/.multichain
#ifdef WIN32
// Windows
return GetSpecialFolderPath(CSIDL_APPDATA) / "MultiChain";
#else
// Mac and Unix
boost::filesystem::path pathRet;
char* pszHome = getenv("HOME");
if (pszHome == NULL || strlen(pszHome) == 0)
pathRet = boost::filesystem::path("/");
else
pathRet = boost::filesystem::path(pszHome);
#ifdef MAC_OSX
// Mac
pathRet /= "Library/Application Support";
TryCreateDirectory(pathRet);
return pathRet / "Bitcoin";
#else
// Unix
return pathRet / ".multichain";
#endif
#endif
}

int mc_GetDataDirArg(char *buf)
Expand Down Expand Up @@ -871,7 +863,28 @@ int mc_FindIPv4ServerAddress(uint32_t *all_ips,int max_ips)
result=0;
c=0;

#ifndef WIN32
#ifdef MAC_OSX
struct ifaddrs *ifaddr = NULL;
if (getifaddrs(&ifaddr) == -1) {
return c;
}
if (!ifaddr) {
return c;
}
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock > 0) {
for (struct ifaddrs *ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == 0) {
continue;
}
int family = ifa->ifa_addr->sa_family;
if (family != AF_INET) {
continue;
}
uint32_t a = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
ptr=(unsigned char*)&a;

#elif !defined WIN32

int sock;
struct ifreq ifreqs[20];
Expand Down Expand Up @@ -927,7 +940,13 @@ int mc_FindIPv4ServerAddress(uint32_t *all_ips,int max_ips)

}
}
#ifdef MAC_OSX
if (sock > 0) {
close(sock);
}
freeifaddrs(ifaddr);
#endif
return c;
}