Initial 64-bit support

develop
lethosor 2016-07-03 23:32:43 -04:00
parent 233a5e9c10
commit 2455e36510
16 changed files with 136 additions and 88 deletions

@ -58,6 +58,18 @@ if(MSVC)
add_definitions( "/wd4819" ) add_definitions( "/wd4819" )
endif() endif()
SET(DFHACK_BUILD_ARCH "32" CACHE STRING "Architecture to build ('32' or '64')")
IF("${DFHACK_BUILD_ARCH}" STREQUAL "32")
SET(DFHACK_BUILD_32 1)
SET(DFHACK_BUILD_64 0)
ELSEIF("${DFHACK_BUILD_ARCH}" STREQUAL "64")
SET(DFHACK_BUILD_32 0)
SET(DFHACK_BUILD_64 1)
ADD_DEFINITIONS(-DDFHACK64)
ELSE()
MESSAGE(SEND_ERROR "Invalid build architecture (should be 32/64): ${DFHACK_BUILD_ARCH}")
ENDIF()
IF(CMAKE_CROSSCOMPILING) IF(CMAKE_CROSSCOMPILING)
SET(DFHACK_NATIVE_BUILD_DIR "DFHACK_NATIVE_BUILD_DIR-NOTFOUND" CACHE FILEPATH "Path to a native build directory") SET(DFHACK_NATIVE_BUILD_DIR "DFHACK_NATIVE_BUILD_DIR-NOTFOUND" CACHE FILEPATH "Path to a native build directory")
INCLUDE("${DFHACK_NATIVE_BUILD_DIR}/ImportExecutables.cmake") INCLUDE("${DFHACK_NATIVE_BUILD_DIR}/ImportExecutables.cmake")
@ -152,8 +164,15 @@ IF(UNIX)
# enable C++11 features # enable C++11 features
add_definitions(-DLINUX_BUILD) add_definitions(-DLINUX_BUILD)
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -Wall -Wno-unused-variable") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -Wall -Wno-unused-variable")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -m32 -march=i686 -mtune=generic -std=c++0x") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -mtune=generic -std=c++0x")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -m32 -march=i686 -mtune=generic") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -mtune=generic")
IF(DFHACK_BUILD_64)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -mno-avx")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 -mno-avx")
ELSE()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -march=i686")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -march=i686")
ENDIF()
ELSEIF(MSVC) ELSEIF(MSVC)
# for msvc, tell it to always use 8-byte pointers to member functions to avoid confusion # for msvc, tell it to always use 8-byte pointers to member functions to avoid confusion
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /vmg /vmm /MP") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /vmg /vmm /MP")

