As of https://github.com/OpenRCT2/OpenLoco/pull/236, we are using vcpkg for OpenLoco's dependency management, both for Windows and macOS. Now, on macOS, we require Boost's filesystem component as well, as use std::filesystem is not provided yet. As of yet, we are having some trouble getting this to work using vcpkg, however. @ras0219-msft suggested we file an issue.
Here is what I did to try to get Boost to work.
First, we clone the vcpkg repo, bootstrap it, and define triplets/x86-osx.cmake:
set(VCPKG_TARGET_ARCHITECTURE x86)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
set(VCPKG_C_FLAGS -m32)
set(VCPKG_CXX_FLAGS -m32)
We install our set of dependencies as follows. Note that we use a set of patches for SDL2, but it's not the problem at hand.
./vcpkg install sdl2:x86-osx \
sdl2-mixer:x86-osx \
yaml-cpp:x86-osx \
boost-filesystem:x86-osx
Next, we invoke cmake in a fresh build dir for OpenLoco:
cmake .. "-DCMAKE_TOOLCHAIN_FILE=../Dependencies/macos/vcpkg/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x86-osx
-- The CXX compiler identification is AppleClang 10.0.0.10001044
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/local/bin/pkg-config (found version "0.29.2")
-- Found SDL2_mixer: /Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/debug/lib/libSDL2_mixer.a (found version "2.0.2")
-- Boost version: 1.68.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/aaron/Projects/OpenLoco/OpenLoco/build2
Note that all dependencies, including Boost, have been found.
Invoking make yields successful compilation, but the linking phase ends with the following errors:
Undefined symbols for architecture i386:
"boost::system::detail::system_category_instance", referenced from:
boost::system::system_category() in hooks.cpp.o
"boost::system::detail::generic_category_instance", referenced from:
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
boost::system::generic_category() in audio.cpp.o
boost::system::generic_category() in channel.cpp.o
boost::system::generic_category() in music_channel.cpp.o
boost::system::generic_category() in vehicle_channel.cpp.o
boost::system::generic_category() in config.cpp.o
boost::system::generic_category() in environment.cpp.o
boost::system::generic_category() in gfx.cpp.o
...
...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Now, the error suggests the binaries built for a different architecture. However, when we inspect the binaries in question:
$ lipo -info libboost_*
Non-fat file: libboost_filesystem.a is architecture: i386
Non-fat file: libboost_regex.a is architecture: i386
Non-fat file: libboost_system.a is architecture: i386
As for the symbols:
$ nm libboost_filesystem.a | grep -E '(system|generic)_category_instance'
$ nm libboost_system.a | grep -E '(system|generic)_category_instance'
00014308 b __ZGVZN5boost6system6detail19system_category_ncxEvE24system_category_instance
0001431c b __ZGVZN5boost6system6detail20generic_category_ncxEvE25generic_category_instance
000142fc b __ZZN5boost6system6detail19system_category_ncxEvE24system_category_instance
00014310 b __ZZN5boost6system6detail20generic_category_ncxEvE25generic_category_instance
I searched around a bit and eventually found https://github.com/boostorg/system/issues/26, which sounded like a reasonable hypothesis, but have been unable to get it to work.
Any help would be greatly appreciated!
Can you post output of make VERBOSE=1? It looks like the library chosen by linker is not the one for expected architecture, do you have boost-filesystem:AMD64-osx installed as well?
No, I haven't installed any of the 64-bits variants — just the x86-osx packages.
The linker command used is as follows (linebreaks mine for clarity):
/Library/Developer/CommandLineTools/usr/bin/c++ \
-DDEBUG=0 \
-m32 \
-fstrict-aliasing \
-Werror \
-Wall \
-Wno-unknown-pragmas \
-Wno-unused-private-field \
-Waddress \
-Warray-bounds \
-Wchar-subscripts \
-Wenum-compare \
-Wformat \
-Wignored-qualifiers \
-Winit-self \
-Wmissing-declarations \
-Wnon-virtual-dtor \
-Wnull-dereference \
-Wstrict-aliasing \
-Wstrict-overflow=1 \
-Wundef \
-Wunreachable-code \
-Wnon-virtual-dtor \
-Wl,-search_paths_first \
-Wl,-headerpad_max_install_names \
-m32 \
-m32 \
-fno-pie \
-sectcreate loco_text __text "/Users/aaron/Projects/OpenLoco/OpenLoco/build2/openloco_text" \
-sectcreate loco_data __data /Users/aaron/Projects/OpenLoco/OpenLoco/build2/openloco_data \
-segaddr loco_data 0x4d7000 \
-segprot loco_data rwx rwx \
-segaddr loco_text 0x401000 \
-segprot loco_text rwx rwx \
-segaddr __TEXT 0x2000000 \
-read_only_relocs suppress \
CMakeFiles/openloco.dir/src/openloco/audio/audio.cpp.o \
CMakeFiles/openloco.dir/src/openloco/audio/channel.cpp.o \
CMakeFiles/openloco.dir/src/openloco/audio/music_channel.cpp.o \
CMakeFiles/openloco.dir/src/openloco/audio/vehicle_channel.cpp.o \
CMakeFiles/openloco.dir/src/openloco/company.cpp.o \
CMakeFiles/openloco.dir/src/openloco/companymgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/config.cpp.o \
CMakeFiles/openloco.dir/src/openloco/console.cpp.o \
CMakeFiles/openloco.dir/src/openloco/date.cpp.o \
CMakeFiles/openloco.dir/src/openloco/environment.cpp.o \
CMakeFiles/openloco.dir/src/openloco/graphics/colour.cpp.o \
CMakeFiles/openloco.dir/src/openloco/graphics/gfx.cpp.o \
CMakeFiles/openloco.dir/src/openloco/gui.cpp.o \
CMakeFiles/openloco.dir/src/openloco/industry.cpp.o \
CMakeFiles/openloco.dir/src/openloco/industrymgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/input.cpp.o \
CMakeFiles/openloco.dir/src/openloco/input/mouse_input.cpp.o \
CMakeFiles/openloco.dir/src/openloco/interop/hook.cpp.o \
CMakeFiles/openloco.dir/src/openloco/interop/hooks.cpp.o \
CMakeFiles/openloco.dir/src/openloco/interop/interop.cpp.o \
CMakeFiles/openloco.dir/src/openloco/intro.cpp.o \
CMakeFiles/openloco.dir/src/openloco/localisation/conversion.cpp.o \
CMakeFiles/openloco.dir/src/openloco/localisation/languagefiles.cpp.o \
CMakeFiles/openloco.dir/src/openloco/localisation/languages.cpp.o \
CMakeFiles/openloco.dir/src/openloco/localisation/stringmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/localisation/unicode.cpp.o \
CMakeFiles/openloco.dir/src/openloco/map/tile.cpp.o \
CMakeFiles/openloco.dir/src/openloco/map/tilemgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/messagemgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/objects/objectmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/openloco.cpp.o \
CMakeFiles/openloco.dir/src/openloco/platform/platform.posix.cpp.o \
CMakeFiles/openloco.dir/src/openloco/platform/platform.windows.cpp.o \
CMakeFiles/openloco.dir/src/openloco/progressbar.cpp.o \
CMakeFiles/openloco.dir/src/openloco/scenariomgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/station.cpp.o \
CMakeFiles/openloco.dir/src/openloco/stationmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/things/misc.cpp.o \
CMakeFiles/openloco.dir/src/openloco/things/thing.cpp.o \
CMakeFiles/openloco.dir/src/openloco/things/thingmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/things/vehicle.cpp.o \
CMakeFiles/openloco.dir/src/openloco/town.cpp.o \
CMakeFiles/openloco.dir/src/openloco/townmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/tutorial.cpp.o \
CMakeFiles/openloco.dir/src/openloco/ui.cpp.o \
CMakeFiles/openloco.dir/src/openloco/ui/dropdown.cpp.o \
CMakeFiles/openloco.dir/src/openloco/ui/scrollview.cpp.o \
CMakeFiles/openloco.dir/src/openloco/ui/viewport_interaction.cpp.o \
CMakeFiles/openloco.dir/src/openloco/utility/string.cpp.o \
CMakeFiles/openloco.dir/src/openloco/version.cpp.o \
CMakeFiles/openloco.dir/src/openloco/viewportmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/widget.cpp.o \
CMakeFiles/openloco.dir/src/openloco/window.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windowmgr.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/about.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/about_music.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/constructionwnd.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/map.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/options.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/promptbrowsewnd.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/promptokcancelwnd.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/stationwnd.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/textinputwnd.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/title_exit.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/title_logo.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/title_menu.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/title_options.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/title_version.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/tooltip.cpp.o \
CMakeFiles/openloco.dir/src/openloco/windows/townwnd.cpp.o \
CMakeFiles/openloco.dir/src/openloco/platform/platform.macos.mm.o \
-o openloco \
/Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/\debug/lib/libSDL2d.a \
/Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/debug/lib/libSDL2_mixer.a \
/Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/debug/lib/libyaml-cpp.a \
/Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/debug/lib/libyaml-cpp.a \
/Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/debug/lib/libboost_filesystem.a \
/Users/aaron/Projects/OpenLoco/Dependencies/macos/vcpkg/installed/x86-osx/debug/lib/libboost_system.a \
-framework Cocoa -lm -liconv \
-framework CoreVideo \
-framework Cocoa \
-framework IOKit \
-framework ForceFeedback \
-framework Carbon \
-framework CoreAudio \
-framework AudioToolbox \
-Wl, \
-undefined,error
The problem is likely that boost::system::detail::system_category_instance _et al._ are not exposed from Boost; note b in nm's output, whereas it should be B or D.
Hi,
As it happens, I just bumped into exactly the same problem. Like you say, it seems like its related to https://github.com/boostorg/system/issues/26. Did you managed to build vcpkg's boost with C++ 14 by any chance? I'm going to try that next.
Well, I've managed to fix my problems by building boost using C++14. My adventures are narrated here: https://github.com/Microsoft/vcpkg/issues/4476. However, please note I am using LLVM's Clang rather than XCode to build my vcpkg tree. Good luck.
@AaronVanGeffen Thanks for posting and thanks to @mcraveiro for investigating!
I am able to reproduce these issues _exactly_ via
//main.cpp
#include <boost/system/error_code.hpp>
int main()
{
boost::system::system_category();
return 0;
}
and building (that main.cpp) with and without c++14 support while linking boost_system from vcpkg:
# with 14
$ make
[100%] Linking CXX executable main
Undefined symbols for architecture x86_64:
"boost::system::detail::system_category_instance", referenced from:
boost::system::system_category() in main.cpp.o
"boost::system::detail::generic_category_instance", referenced from:
boost::system::generic_category() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
# without 14
$ make
[100%] Linking CXX executable main
[100%] Built target main
Now, for what to do about it. We could start building in 14 by default, with instructions for users on how to drop back to 11 if desired; I'm not really sure what the current "state of OSX" is here as far as how things tend to be built. A good meterstick would be whatever Homebrew currently does.
I personally think that the whole boost approach of "we default to C++ 14 for GCC but not for Clang" is really not ideal :-) Given clang has pretty decent support too, they should have the same behaviour across the board. But, at any rate, I for one am in favour of defaulting vcpkg to C++ 14.
Now, for what to do about it. We could start building in 14 by default, with instructions for users on how to drop back to 11 if desired; I'm not really sure what the current "state of OSX" is here as far as how things tend to be built. A good meterstick would be whatever Homebrew currently does.
Going by homebrew-core/Formula/boost.rb, Homebrew has been explicitly compiling Boost as C++14 for a while now:
# Boost is using "clang++ -x c" to select C compiler which breaks C++14
# handling using ENV.cxx14. Using "cxxflags" and "linkflags" still works.
args << "cxxflags=-std=c++14"
if ENV.compiler == :clang
args << "cxxflags=-stdlib=libc++" << "linkflags=-stdlib=libc++"
Perhaps a similar solution could be adopted by vcpkg?
Hello, is there an update about the bug? I'm facing something very similar.
Most helpful comment
Going by homebrew-core/Formula/boost.rb, Homebrew has been explicitly compiling Boost as C++14 for a while now:
Perhaps a similar solution could be adopted by vcpkg?