diff --git a/build/premake/premake4.lua b/build/premake/premake4.lua index 8099d11260..71b2823f34 100644 --- a/build/premake/premake4.lua +++ b/build/premake/premake4.lua @@ -617,6 +617,7 @@ function setup_all_libs () -- note: don't add "lib/sysdep/os/win/aken.cpp" because that must be compiled with the DDK. windows = { "lib/sysdep/os/win", "lib/sysdep/os/win/wposix", "lib/sysdep/os/win/whrt" }, macosx = { "lib/sysdep/os/osx", "lib/sysdep/os/unix" }, + bsd = { "lib/sysdep/os/bsd", "lib/sysdep/os/unix", "lib/sysdep/os/unix/x" }, } for i,v in pairs(sysdep_dirs[os.get()]) do table.insert(source_dirs, v); diff --git a/build/workspaces/clean-workspaces.sh b/build/workspaces/clean-workspaces.sh index 58b354d7ab..c1155cdc32 100755 --- a/build/workspaces/clean-workspaces.sh +++ b/build/workspaces/clean-workspaces.sh @@ -1,5 +1,14 @@ #!/bin/sh +# FreeBSD's make is different than GNU make, so we allow overriding the make command. +# If not set, MAKE will default to "gmake" on FreeBSD, or "make" on other OSes +if [ "`uname -s`" = "FreeBSD" ] +then + MAKE=${MAKE:="gmake"} +else + MAKE=${MAKE:="make"} +fi + # (We don't attempt to clean up every last file here - output in # binaries/system/ will still be there, etc. This is mostly just # to quickly fix problems in the bundled dependencies.) @@ -14,7 +23,7 @@ echo "Cleaning bundled third-party dependencies..." (cd ../../libraries/spidermonkey && rm -rf ./js-1.8.5) (cd ../../libraries/nvtt/src && rm -rf ./build) -(cd ../premake/premake4/build/gmake.unix && make clean) +(cd ../premake/premake4/build/gmake.unix && ${MAKE} clean) echo "Cleaning build output..." diff --git a/build/workspaces/update-workspaces.sh b/build/workspaces/update-workspaces.sh index aa01560057..16ac370142 100644 --- a/build/workspaces/update-workspaces.sh +++ b/build/workspaces/update-workspaces.sh @@ -8,6 +8,15 @@ die() JOBS=${JOBS:="-j2"} +# FreeBSD's make is different than GNU make, so we allow overriding the make command. +# If not set, MAKE will default to "gmake" on FreeBSD, or "make" on other OSes +if [ "`uname -s`" = "FreeBSD" ] +then + MAKE=${MAKE:="gmake"} +else + MAKE=${MAKE:="make"} +fi + # Parse command-line options: premake_args="" @@ -44,24 +53,24 @@ echo "Updating bundled third-party dependencies..." echo # Build/update bundled external libraries -(cd ../../libraries/fcollada/src && make ${JOBS}) || die "FCollada build failed" +(cd ../../libraries/fcollada/src && ${MAKE} ${JOBS}) || die "FCollada build failed" echo if [ "$with_system_mozjs185" = "false" ]; then - (cd ../../libraries/spidermonkey && JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed" + (cd ../../libraries/spidermonkey && MAKE=${MAKE} JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed" fi echo if [ "$with_system_nvtt" = "false" ]; then - (cd ../../libraries/nvtt && JOBS=${JOBS} ./build.sh) || die "NVTT build failed" + (cd ../../libraries/nvtt && MAKE=${MAKE} JOBS=${JOBS} ./build.sh) || die "NVTT build failed" fi echo if [ "$with_system_enet" = "false" ]; then - (cd ../../libraries/enet && JOBS=${JOBS} ./build.sh) || die "ENet build failed" + (cd ../../libraries/enet && MAKE=${MAKE} JOBS=${JOBS} ./build.sh) || die "ENet build failed" fi echo # Now build premake and run it to create the makefiles cd ../premake/premake4 -make -C build/gmake.unix ${JOBS} || die "Premake build failed" +${MAKE} -C build/gmake.unix ${JOBS} || die "Premake build failed" echo diff --git a/source/graphics/ModelAbstract.cpp b/source/graphics/ModelAbstract.cpp index 601b064980..aa56125cb7 100644 --- a/source/graphics/ModelAbstract.cpp +++ b/source/graphics/ModelAbstract.cpp @@ -89,4 +89,4 @@ void CModelAbstract::CalcSelectionBox() objBounds.Transform(GetTransform(), m_SelectionBox); } -} \ No newline at end of file +} diff --git a/source/graphics/TerrainTextureEntry.cpp b/source/graphics/TerrainTextureEntry.cpp index a0901f1a38..6682f744c8 100644 --- a/source/graphics/TerrainTextureEntry.cpp +++ b/source/graphics/TerrainTextureEntry.cpp @@ -102,4 +102,4 @@ void CTerrainTextureEntry::BuildBaseColor() const float* CTerrainTextureEntry::GetTextureMatrix() { return &m_TextureMatrix._11; -} \ No newline at end of file +} diff --git a/source/graphics/TerritoryBoundary.cpp b/source/graphics/TerritoryBoundary.cpp index cf7982cb4d..da0fcd2419 100644 --- a/source/graphics/TerritoryBoundary.cpp +++ b/source/graphics/TerritoryBoundary.cpp @@ -216,4 +216,4 @@ std::vector CTerritoryBoundaryCalculator::ComputeBoundaries( } return boundaries; -} \ No newline at end of file +} diff --git a/source/graphics/TextRenderer.h b/source/graphics/TextRenderer.h index 394010c617..fce45b6c25 100644 --- a/source/graphics/TextRenderer.h +++ b/source/graphics/TextRenderer.h @@ -64,4 +64,4 @@ private: std::vector m_Batches; }; -#endif // INCLUDED_TEXTRENDERER \ No newline at end of file +#endif // INCLUDED_TEXTRENDERER diff --git a/source/lib/sysdep/os/bsd/bcpu.cpp b/source/lib/sysdep/os/bsd/bcpu.cpp new file mode 100644 index 0000000000..ea3394520b --- /dev/null +++ b/source/lib/sysdep/os/bsd/bcpu.cpp @@ -0,0 +1,124 @@ +/* Copyright (c) 2012 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "precompiled.h" + +#include "lib/sysdep/os_cpu.h" +#include "lib/alignment.h" +#include "lib/bits.h" +#include "lib/module_init.h" + +#include "valgrind.h" +#include + +size_t os_cpu_NumProcessors() +{ + static size_t numProcessors; + + if(numProcessors == 0) + { + // Valgrind reports the number of real CPUs, but only emulates a single CPU. + // That causes problems when we expect all those CPUs to be distinct, so + // just pretend there's only one CPU + if (RUNNING_ON_VALGRIND) + numProcessors = 1; + else + { + long res = sysconf(_SC_NPROCESSORS_CONF); + ENSURE(res != -1); + numProcessors = (size_t)res; + } + } + + return numProcessors; +} + + +uintptr_t os_cpu_ProcessorMask() +{ + static uintptr_t processorMask; + + if(!processorMask) + processorMask = bit_mask(os_cpu_NumProcessors()); + + return processorMask; +} + + +size_t os_cpu_PageSize() +{ + static size_t pageSize; + + if(!pageSize) + pageSize = (size_t)sysconf(_SC_PAGESIZE); + + return pageSize; +} + + +size_t os_cpu_LargePageSize() +{ + // assume they're unsupported. + return 0; +} + + +size_t os_cpu_QueryMemorySize() +{ + size_t memorySize = 0; + size_t len = sizeof(memorySize); + // Argh, the API doesn't seem to be const-correct + /*const*/ int mib[2] = { CTL_HW, HW_PHYSMEM }; + sysctl(mib, 2, &memorySize, &len, 0, 0); + memorySize /= MiB; + return memorySize; +} + + +size_t os_cpu_MemoryAvailable() +{ + size_t memoryAvailable = 0; + size_t len = sizeof(memoryAvailable); + // Argh, the API doesn't seem to be const-correct + /*const*/ int mib[2] = { CTL_HW, HW_USERMEM }; + sysctl(mib, 2, &memoryAvailable, &len, 0, 0); + memoryAvailable /= MiB; + return memoryAvailable; +} + +uintptr_t os_cpu_SetThreadAffinityMask(uintptr_t UNUSED(processorMask)) +{ + // not yet implemented + return os_cpu_ProcessorMask(); +} + +Status os_cpu_CallByEachCPU(OsCpuCallback cb, uintptr_t cbData) +{ + for(size_t processor = 0; processor < os_cpu_NumProcessors(); processor++) + { + const uintptr_t processorMask = uintptr_t(1) << processor; + os_cpu_SetThreadAffinityMask(processorMask); + cb(processor, cbData); + } + + return INFO::OK; +} diff --git a/source/lib/sysdep/os/bsd/bdbg.cpp b/source/lib/sysdep/os/bsd/bdbg.cpp new file mode 100644 index 0000000000..89cb1aa339 --- /dev/null +++ b/source/lib/sysdep/os/bsd/bdbg.cpp @@ -0,0 +1,129 @@ +/* Copyright (c) 2012 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Note: This used to use BFD to get more useful debugging information. +// (See SVN r8270 if you want that code.) +// That requires binutils at runtime, which hits some bugs and library versioning +// issues on some Linux distros. +// The debugging info reported by this code with BFD wasn't especially useful, +// and it's easy enough to get people to run in gdb if we want a proper backtrace. +// So we now go with the simple approach of not using BFD. + +#include "precompiled.h" + +#include "lib/sysdep/sysdep.h" +#include "lib/debug.h" + +#include + +void* debug_GetCaller(void* UNUSED(context), const wchar_t* UNUSED(lastFuncToSkip)) +{ + // bt[0] == this function + // bt[1] == our caller + // bt[2] == the first caller they are interested in + // HACK: we currently don't support lastFuncToSkip (would require debug information), + // instead just returning the caller of the function calling us + void *bt[3]; + int bt_size = backtrace(bt, 3); + if (bt_size < 3) + return NULL; + return bt[2]; +} + +Status debug_DumpStack(wchar_t* buf, size_t max_chars, void* UNUSED(context), const wchar_t* UNUSED(lastFuncToSkip)) +{ + static const size_t N_FRAMES = 16; + void *bt[N_FRAMES]; + int bt_size = 0; + wchar_t *bufpos = buf; + wchar_t *bufend = buf + max_chars; + + bt_size = backtrace(bt, ARRAY_SIZE(bt)); + + // Assumed max length of a single print-out + static const size_t MAX_OUT_CHARS = 1024; + + for (size_t i = 0; (int)i < bt_size && bufpos+MAX_OUT_CHARS < bufend; i++) + { + wchar_t file[DEBUG_FILE_CHARS]; + wchar_t symbol[DEBUG_SYMBOL_CHARS]; + int line; + int len; + + if (debug_ResolveSymbol(bt[i], symbol, file, &line) == 0) + { + if (file[0]) + len = swprintf(bufpos, MAX_OUT_CHARS, L"(%p) %ls:%d %ls\n", bt[i], file, line, symbol); + else + len = swprintf(bufpos, MAX_OUT_CHARS, L"(%p) %ls\n", bt[i], symbol); + } + else + { + len = swprintf(bufpos, MAX_OUT_CHARS, L"(%p)\n", bt[i]); + } + + if (len < 0) + { + // MAX_OUT_CHARS exceeded, realistically this was caused by some + // mindbogglingly long symbol name... replace the end with an + // ellipsis and a newline + memcpy(&bufpos[MAX_OUT_CHARS-6], L"...\n", 5*sizeof(wchar_t)); + len = MAX_OUT_CHARS; + } + + bufpos += len; + } + + return INFO::OK; +} + +Status debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, wchar_t* file, int* line) +{ + if (sym_name) + *sym_name = 0; + if (file) + *file = 0; + if (line) + *line = 0; + + char** symbols = backtrace_symbols(&ptr_of_interest, 1); + if (symbols) + { + swprintf_s(sym_name, DEBUG_SYMBOL_CHARS, L"%hs", symbols[0]); + free(symbols); + + // (Note that this will usually return a pretty useless string, + // because we compile with -fvisibility=hidden and there won't be + // any exposed symbols for backtrace_symbols to report.) + + return INFO::OK; + } + else + { + return ERR::FAIL; + } +} + +void debug_SetThreadName(char const* UNUSED(name)) +{ + // Currently unimplemented +} diff --git a/source/lib/sysdep/os/bsd/bsd.cpp b/source/lib/sysdep/os/bsd/bsd.cpp new file mode 100644 index 0000000000..34e1460501 --- /dev/null +++ b/source/lib/sysdep/os/bsd/bsd.cpp @@ -0,0 +1,73 @@ +/* Copyright (c) 2012 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "precompiled.h" + +#include "lib/sysdep/sysdep.h" + +#define GNU_SOURCE +#include "mocks/dlfcn.h" +#include "mocks/unistd.h" + +#include + +OsPath sys_ExecutablePathname() +{ + // Find the executable's filename + Dl_info dl_info; + memset(&dl_info, 0, sizeof(dl_info)); + if (!T::dladdr((void *)sys_ExecutablePathname, &dl_info) || !dl_info.dli_fname) + return OsPath(); + const char* path = dl_info.dli_fname; + + // If this looks like an absolute path, use realpath to get the normalized + // path (with no '.' or '..') + if (path[0] == '/') + { + char resolved[PATH_MAX]; + if (!realpath(path, resolved)) + return OsPath(); + return resolved; + } + + // If this looks like a relative path, resolve against cwd and use realpath + if (strchr(path, '/')) + { + char cwd[PATH_MAX]; + if (!T::getcwd(cwd, PATH_MAX)) + return OsPath(); + + char absolute[PATH_MAX]; + int ret = snprintf(absolute, PATH_MAX, "%s/%s", cwd, path); + if (ret < 0 || ret >= PATH_MAX) + return OsPath(); // path too long, or other error + char resolved[PATH_MAX]; + if (!realpath(absolute, resolved)) + return OsPath(); + return resolved; + } + + // If it's not a path at all, i.e. it's just a filename, we'd + // probably have to search through PATH to find it. + // That's complex and should be uncommon, so don't bother. + return OsPath(); +} diff --git a/source/lib/sysdep/os/bsd/dir_watch.cpp b/source/lib/sysdep/os/bsd/dir_watch.cpp new file mode 100644 index 0000000000..904ba54ee0 --- /dev/null +++ b/source/lib/sysdep/os/bsd/dir_watch.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2012 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "precompiled.h" +#include "lib/sysdep/dir_watch.h" + +// stub implementations + +Status dir_watch_Add(const OsPath& UNUSED(path), PDirWatch& UNUSED(dirWatch)) +{ + return INFO::OK; +} + +Status dir_watch_Poll(DirWatchNotifications& UNUSED(notifications)) +{ + return INFO::OK; +} diff --git a/source/maths/BoundingBoxOriented.cpp b/source/maths/BoundingBoxOriented.cpp index c5ff27a61a..12e287d315 100644 --- a/source/maths/BoundingBoxOriented.cpp +++ b/source/maths/BoundingBoxOriented.cpp @@ -83,4 +83,4 @@ bool CBoundingBoxOriented::RayIntersect(const CVector3D& origin, const CVector3D tMin_out = tMin; tMax_out = tMax; return true; -} \ No newline at end of file +} diff --git a/source/pch/gui/precompiled.h b/source/pch/gui/precompiled.h index 5a22b90f1a..59d08870d1 100644 --- a/source/pch/gui/precompiled.h +++ b/source/pch/gui/precompiled.h @@ -19,4 +19,4 @@ #if MSC_VERSION # pragma warning(disable:4250) // "inherits 'IGUITextOwner::IGUITextOwner::UpdateCachedSize' via dominance" -#endif \ No newline at end of file +#endif diff --git a/source/ps/Compress.cpp b/source/ps/Compress.cpp index e7acdc481d..594fc0338e 100644 --- a/source/ps/Compress.cpp +++ b/source/ps/Compress.cpp @@ -60,4 +60,4 @@ void DecompressZLib(const std::string& data, std::string& out, bool includeLengt ENSURE(destLen == out.size()); // TODO: better error reporting might be nice -} \ No newline at end of file +} diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp index 869fbfaf07..643bb5fa96 100644 --- a/source/ps/SavedGame.cpp +++ b/source/ps/SavedGame.cpp @@ -201,4 +201,4 @@ std::vector SavedGames::GetSavedGames(ScriptInterface& scriptI } return games; -} \ No newline at end of file +} diff --git a/source/ps/SavedGame.h b/source/ps/SavedGame.h index b37b7647bb..43ad873d36 100644 --- a/source/ps/SavedGame.h +++ b/source/ps/SavedGame.h @@ -34,4 +34,4 @@ std::vector GetSavedGames(ScriptInterface& scriptInterface); } -#endif // INCLUDED_SAVEDGAME \ No newline at end of file +#endif // INCLUDED_SAVEDGAME diff --git a/source/tools/atlas/AtlasUI/ErrorReporter/ErrorReporter.h b/source/tools/atlas/AtlasUI/ErrorReporter/ErrorReporter.h index 1b41a921a9..9cdaa9f6fc 100644 --- a/source/tools/atlas/AtlasUI/ErrorReporter/ErrorReporter.h +++ b/source/tools/atlas/AtlasUI/ErrorReporter/ErrorReporter.h @@ -1 +1 @@ -void ReportError(); \ No newline at end of file +void ReportError(); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp index 6321cfbe19..61940b32e2 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp @@ -247,4 +247,4 @@ void Brush::CreateUI(wxWindow* parent, wxSizer* sizer) spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Strength")), wxSizerFlags().Align(wxALIGN_CENTER|wxALIGN_RIGHT)); spinnerSizer->Add(new BrushStrengthCtrl(parent, *this), wxSizerFlags().Expand()); sizer->Add(spinnerSizer, wxSizerFlags().Expand()); -} \ No newline at end of file +}