@ -11,8 +11,12 @@ ELSE()
ENDIF() ENDIF()
IF(UNIX) IF(UNIX)
add_definitions(-DLINUX_BUILD) ADD_DEFINITIONS(-DLINUX_BUILD)
SET(CMAKE_C_FLAGS "-m32") IF(DFHACK_BUILD_64)
SET(CMAKE_C_FLAGS "-m64 -mno-avx")
ELSE()
SET(CMAKE_C_FLAGS "-m32")
ENDIF()
ENDIF() ENDIF()
SET (HDR_LIBLUA SET (HDR_LIBLUA

@ -276,11 +276,11 @@ virtual_identity *virtual_identity::find(void *vtable)
if (p->vtable_ptr && p->vtable_ptr != vtable) { if (p->vtable_ptr && p->vtable_ptr != vtable) {
std::cerr << "Conflicting vtable ptr for class '" << p->getName() std::cerr << "Conflicting vtable ptr for class '" << p->getName()
<< "': found 0x" << std::hex << unsigned(vtable) << "': found 0x" << std::hex << uintptr_t(vtable)
<< ", previous 0x" << unsigned(p->vtable_ptr) << std::dec << std::endl; << ", previous 0x" << uintptr_t(p->vtable_ptr) << std::dec << std::endl;
abort(); abort();
} else if (!p->vtable_ptr) { } else if (!p->vtable_ptr) {
uint32_t pv = unsigned(vtable); uintptr_t pv = uintptr_t(vtable);
pv -= Core::getInstance().vinfo->getRebaseDelta(); pv -= Core::getInstance().vinfo->getRebaseDelta();
std::cerr << "<vtable-address name='" << p->getOriginalName() << "' value='0x" std::cerr << "<vtable-address name='" << p->getOriginalName() << "' value='0x"
<< std::hex << pv << std::dec << "'/>" << std::endl; << std::hex << pv << std::dec << "'/>" << std::endl;
@ -292,7 +292,7 @@ virtual_identity *virtual_identity::find(void *vtable)
} }
std::cerr << "UNKNOWN CLASS '" << name << "': vtable = 0x" std::cerr << "UNKNOWN CLASS '" << name << "': vtable = 0x"
<< std::hex << unsigned(vtable) << std::dec << std::endl; << std::hex << uintptr_t(vtable) << std::dec << std::endl;
known[vtable] = NULL; known[vtable] = NULL;
return NULL; return NULL;

@ -30,6 +30,8 @@ namespace df {
NUMBER_IDENTITY_TRAITS(uint32_t); NUMBER_IDENTITY_TRAITS(uint32_t);
NUMBER_IDENTITY_TRAITS(int64_t); NUMBER_IDENTITY_TRAITS(int64_t);
NUMBER_IDENTITY_TRAITS(uint64_t); NUMBER_IDENTITY_TRAITS(uint64_t);
NUMBER_IDENTITY_TRAITS(intptr_t);
NUMBER_IDENTITY_TRAITS(uintptr_t);
NUMBER_IDENTITY_TRAITS(float); NUMBER_IDENTITY_TRAITS(float);
NUMBER_IDENTITY_TRAITS(double); NUMBER_IDENTITY_TRAITS(double);

@ -2310,8 +2310,8 @@ static void *checkaddr(lua_State *L, int idx, bool allow_null = false)
return rv; return rv;
} }
static uint32_t getImageBase() { return Core::getInstance().p->getBase(); } static uintptr_t getImageBase() { return Core::getInstance().p->getBase(); }
static int getRebaseDelta() { return Core::getInstance().vinfo->getRebaseDelta(); } static intptr_t getRebaseDelta() { return Core::getInstance().vinfo->getRebaseDelta(); }
static int8_t getModstate() { return Core::getInstance().getModstate(); } static int8_t getModstate() { return Core::getInstance().getModstate(); }
static std::string internal_strerror(int n) { return strerror(n); } static std::string internal_strerror(int n) { return strerror(n); }
@ -2344,7 +2344,7 @@ static int internal_getPE(lua_State *L)
static int internal_getAddress(lua_State *L) static int internal_getAddress(lua_State *L)
{ {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
uint32_t addr = Core::getInstance().vinfo->getAddress(name); uintptr_t addr = Core::getInstance().vinfo->getAddress(name);
if (addr) if (addr)
lua_pushnumber(L, addr); lua_pushnumber(L, addr);
else else
@ -2355,7 +2355,7 @@ static int internal_getAddress(lua_State *L)
static int internal_setAddress(lua_State *L) static int internal_setAddress(lua_State *L)
{ {
std::string name = luaL_checkstring(L, 1); std::string name = luaL_checkstring(L, 1);
uint32_t addr = (uint32_t)checkaddr(L, 2, true); uintptr_t addr = (uintptr_t)checkaddr(L, 2, true);
internal_getAddress(L); internal_getAddress(L);
// Set the address // Set the address
@ -2372,7 +2372,7 @@ static int internal_setAddress(lua_State *L)
} }
// Print via printerr, so that it is definitely logged to stderr.log. // Print via printerr, so that it is definitely logged to stderr.log.
uint32_t iaddr = addr - Core::getInstance().vinfo->getRebaseDelta(); uintptr_t iaddr = addr - Core::getInstance().vinfo->getRebaseDelta();
fprintf(stderr, "Setting global '%s' to %x (%x)\n", name.c_str(), addr, iaddr); fprintf(stderr, "Setting global '%s' to %x (%x)\n", name.c_str(), addr, iaddr);
fflush(stderr); fflush(stderr);
@ -2382,7 +2382,7 @@ static int internal_setAddress(lua_State *L)
static int internal_getVTable(lua_State *L) static int internal_getVTable(lua_State *L)
{ {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
uint32_t addr = (uint32_t)Core::getInstance().vinfo->getVTable(name); uintptr_t addr = (uintptr_t)Core::getInstance().vinfo->getVTable(name);
if (addr) if (addr)
lua_pushnumber(L, addr); lua_pushnumber(L, addr);
else else
@ -2412,9 +2412,9 @@ static int internal_getMemRanges(lua_State *L)
for(size_t i = 0; i < ranges.size(); i++) for(size_t i = 0; i < ranges.size(); i++)
{ {
lua_newtable(L); lua_newtable(L);
lua_pushnumber(L, (uint32_t)ranges[i].start); lua_pushnumber(L, (uintptr_t)ranges[i].start);
lua_setfield(L, -2, "start_addr"); lua_setfield(L, -2, "start_addr");
lua_pushnumber(L, (uint32_t)ranges[i].end); lua_pushnumber(L, (uintptr_t)ranges[i].end);
lua_setfield(L, -2, "end_addr"); lua_setfield(L, -2, "end_addr");
lua_pushstring(L, ranges[i].name); lua_pushstring(L, ranges[i].name);
lua_setfield(L, -2, "name"); lua_setfield(L, -2, "name");

@ -993,7 +993,7 @@ static int meta_ptr_tostring(lua_State *state)
lua_getfield(state, UPVAL_METATABLE, "__metatable"); lua_getfield(state, UPVAL_METATABLE, "__metatable");
const char *cname = lua_tostring(state, -1); const char *cname = lua_tostring(state, -1);
lua_pushstring(state, stl_sprintf("<%s: 0x%08x>", cname, (unsigned)ptr).c_str()); lua_pushstring(state, stl_sprintf("<%s: 0x%08x>", cname, (uintptr_t)ptr).c_str());
return 1; return 1;
} }

@ -118,8 +118,8 @@ Process::~Process()
string Process::doReadClassName (void * vptr) string Process::doReadClassName (void * vptr)
{ {
//FIXME: BAD!!!!! //FIXME: BAD!!!!!
char * typeinfo = Process::readPtr(((char *)vptr - 0x4)); char * typeinfo = Process::readPtr(((char *)vptr - sizeof(void*)));
char * typestring = Process::readPtr(typeinfo + 0x4); char * typestring = Process::readPtr(typeinfo + sizeof(void*));
string raw = readCString(typestring); string raw = readCString(typestring);
size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers
size_t end = raw.length(); size_t end = raw.length();
@ -151,9 +151,15 @@ void Process::getMemRanges( vector<t_memrange> & ranges )
the_task = mach_task_self(); the_task = mach_task_self();
#ifdef DFHACK64
mach_vm_size_t vmsize;
mach_vm_address_t address;
vm_region_basic_info_data_64_t info;
#else
vm_size_t vmsize; vm_size_t vmsize;
vm_address_t address; vm_address_t address;
vm_region_basic_info_data_t info; vm_region_basic_info_data_t info;
#endif
mach_msg_type_number_t info_count; mach_msg_type_number_t info_count;
vm_region_flavor_t flavor; vm_region_flavor_t flavor;
memory_object_name_t object; memory_object_name_t object;
@ -162,10 +168,18 @@ void Process::getMemRanges( vector<t_memrange> & ranges )
address = 0; address = 0;
do { do {
#ifdef DFHACK64
flavor = VM_REGION_BASIC_INFO_64;
info_count = VM_REGION_BASIC_INFO_COUNT_64;
kr = mach_vm_region(the_task, &address, &vmsize, flavor,
(vm_region_info_64_t)&info, &info_count, &object);
#else
flavor = VM_REGION_BASIC_INFO; flavor = VM_REGION_BASIC_INFO;
info_count = VM_REGION_BASIC_INFO_COUNT; info_count = VM_REGION_BASIC_INFO_COUNT;
kr = vm_region(the_task, &address, &vmsize, flavor, kr = vm_region(the_task, &address, &vmsize, flavor,
(vm_region_info_t)&info, &info_count, &object); (vm_region_info_t)&info, &info_count, &object);
#endif
if (kr == KERN_SUCCESS) { if (kr == KERN_SUCCESS) {
if (info.reserved==1) { if (info.reserved==1) {
address += vmsize; address += vmsize;

@ -122,8 +122,8 @@ Process::~Process()
string Process::doReadClassName (void * vptr) string Process::doReadClassName (void * vptr)
{ {
//FIXME: BAD!!!!! //FIXME: BAD!!!!!
char * typeinfo = Process::readPtr(((char *)vptr - 0x4)); char * typeinfo = Process::readPtr(((char *)vptr - sizeof(void*)));
char * typestring = Process::readPtr(typeinfo + 0x4); char * typestring = Process::readPtr(typeinfo + sizeof(void*));
string raw = readCString(typestring); string raw = readCString(typestring);
size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers size_t start = raw.find_first_of("abcdefghijklmnopqrstuvwxyz");// trim numbers
size_t end = raw.length(); size_t end = raw.length();

@ -305,7 +305,7 @@ VMethodInterposeLinkBase::VMethodInterposeLinkBase(virtual_identity *host, int v
*/ */
fprintf(stderr, "Bad VMethodInterposeLinkBase arguments: %d %08x (%s)\n", fprintf(stderr, "Bad VMethodInterposeLinkBase arguments: %d %08x (%s)\n",
vmethod_idx, unsigned(interpose_method), name_str); vmethod_idx, uintptr_t(interpose_method), name_str);
fflush(stderr); fflush(stderr);
abort(); abort();
} }

@ -69,7 +69,7 @@ VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash)
return 0; return 0;
} }
VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uint32_t timestamp) VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uintptr_t timestamp)
{ {
for(size_t i = 0; i < versions.size();i++) for(size_t i = 0; i < versions.size();i++)
{ {
@ -140,7 +140,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
} }
if ((is_vtable && no_vtables) || (!is_vtable && no_globals)) if ((is_vtable && no_vtables) || (!is_vtable && no_globals))
continue; continue;
uint32_t addr = strtol(cstr_value, 0, 0); uintptr_t addr = strtol(cstr_value, 0, 0);
if (is_vtable) if (is_vtable)
mem->setVTable(cstr_key, addr); mem->setVTable(cstr_key, addr);
else else

@ -487,6 +487,8 @@ namespace df
NUMBER_IDENTITY_TRAITS(uint32_t); NUMBER_IDENTITY_TRAITS(uint32_t);
NUMBER_IDENTITY_TRAITS(int64_t); NUMBER_IDENTITY_TRAITS(int64_t);
NUMBER_IDENTITY_TRAITS(uint64_t); NUMBER_IDENTITY_TRAITS(uint64_t);
NUMBER_IDENTITY_TRAITS(intptr_t);
NUMBER_IDENTITY_TRAITS(uintptr_t);
NUMBER_IDENTITY_TRAITS(float); NUMBER_IDENTITY_TRAITS(float);
NUMBER_IDENTITY_TRAITS(double); NUMBER_IDENTITY_TRAITS(double);

@ -49,10 +49,10 @@ namespace DFHack
{ {
private: private:
std::vector <std::string> md5_list; std::vector <std::string> md5_list;
std::vector <uint32_t> PE_list; std::vector <uintptr_t> PE_list;
std::map <std::string, uint32_t> Addresses; std::map <std::string, uintptr_t> Addresses;
std::map <std::string, uint32_t> VTables; std::map <std::string, uintptr_t> VTables;
uint32_t base; uintptr_t base;
int rebase_delta; int rebase_delta;
std::string version; std::string version;
OSType OS; OSType OS;
@ -75,10 +75,10 @@ namespace DFHack
OS = rhs.OS; OS = rhs.OS;
}; };
uint32_t getBase () const { return base; }; uintptr_t getBase () const { return base; };
int getRebaseDelta() const { return rebase_delta; } int getRebaseDelta() const { return rebase_delta; }
void setBase (const uint32_t _base) { base = _base; }; void setBase (const uintptr_t _base) { base = _base; };
void rebaseTo(const uint32_t new_base) void rebaseTo(const uintptr_t new_base)
{ {
int64_t old = base; int64_t old = base;
int64_t newx = new_base; int64_t newx = new_base;
@ -100,11 +100,11 @@ namespace DFHack
return std::find(md5_list.begin(), md5_list.end(), _md5) != md5_list.end(); return std::find(md5_list.begin(), md5_list.end(), _md5) != md5_list.end();
}; };
void addPE (uint32_t PE_) void addPE (uintptr_t PE_)
{ {
PE_list.push_back(PE_); PE_list.push_back(PE_);
}; };
bool hasPE (uint32_t PE_) const bool hasPE (uintptr_t PE_) const
{ {
return std::find(PE_list.begin(), PE_list.end(), PE_) != PE_list.end(); return std::find(PE_list.begin(), PE_list.end(), PE_) != PE_list.end();
}; };
@ -115,7 +115,7 @@ namespace DFHack
}; };
std::string getVersion() const { return version; }; std::string getVersion() const { return version; };
void setAddress (const std::string& key, const uint32_t value) void setAddress (const std::string& key, const uintptr_t value)
{ {
Addresses[key] = value; Addresses[key] = value;
}; };
@ -129,7 +129,7 @@ namespace DFHack
return true; return true;
}; };
uint32_t getAddress (const std::string& key) const uintptr_t getAddress (const std::string& key) const
{ {
auto i = Addresses.find(key); auto i = Addresses.find(key);
if(i == Addresses.end()) if(i == Addresses.end())
@ -137,7 +137,7 @@ namespace DFHack
return (*i).second; return (*i).second;
} }
void setVTable (const std::string& key, const uint32_t value) void setVTable (const std::string& key, const uintptr_t value)
{ {
VTables[key] = value; VTables[key] = value;
}; };

@ -40,7 +40,7 @@ namespace DFHack
bool loadFile( std::string path_to_xml); bool loadFile( std::string path_to_xml);
bool isInErrorState() const {return error;}; bool isInErrorState() const {return error;};
VersionInfo * getVersionInfoByMD5(std::string md5string); VersionInfo * getVersionInfoByMD5(std::string md5string);
VersionInfo * getVersionInfoByPETimestamp(uint32_t timestamp); VersionInfo * getVersionInfoByPETimestamp(uintptr_t timestamp);
std::vector<VersionInfo*> versions; std::vector<VersionInfo*> versions;
// trash existing list // trash existing list
void clear(); void clear();

@ -116,7 +116,7 @@ namespace std {
std::size_t operator()(const DFHack::EventManager::EventHandler& h) const { std::size_t operator()(const DFHack::EventManager::EventHandler& h) const {
size_t r = 17; size_t r = 17;
const size_t m = 65537; const size_t m = 65537;
r = m*(r+(int32_t)h.eventHandler); r = m*(r+(intptr_t)h.eventHandler);
r = m*(r+h.freq); r = m*(r+h.freq);
return r; return r;
} }

@ -1173,52 +1173,52 @@ void Buildings::clearBuildings(color_ostream& out) {
void Buildings::updateBuildings(color_ostream& out, void* ptr) void Buildings::updateBuildings(color_ostream& out, void* ptr)
{ {
int32_t id = (int32_t)ptr; // int32_t id = (int32_t)ptr;
auto building = df::building::find(id); // auto building = df::building::find(id);
if (building) // if (building)
{ // {
// Already cached -> weird, so bail out // // Already cached -> weird, so bail out
if (corner1.count(id)) // if (corner1.count(id))
return; // return;
// Civzones cannot be cached because they can // // Civzones cannot be cached because they can
// overlap each other and normal buildings. // // overlap each other and normal buildings.
if (!building->isSettingOccupancy()) // if (!building->isSettingOccupancy())
return; // return;
df::coord p1(min(building->x1, building->x2), min(building->y1,building->y2), building->z); // df::coord p1(min(building->x1, building->x2), min(building->y1,building->y2), building->z);
df::coord p2(max(building->x1, building->x2), max(building->y1,building->y2), building->z); // df::coord p2(max(building->x1, building->x2), max(building->y1,building->y2), building->z);
corner1[id] = p1; // corner1[id] = p1;
corner2[id] = p2; // corner2[id] = p2;
for ( int32_t x = p1.x; x <= p2.x; x++ ) { // for ( int32_t x = p1.x; x <= p2.x; x++ ) {
for ( int32_t y = p1.y; y <= p2.y; y++ ) { // for ( int32_t y = p1.y; y <= p2.y; y++ ) {
df::coord pt(x,y,building->z); // df::coord pt(x,y,building->z);
if (containsTile(building, pt, false)) // if (containsTile(building, pt, false))
locationToBuilding[pt] = id; // locationToBuilding[pt] = id;
} // }
} // }
} // }
else if (corner1.count(id)) // else if (corner1.count(id))
{ // {
//existing building: destroy it // //existing building: destroy it
df::coord p1 = corner1[id]; // df::coord p1 = corner1[id];
df::coord p2 = corner2[id]; // df::coord p2 = corner2[id];
for ( int32_t x = p1.x; x <= p2.x; x++ ) { // for ( int32_t x = p1.x; x <= p2.x; x++ ) {
for ( int32_t y = p1.y; y <= p2.y; y++ ) { // for ( int32_t y = p1.y; y <= p2.y; y++ ) {
df::coord pt(x,y,p1.z); // df::coord pt(x,y,p1.z);
auto cur = locationToBuilding.find(pt); // auto cur = locationToBuilding.find(pt);
if (cur != locationToBuilding.end() && cur->second == id) // if (cur != locationToBuilding.end() && cur->second == id)
locationToBuilding.erase(cur); // locationToBuilding.erase(cur);
} // }
} // }
corner1.erase(id); // corner1.erase(id);
corner2.erase(id); // corner2.erase(id);
} // }
} }
void Buildings::getStockpileContents(df::building_stockpilest *stockpile, std::vector<df::item*> *items) void Buildings::getStockpileContents(df::building_stockpilest *stockpile, std::vector<df::item*> *items)

@ -1,8 +1,15 @@
IF(UNIX) IF(UNIX)
add_definitions(-DLINUX_BUILD) add_definitions(-DLINUX_BUILD)
SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall") SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -m32 -std=c++0x") SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -std=c++0x")
SET(CMAKE_C_FLAGS "-fvisibility=hidden -m32") SET(CMAKE_C_FLAGS "-fvisibility=hidden")
IF(DFHACK_BUILD_64)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -mno-avx")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 -mno-avx")
ELSE()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
ENDIF()
ENDIF() ENDIF()
include_directories("${dfhack_SOURCE_DIR}/library/include") include_directories("${dfhack_SOURCE_DIR}/library/include")