diff --git a/Docs/build_mac.md b/Docs/build_mac.md new file mode 100644 index 00000000000..46f735785a8 --- /dev/null +++ b/Docs/build_mac.md @@ -0,0 +1,114 @@ +# Mac build + +This guide details how to build CARLA from source on MacOS Monterey (Apple Silicon). This work is mostly experimental and serves primarily as a proof-of-concept for those interested in building CARLA 0.9.13 on the Apple Silicon devices. + +--- +## Prerequisites + +### System requirements + +* __MacOS 12__ This is for building on MacOS Monterey (12). The latest version this was tested on is 12.1 on my M1 Max. +* __130 GB disk space.__ Carla will take around 31 GB and Unreal Engine will take around 91 GB so have about 130 GB free to account for both of these plus additional minor software installations. +* __An adequate GPU.__ The M1 GPU's are very capable, though it is still recommended to get the Pro/Max's since I've found the performance to scale nearly linearly with number of GPU cores. +* __Two TCP ports and good internet connection.__ 2000 and 2001 by default. Make sure that these ports are not blocked by firewalls or any other applications. + +..warning:: + __If you are upgrading from CARLA 0.9.12 to 0.9.13__: you must first upgrade the CARLA fork of the UE4 engine to the latest version. See the [__Unreal Engine__](#unreal-engine) section for details on upgrading UE4 + +**WARNING**: UE4-carla does not build on MacOS 12 by default! See [this discussion](https://github.com/carla-simulator/carla/discussions/4848) for more details. + + +### Software requirements + +CARLA requires many different kinds of software to run. Some are built during the CARLA build process itself, such as *Boost.Python*. Others are binaries that should be installed before starting the build (*cmake*, *clang*, different versions of *Python*, etc.). To install these requirements, run the following commands: + +```bash +brew update && brew upgrade + +brew install --build-from-source mono + +brew install coreutils ninja wget autoconf automake curl libtool libpng aria2 libiconv +``` + +I recommend installing python through conda on mac: +```bash +conda create --name carla python=3.8 +conda activate carla +conda install numpy distro wheel +pip install setuptools==47.3.1 nose2 +``` + +(Install xcode through the app store, I used the latest (at time of writing) 12.2.1) +And then open up xcode and install the `xcode command line developer tools` +```bash +xcode-select --install +sudo xcode-select -s /Applications/Xcode.app +``` + +Finally, you'll also need [Rosetta 2](https://support.apple.com/en-us/HT211861) for the translation between x86 (UE4 prerequisite) and arm64 (native Apple Silicon) + +--- + +## Unreal Engine + +For now, refer to the Linux guide for how to build the engine, but note the [strange problem](https://github.com/carla-simulator/carla/discussions/4848) with building the Carla fork (not Vanilla 4.26.2) on Apple silicon. + +## Build CARLA + +Note: This time, the build procedure is somewhat hacky and fragmanted by nature of using different architectures, but it still works reasonably well. The procedure is as follows: +1. Build LibCarla in x86 +2. Build the UE4 carla game (also x86) +3. Build LibCarla (AGAIN) in arm64 +4. Build the PythonAPI in arm64 +5. Add the arm64 Python arm .egg file to your PYTHONPATH +6. Build the UE4 package in x86 (back to x86) + + +This is because the python scripts work much better in `arm64` but the game itself (which depends on UE4) must be built for x86 and run on rosetta2. + +The way I recommend you go about this is as follows: +```bash +# git clone and enter mac branch +./Update.sh # wait a while for the asset fetching to complete + +# go to Util/Buildtools/Environment.sh +# make sure the ARCH (for IS_MAC) is set to "x86_64" + +make LibCarla # in x86 +... + +make launch # in x86 (uses UE4 build and xcode cmd line) +... + +# go to Util/Buildtools/Environment.sh +# make sure the ARCH (for IS_MAC) is set to "arm64" +mv Build Build.x86 # denoting the current (x86) build as such + +make LibCarla # now in arm64! +... + +make PythonAPI # now in arm64 +... + +make check # unit tests to verify everything works! +... + +mv Build Build.arm64 + +# now you can switch between (re)building arm64 and x86 by renaming +# the Build.XYZ to just Build +# example: + +mv Build.x86 Build + +make package +... + +``` + +Also, as an aside, since (almost) all the PythonAPI scripts look for a `'linux-x86_64'` `.egg` file, you'll not be able to find it unless you modify EVERY single file, since this is too much work, you can simply add this to your PYTHONPATH via: +```bash +export PYTHONPATH="${PYTHONPATH}:/PATH/TO/CARLA/PythonAPI/carla/dist/carla-0.9.13-py3.8-macosx-11.0-arm64.egg" +# I simply put this in my .zshrc file +``` +Then you should be able to quickly `import carla` without hassle! \ No newline at end of file diff --git a/LibCarla/source/carla/Buffer.h b/LibCarla/source/carla/Buffer.h index 27b9ca4c3b7..3bc55f13be4 100644 --- a/LibCarla/source/carla/Buffer.h +++ b/LibCarla/source/carla/Buffer.h @@ -71,7 +71,7 @@ namespace carla { _data(std::make_unique(size)) {} /// @copydoc Buffer(size_type) - explicit Buffer(uint64_t size) + explicit Buffer(size_t size) : Buffer([size]() { if (size > max_size()) { throw_exception(std::invalid_argument("message size too big")); @@ -319,7 +319,7 @@ namespace carla { template typename std::enable_if::value>::type copy_from(size_type offset, const T &source) { - reset(boost::asio::buffer_size(source) + offset); + reset(static_cast(boost::asio::buffer_size(source)) + offset); DEBUG_ASSERT(boost::asio::buffer_size(source) == size() - offset); DEBUG_ONLY(auto bytes_copied = ) boost::asio::buffer_copy(buffer() + offset, source); diff --git a/LibCarla/source/carla/MsgPack.h b/LibCarla/source/carla/MsgPack.h index e771871b3a6..e219ea6d2f0 100644 --- a/LibCarla/source/carla/MsgPack.h +++ b/LibCarla/source/carla/MsgPack.h @@ -20,7 +20,8 @@ namespace carla { namespace mp = ::clmdep_msgpack; mp::sbuffer sbuf; mp::pack(sbuf, obj); - return Buffer(reinterpret_cast(sbuf.data()), sbuf.size()); + return Buffer(reinterpret_cast(sbuf.data()), + static_cast(sbuf.size())); } template diff --git a/LibCarla/source/carla/MsgPackAdaptors.h b/LibCarla/source/carla/MsgPackAdaptors.h index 395a9579cec..ab6565bab9d 100644 --- a/LibCarla/source/carla/MsgPackAdaptors.h +++ b/LibCarla/source/carla/MsgPackAdaptors.h @@ -115,7 +115,7 @@ namespace adaptor { v = o.via.array.ptr[1].as(); } - template + template static void copy_to_variant( const uint64_t index, const clmdep_msgpack::object &o, diff --git a/LibCarla/source/carla/road/element/Waypoint.cpp b/LibCarla/source/carla/road/element/Waypoint.cpp index e4917a92a20..b7d2a199fe1 100644 --- a/LibCarla/source/carla/road/element/Waypoint.cpp +++ b/LibCarla/source/carla/road/element/Waypoint.cpp @@ -13,12 +13,12 @@ namespace std { using WaypointHash = hash; WaypointHash::result_type WaypointHash::operator()(const argument_type &waypoint) const { - WaypointHash::result_type seed = 0u; + std::size_t seed = 0u; boost::hash_combine(seed, waypoint.road_id); boost::hash_combine(seed, waypoint.section_id); boost::hash_combine(seed, waypoint.lane_id); boost::hash_combine(seed, static_cast(std::floor(waypoint.s * 200.0))); - return seed; + return static_cast(seed); } } // namespace std diff --git a/LibCarla/source/carla/sensor/s11n/DVSEventArraySerializer.h b/LibCarla/source/carla/sensor/s11n/DVSEventArraySerializer.h index bc7ed0f735d..7f3afaa00ac 100644 --- a/LibCarla/source/carla/sensor/s11n/DVSEventArraySerializer.h +++ b/LibCarla/source/carla/sensor/s11n/DVSEventArraySerializer.h @@ -55,7 +55,7 @@ namespace s11n { }; /// Reset the output buffer - output.reset(sizeof(DVSHeader) + (events.size() * sizeof(data::DVSEvent))); + output.reset(static_cast(sizeof(DVSHeader) + (events.size() * sizeof(data::DVSEvent)))); /// Pointer to data in buffer unsigned char *it = output.data(); diff --git a/LibCarla/source/test/common/test_buffer.cpp b/LibCarla/source/test/common/test_buffer.cpp index 1739fa75033..31aa7279d02 100644 --- a/LibCarla/source/test/common/test_buffer.cpp +++ b/LibCarla/source/test/common/test_buffer.cpp @@ -114,9 +114,9 @@ TEST(buffer, memcpy) { #ifndef LIBCARLA_NO_EXCEPTIONS TEST(buffer, message_too_big) { - ASSERT_THROW(Buffer(4294967296ul), std::invalid_argument); + ASSERT_THROW(Buffer(static_cast(4294967296ul)), std::invalid_argument); Buffer buf; - ASSERT_THROW(buf.reset(4294967296ul), std::invalid_argument); + ASSERT_THROW(buf.reset(static_cast(4294967296ul)), std::invalid_argument); } #endif // LIBCARLA_NO_EXCEPTIONS diff --git a/LibCarla/source/test/common/test_streaming.cpp b/LibCarla/source/test/common/test_streaming.cpp index ad4f35c3e35..e5183e43882 100644 --- a/LibCarla/source/test/common/test_streaming.cpp +++ b/LibCarla/source/test/common/test_streaming.cpp @@ -55,12 +55,12 @@ TEST(streaming, low_level_sending_strings) { io_context_running io; - Server srv(io.service, TESTING_PORT); + carla::streaming::low_level::Server srv(io.service, TESTING_PORT); srv.SetTimeout(1s); auto stream = srv.MakeStream(); - Client c; + carla::streaming::low_level::Client c; c.Subscribe(io.service, stream.token(), [&](auto message) { ++message_count; ASSERT_EQ(message.size(), message_text.size()); @@ -90,10 +90,10 @@ TEST(streaming, low_level_unsubscribing) { io_context_running io; - Server srv(io.service, TESTING_PORT); + carla::streaming::low_level::Server srv(io.service, TESTING_PORT); srv.SetTimeout(1s); - Client c; + carla::streaming::low_level::Client c; for (auto n = 0u; n < 10u; ++n) { auto stream = srv.MakeStream(); std::atomic_size_t message_count{0u}; diff --git a/Makefile b/Makefile index 5faab368690..2bd98dd7c4c 100644 --- a/Makefile +++ b/Makefile @@ -2,5 +2,5 @@ include Util/BuildTools/Vars.mk ifeq ($(OS),Windows_NT) include Util/BuildTools/Windows.mk else -include Util/BuildTools/Linux.mk +include Util/BuildTools/Unix.mk endif diff --git a/PythonAPI/carla/setup.py b/PythonAPI/carla/setup.py index dd5318e89b6..f60958e738a 100755 --- a/PythonAPI/carla/setup.py +++ b/PythonAPI/carla/setup.py @@ -34,8 +34,8 @@ def walk(folder, file_filter='*'): if os.name == "posix": import distro - linux_distro = distro.linux_distribution()[0] - if linux_distro.lower() in ["ubuntu", "debian", "deepin"]: + if distro.id().lower() in ["ubuntu", "debian", "deepin", "darwin"]: + is_mac = bool(distro.id().lower() == "darwin") pwd = os.path.dirname(os.path.realpath(__file__)) pylib = "libboost_python%d%d.a" % (sys.version_info.major, sys.version_info.minor) @@ -63,6 +63,9 @@ def walk(folder, file_filter='*'): '-Wconversion', '-Wfloat-overflow-conversion', '-DBOOST_ERROR_CODE_HEADER_ONLY', '-DLIBCARLA_WITH_PYTHON_SUPPORT' ] + if is_mac: + extra_compile_args += ['-stdlib=libc++'] # compile same as boost + # see: https://stackoverflow.com/questions/35006614/what-does-symbol-not-found-expected-in-flat-namespace-actually-mean if is_rss_variant_enabled(): extra_compile_args += ['-DLIBCARLA_RSS_ENABLED'] extra_compile_args += ['-DLIBCARLA_PYTHON_MAJOR_' + str(sys.version_info.major)] @@ -91,7 +94,10 @@ def walk(folder, file_filter='*'): extra_link_args += ['-ljpeg', '-ltiff'] extra_compile_args += ['-DLIBCARLA_IMAGE_WITH_PNG_SUPPORT=false'] else: - extra_link_args += ['-lpng', '-ljpeg', '-ltiff'] + if is_mac: + extra_link_args += ['-lpng'] # TODO: find a suitable MacOS replacement for libjpeg and libtiff + else: + extra_link_args += ['-lpng', '-ljpeg', '-ltiff'] extra_compile_args += ['-DLIBCARLA_IMAGE_WITH_PNG_SUPPORT=true'] # @todo Why would we need this? # include_dirs += ['/usr/lib/gcc/x86_64-linux-gnu/7/include'] diff --git a/Unreal/CarlaUE4/Config/DefaultEngine.ini b/Unreal/CarlaUE4/Config/DefaultEngine.ini index 19833af6d63..b1bd0750447 100644 --- a/Unreal/CarlaUE4/Config/DefaultEngine.ini +++ b/Unreal/CarlaUE4/Config/DefaultEngine.ini @@ -57,6 +57,27 @@ OcclusionPlugin= +TargetedRHIs=SF_VULKAN_SM5 +TargetedRHIs=GLSL_430 +[/Script/IOSRuntimeSettings.IOSRuntimeSettings] +bSupportsPortraitOrientation=False +bSupportsUpsideDownOrientation=False +bSupportsLandscapeLeftOrientation=True +PreferredLandscapeOrientation=LandscapeLeft + +[/Script/MacTargetPlatform.MacTargetSettings] +-TargetedRHIs=SF_METAL_SM5 ++TargetedRHIs=SF_METAL_SM5 +MaxShaderLanguageVersion=3 +UseFastIntrinsics=False +EnableMathOptimisations=True +AudioSampleRate=0 +AudioCallbackBufferFrameSize=0 +AudioNumBuffersToEnqueue=0 +AudioMaxChannels=0 +AudioNumSourceWorkers=0 +SpatializationPlugin= +ReverbPlugin= +OcclusionPlugin= + [/Script/Engine.PhysicsSettings] DefaultGravityZ=-980.000000 DefaultTerminalVelocity=4000.000000 @@ -110,3 +131,4 @@ DefaultGraphicsRHI=DefaultGraphicsRHI_DX12 +DefaultChannelResponses=(Channel=ECC_GameTraceChannel3,DefaultResponse=ECR_Overlap,bTraceType=True,bStaticObject=False,Name="OverlapChannel") +EditProfiles=(Name="BlockAll",CustomResponses=((Channel="SensorObject"),(Channel="SensorTrace"))) +EditProfiles=(Name="OverlapAll",CustomResponses=((Channel="SensorObject",Response=ECR_Overlap),(Channel="SensorTrace",Response=ECR_Overlap))) + diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h index e9ffa62130e..343e666e9d7 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h @@ -166,13 +166,13 @@ class FCarlaActor template T* GetActorData() { - return dynamic_cast(ActorData.Get()); + return static_cast(ActorData.Get()); } template const T* GetActorData() const { - return dynamic_cast(ActorData.Get()); + return static_cast(ActorData.Get()); } // Actor function interface ---------------------- diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs index d5e2afd93f5..c5653f40b54 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs @@ -114,6 +114,12 @@ public Carla(ReadOnlyTargetRules Target) : base(Target) AddCarlaServerDependency(Target); } + private bool IsMac(ReadOnlyTargetRules Target) + { + return (Target.Platform == UnrealTargetPlatform.Mac); + } + + private bool UseDebugLibs(ReadOnlyTargetRules Target) { if (IsWindows(Target)) @@ -231,6 +237,7 @@ private void AddCarlaServerDependency(ReadOnlyTargetRules Target) PublicDefinitions.Add("LIBCARLA_NO_EXCEPTIONS"); PublicDefinitions.Add("PUGIXML_NO_EXCEPTIONS"); PublicDefinitions.Add("BOOST_DISABLE_ABI_HEADERS"); + PublicDefinitions.Add("MSGPACK_DISABLE_LEGACY_NIL"); PublicDefinitions.Add("BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY"); } } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp index 16791d2f069..0644b59dff1 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp @@ -277,7 +277,7 @@ static carla::Buffer FWorldObserver_Serialize( auto total_size = sizeof(Serializer::Header) + sizeof(ActorDynamicState) * Registry.Num(); auto current_size = 0; // Set up buffer for writing. - buffer.reset(total_size); + buffer.reset(static_cast(total_size)); auto write_data = [¤t_size, &buffer](const auto &data) { auto begin = buffer.begin() + current_size; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp index 4998962a2ee..86469fee04a 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp @@ -593,7 +593,7 @@ float ACarlaWheeledVehicle::GetWheelSteerAngle(EVehicleWheelLocation WheelLocati } else { - return VehicleAnim->GetWheelRotAngle((uint8)WheelLocation); + return VehicleAnim->GetWheelRotAngle((uint8)WheelLocation); } } diff --git a/Util/BuildTools/BuildCarlaUE4.sh b/Util/BuildTools/BuildCarlaUE4.sh index 560dca9dec8..ba1fac3d546 100755 --- a/Util/BuildTools/BuildCarlaUE4.sh +++ b/Util/BuildTools/BuildCarlaUE4.sh @@ -93,7 +93,11 @@ if ${HARD_CLEAN} ; then log "Doing a \"hard\" clean of the Unreal Engine project." - make CarlaUE4Editor ARGS=-clean + if ${MAC_OS}; then + xcodebuild -scheme CarlaUe4 clean + else + make CarlaUE4Editor ARGS=-clean + fi fi @@ -113,6 +117,9 @@ if ${REMOVE_INTERMEDIATE} ; then popd >/dev/null + if ${MAC_OS}; then + rm -rf CarlaUE4.xcworkspace + fi fi # ============================================================================== @@ -141,13 +148,23 @@ if ${BUILD_CARLAUE4} ; then # This command fails sometimes but normally we can continue anyway. set +e log "Generate Unreal project files." - ${UE4_ROOT}/GenerateProjectFiles.sh -project="${PWD}/CarlaUE4.uproject" -game -engine -makefiles + BUILD_TYPE= + if ${MAC_OS}; then + BUILD_TYPE=" -xcode" + else + BUILD_TYPE=" -makefiles" + fi + ${UE4_ROOT}/GenerateProjectFiles.sh -project="${PWD}/CarlaUE4.uproject" -game -engine ${BUILD_TYPE} set -e fi log "Build CarlaUE4 project." - make CarlaUE4Editor + if ${MAC_OS}; then + xcodebuild -scheme CarlaUE4 -target CarlaUE4Editor -UseModernBuildSystem=YES + else + make CarlaUE4Editor + fi #Providing the user with the ExportedMaps folder EXPORTED_MAPS="${CARLAUE4_ROOT_FOLDER}/Content/Carla/ExportedMaps" @@ -163,8 +180,11 @@ fi if ${LAUNCH_UE4_EDITOR} ; then log "Launching UE4Editor..." - ${GDB} ${UE4_ROOT}/Engine/Binaries/Linux/UE4Editor "${PWD}/CarlaUE4.uproject" ${RHI} - + if ${MAC_OS}; then + /usr/bin/open -a "${UE4_ROOT}/Engine/Binaries/Mac/UE4Editor.app" "${PWD}/CarlaUE4.uproject" + else + ${GDB} ${UE4_ROOT}/Engine/Binaries/Linux/UE4Editor "${PWD}/CarlaUE4.uproject" ${RHI} + fi else log "Success!" diff --git a/Util/BuildTools/BuildOSM2ODR.sh b/Util/BuildTools/BuildOSM2ODR.sh index b1c2bf5966f..8eca7691c2b 100755 --- a/Util/BuildTools/BuildOSM2ODR.sh +++ b/Util/BuildTools/BuildOSM2ODR.sh @@ -89,8 +89,8 @@ if ${BUILD_OSM2ODR} ; then mkdir -p ${OSM2ODR_BUILD_FOLDER} cd ${OSM2ODR_BUILD_FOLDER} # define clang compiler - export CC=/usr/bin/clang-8 - export CXX=/usr/bin/clang++-8 + export CC=/usr/bin/clang + export CXX=/usr/bin/clang++ cmake ${OSM2ODR_SOURCE_FOLDER} \ -G "Eclipse CDT4 - Ninja" \ diff --git a/Util/BuildTools/BuildPythonAPI.sh b/Util/BuildTools/BuildPythonAPI.sh index 10c98582364..a4efc697721 100755 --- a/Util/BuildTools/BuildPythonAPI.sh +++ b/Util/BuildTools/BuildPythonAPI.sh @@ -50,8 +50,8 @@ done source $(dirname "$0")/Environment.sh -export CC=clang-8 -export CXX=clang++-8 +export CC=clang +export CXX=clang++ if ! { ${REMOVE_INTERMEDIATE} || ${BUILD_PYTHONAPI} ; }; then fatal_error "Nothing selected to be done." @@ -89,7 +89,11 @@ if ${BUILD_PYTHONAPI} ; then # Add patchelf to the path. Auditwheel relies on patchelf to repair ELF files. export PATH="${LIBCARLA_INSTALL_CLIENT_FOLDER}/bin:${PATH}" - CODENAME=$(cat /etc/os-release | grep VERSION_CODENAME) + if ${MAC_OS} ; then + CODENAME="osx" + else + CODENAME=$(cat /etc/os-release | grep VERSION_CODENAME) + fi if [[ ! -z ${TARGET_WHEEL_PLATFORM} ]] && [[ ${CODENAME#*=} != "bionic" ]] ; then log "A target platform has been specified but you are not using a compatible linux distribution. The wheel repair step will be skipped" TARGET_WHEEL_PLATFORM= diff --git a/Util/BuildTools/Environment.sh b/Util/BuildTools/Environment.sh index 7bab03f1a8e..9d4b851613c 100644 --- a/Util/BuildTools/Environment.sh +++ b/Util/BuildTools/Environment.sh @@ -8,6 +8,31 @@ CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" source $(dirname "$0")/Vars.mk unset CURDIR + +if [[ "$(uname)" == "Darwin" ]] ; then + export MAC_OS=true # automatically set to false on non-Mac builds +else + export MAC_OS=false +fi + +if ${MAC_OS}; then + ARCH="x86_64" # for building the UE4 package + # ARCH="arm64" # for building the PythonAPI + # for OSX apple silicon build (building x86 & using rosetta2) + # NOTE: UE4 wants use of macos 10.14, but 12.1 works fine + export ARCH_TARGET="-target ${ARCH}-apple-macos12.1" + export OS_FLAGS=" -nostdinc++" # for macos + export OS_STDLIB="-stdlib=libc++" + # for cmake -arch flag: https://cmake.org/cmake/help/latest/prop_tgt/OSX_ARCHITECTURES.html#prop_tgt:OSX_ARCHITECTURES + export CMAKE_OSX_ARCHITECTURES=${ARCH} + export TARGET_PLATFORM="Mac" +else + export ARCH_TARGET="" # use default arch on linux + export OS_FLAGS="" + export OS_STDLIB="" + export TARGET_PLATFORM="Linux" +fi + if [ -n "${CARLA_BUILD_NO_COLOR}" ]; then function log { @@ -46,4 +71,5 @@ function move_if_changed { rm -f $1 } -CARLA_BUILD_CONCURRENCY=`nproc --all` +# CARLA_BUILD_CONCURRENCY=`nproc --all` +CARLA_BUILD_CONCURRENCY=12 diff --git a/Util/BuildTools/Package.sh b/Util/BuildTools/Package.sh index d3e07d6e4fc..0a8df4c0175 100755 --- a/Util/BuildTools/Package.sh +++ b/Util/BuildTools/Package.sh @@ -112,12 +112,12 @@ if ${DO_CARLA_RELEASE} ; then -project="${PWD}/CarlaUE4.uproject" \ -nocompileeditor -nop4 -cook -stage -archive -package -iterate \ -clientconfig=${PACKAGE_CONFIG} -ue4exe=UE4Editor \ - -prereqs -targetplatform=Linux -build -utf8output \ + -prereqs -targetplatform=${TARGET_PLATFORM} -build -utf8output \ -archivedirectory="${RELEASE_BUILD_FOLDER}" popd >/dev/null - if [[ ! -d ${RELEASE_BUILD_FOLDER}/LinuxNoEditor ]] ; then + if [[ ! -d ${RELEASE_BUILD_FOLDER}/${TARGET_PLATFORM}NoEditor ]] ; then fatal_error "Failed to cook the project!" fi @@ -129,7 +129,7 @@ fi if ${DO_CARLA_RELEASE} ; then - DESTINATION=${RELEASE_BUILD_FOLDER}/LinuxNoEditor + DESTINATION=${RELEASE_BUILD_FOLDER}/${TARGET_PLATFORM}NoEditor log "Adding extra files to CARLA package." @@ -145,7 +145,12 @@ if ${DO_CARLA_RELEASE} ; then copy_if_changed "./Docs/python_api.md" "${DESTINATION}/PythonAPI/python_api.md" copy_if_changed "./Util/Docker/Release.Dockerfile" "${DESTINATION}/Dockerfile" copy_if_changed "./Util/ImportAssets.sh" "${DESTINATION}/ImportAssets.sh" - copy_if_changed "./Util/DockerUtils/dist/RecastBuilder" "${DESTINATION}/Tools/" + if ${MAC_OS}; then + RECAST_BIN="./Util/DockerUtils/dist/RecastBuilder.app/" + else + RECAST_BIN="./Util/DockerUtils/dist/RecastBuilder" + fi + copy_if_changed ${RECAST_BIN} "${DESTINATION}/Tools/" copy_if_changed "./PythonAPI/carla/dist/*.egg" "${DESTINATION}/PythonAPI/carla/dist/" copy_if_changed "./PythonAPI/carla/dist/*.whl" "${DESTINATION}/PythonAPI/carla/dist/" @@ -181,14 +186,14 @@ fi if ${DO_CARLA_RELEASE} && ${DO_TARBALL} ; then DESTINATION=${RELEASE_PACKAGE_PATH} - SOURCE=${RELEASE_BUILD_FOLDER}/LinuxNoEditor + SOURCE=${RELEASE_BUILD_FOLDER}/${TARGET_PLATFORM}NoEditor pushd "${SOURCE}" >/dev/null log "Packaging CARLA release." - rm -f ./Manifest_NonUFSFiles_Linux.txt - rm -f ./Manifest_UFSFiles_Linux.txt + rm -f ./Manifest_NonUFSFiles_${TARGET_PLATFORM}.txt + rm -f ./Manifest_UFSFiles_${TARGET_PLATFORM}.txt rm -Rf ./CarlaUE4/Saved rm -Rf ./Engine/Saved @@ -215,7 +220,7 @@ fi # ============================================================================== PACKAGE_PATH_FILE=${CARLAUE4_ROOT_FOLDER}/Content/PackagePath.txt -MAP_LIST_FILE=${CARLAUE4_ROOT_FOLDER}/Content/MapPathsLinux.txt +MAP_LIST_FILE=${CARLAUE4_ROOT_FOLDER}/Content/MapPaths${TARGET_PLATFORM}.txt for PACKAGE_NAME in "${PACKAGES[@]}" ; do if [[ ${PACKAGE_NAME} != "Carla" ]] ; then @@ -238,15 +243,15 @@ for PACKAGE_NAME in "${PACKAGES[@]}" ; do if [[ ${PACKAGE_NAME} != "Carla" ]] ; pushd "${CARLAUE4_ROOT_FOLDER}" > /dev/null # Prepare cooking of package - ${UE4_ROOT}/Engine/Binaries/Linux/UE4Editor "${CARLAUE4_ROOT_FOLDER}/CarlaUE4.uproject" \ + ${UE4_ROOT}/Engine/Binaries/${TARGET_PLATFORM}/UE4Editor "${CARLAUE4_ROOT_FOLDER}/CarlaUE4.uproject" \ -run=PrepareAssetsForCooking -PackageName=${PACKAGE_NAME} -OnlyPrepareMaps=false PACKAGE_FILE=$(<${PACKAGE_PATH_FILE}) MAPS_TO_COOK=$(<${MAP_LIST_FILE}) # Cook maps - ${UE4_ROOT}/Engine/Binaries/Linux/UE4Editor "${CARLAUE4_ROOT_FOLDER}/CarlaUE4.uproject" \ - -run=cook -map="${MAPS_TO_COOK}" -cooksinglepackage -targetplatform="LinuxNoEditor" \ + ${UE4_ROOT}/Engine/Binaries/${TARGET_PLATFORM}/UE4Editor "${CARLAUE4_ROOT_FOLDER}/CarlaUE4.uproject" \ + -run=cook -map="${MAPS_TO_COOK}" -cooksinglepackage -targetplatform="${TARGET_PLATFORM}NoEditor" \ -OutputDir="${BUILD_FOLDER}" PROP_MAP_FOLDER="${PACKAGE_PATH}/Maps/${PROPS_MAP_NAME}" diff --git a/Util/BuildTools/Setup.sh b/Util/BuildTools/Setup.sh index 22430cbee7e..d44c1792290 100755 --- a/Util/BuildTools/Setup.sh +++ b/Util/BuildTools/Setup.sh @@ -37,14 +37,14 @@ done # -- Set up environment -------------------------------------------------------- # ============================================================================== -command -v /usr/bin/clang++-8 >/dev/null 2>&1 || { - echo >&2 "clang 8 is required, but it's not installed."; +command -v /usr/bin/clang++ >/dev/null 2>&1 || { + echo >&2 "clang is required, but it's not installed."; exit 1; } CXX_TAG=c8 -export CC=/usr/bin/clang-8 -export CXX=/usr/bin/clang++-8 +export CC=/usr/bin/clang +export CXX=/usr/bin/clang++ source $(dirname "$0")/Environment.sh @@ -101,6 +101,13 @@ fi unset LLVM_BASENAME +if ${MAC_OS}; then + # overwrite the LLVM paths to use the MacOSX libraries + # LLVM_INCLUDE=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 + # LLVM_LIBPATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib + LLVM_INCLUDE=$(xcrun --show-sdk-path)/usr/include/c++/v1 + LLVM_LIBPATH=$(xcrun --show-sdk-path)/usr/lib +fi # ============================================================================== # -- Get boost includes -------------------------------------------------------- # ============================================================================== @@ -148,8 +155,8 @@ for PY_VERSION in ${PY_VERSION_LIST[@]} ; do pushd ${BOOST_BASENAME}-source >/dev/null - BOOST_TOOLSET="clang-8.0" - BOOST_CFLAGS="-fPIC -std=c++14 -DBOOST_ERROR_CODE_HEADER_ONLY" + BOOST_TOOLSET="clang" + BOOST_CFLAGS="-fPIC -std=c++14 ${ARCH_TARGET} ${OS_LIBCPP} -DBOOST_ERROR_CODE_HEADER_ONLY" py3="/usr/bin/env python${PY_VERSION}" py3_root=`${py3} -c "import sys; print(sys.prefix)"` @@ -217,16 +224,17 @@ else log "Building rpclib with libc++." - # rpclib does not use any cmake 3.9 feature. - # As cmake 3.9 is not standard in Ubuntu 16.04, change cmake version to 3.5 - sed -i s/"3.9.0"/"3.5.0"/g ${RPCLIB_BASENAME}-source/CMakeLists.txt - + if ! ${MAC_OS}; then + # rpclib does not use any cmake 3.9 feature. + # As cmake 3.9 is not standard in Ubuntu 16.04, change cmake version to 3.5 + sed -i s/"3.9.0"/"3.5.0"/g ${RPCLIB_BASENAME}-source/CMakeLists.txt + fi mkdir -p ${RPCLIB_BASENAME}-libcxx-build pushd ${RPCLIB_BASENAME}-libcxx-build >/dev/null cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-fPIC -std=c++14 -stdlib=libc++ -I${LLVM_INCLUDE} -Wl,-L${LLVM_LIBPATH} -DBOOST_NO_EXCEPTIONS -DASIO_NO_EXCEPTIONS" \ + -DCMAKE_CXX_FLAGS="-fPIC -std=c++14 ${ARCH_TARGET} ${OS_FLAGS} -stdlib=libc++ -I${LLVM_INCLUDE} -Wl,-L${LLVM_LIBPATH} -DBOOST_NO_EXCEPTIONS -DASIO_NO_EXCEPTIONS -DMSGPACK_DISABLE_LEGACY_NIL" \ -DCMAKE_INSTALL_PREFIX="../${RPCLIB_BASENAME}-libcxx-install" \ ../${RPCLIB_BASENAME}-source @@ -243,7 +251,7 @@ else pushd ${RPCLIB_BASENAME}-libstdcxx-build >/dev/null cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-fPIC -std=c++14" \ + -DCMAKE_CXX_FLAGS="-fPIC -std=c++14 ${ARCH_TARGET}" \ -DCMAKE_INSTALL_PREFIX="../${RPCLIB_BASENAME}-libstdcxx-install" \ ../${RPCLIB_BASENAME}-source @@ -290,7 +298,7 @@ else pushd ${GTEST_BASENAME}-libcxx-build >/dev/null cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-std=c++14 -stdlib=libc++ -I${LLVM_INCLUDE} -Wl,-L${LLVM_LIBPATH} -DBOOST_NO_EXCEPTIONS -fno-exceptions" \ + -DCMAKE_CXX_FLAGS="-std=c++14 ${OS_FLAGS} ${ARCH_TARGET} -stdlib=libc++ -I${LLVM_INCLUDE} -Wl,-L${LLVM_LIBPATH} -DBOOST_NO_EXCEPTIONS -fno-exceptions" \ -DCMAKE_INSTALL_PREFIX="../${GTEST_BASENAME}-libcxx-install" \ ../${GTEST_BASENAME}-source @@ -307,7 +315,7 @@ else pushd ${GTEST_BASENAME}-libstdcxx-build >/dev/null cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-std=c++14" \ + -DCMAKE_CXX_FLAGS="-std=c++14 ${ARCH_TARGET}" \ -DCMAKE_INSTALL_PREFIX="../${GTEST_BASENAME}-libstdcxx-install" \ ../${GTEST_BASENAME}-source @@ -335,7 +343,8 @@ RECAST_INCLUDE=${PWD}/${RECAST_BASENAME}-install/include RECAST_LIBPATH=${PWD}/${RECAST_BASENAME}-install/lib if [[ -d "${RECAST_BASENAME}-install" && - -f "${RECAST_BASENAME}-install/bin/RecastBuilder" ]] ; then + (-f "${RECAST_BASENAME}-install/bin/RecastBuilder" || + $MAC_OS && -d "${RECAST_BASENAME}-install/bin/RecastBuilder.app") ]] ; then log "${RECAST_BASENAME} already installed." else rm -Rf \ @@ -360,7 +369,7 @@ else pushd ${RECAST_BASENAME}-build >/dev/null cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-std=c++14 -fPIC" \ + -DCMAKE_CXX_FLAGS="-std=c++14 -fPIC ${ARCH_TARGET}" \ -DCMAKE_INSTALL_PREFIX="../${RECAST_BASENAME}-install" \ -DRECASTNAVIGATION_DEMO=False \ -DRECASTNAVIGATION_TEST=False \ @@ -383,7 +392,11 @@ fi # make sure the RecastBuilder is corrctly copied RECAST_INSTALL_DIR="${CARLA_BUILD_FOLDER}/../Util/DockerUtils/dist" if [[ ! -f "${RECAST_INSTALL_DIR}/RecastBuilder" ]]; then - cp "${RECAST_BASENAME}-install/bin/RecastBuilder" "${RECAST_INSTALL_DIR}/" + if ${MAC_OS}; then + cp -r "${RECAST_BASENAME}-install/bin/RecastBuilder.app" "${RECAST_INSTALL_DIR}/" + else + cp "${RECAST_BASENAME}-install/bin/RecastBuilder" "${RECAST_INSTALL_DIR}/" + fi fi unset RECAST_BASENAME @@ -449,12 +462,13 @@ else pushd ${XERCESC_SRC_DIR}/build >/dev/null + if ${MAC_OS}; then ICONV=iconv; else ICONV=gnuiconv; fi cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-std=c++14 -fPIC -w" \ + -DCMAKE_CXX_FLAGS="-std=c++14 -fPIC -w ${ARCH_TARGET}" \ -DCMAKE_INSTALL_PREFIX="../../${XERCESC_INSTALL_DIR}" \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=OFF \ - -Dtranscoder=gnuiconv \ + -Dtranscoder=${ICONV} \ -Dnetwork=OFF \ .. ninja @@ -526,7 +540,7 @@ if ${USE_CHRONO} ; then pushd ${CHRONO_SRC_DIR}/build >/dev/null cmake -G "Ninja" \ - -DCMAKE_CXX_FLAGS="-fPIC -std=c++14 -stdlib=libc++ -I${LLVM_INCLUDE} -L${LLVM_LIBPATH} -Wno-unused-command-line-argument" \ + -DCMAKE_CXX_FLAGS="-fPIC -std=c++14 ${ARCH_TARGET} -stdlib=libc++ -I${LLVM_INCLUDE} -L${LLVM_LIBPATH} -Wno-unused-command-line-argument" \ -DEIGEN3_INCLUDE_DIR="../../${EIGEN_INCLUDE}" \ -DCMAKE_INSTALL_PREFIX="../../${CHRONO_INSTALL_DIR}" \ -DCMAKE_BUILD_TYPE=Release \ @@ -576,7 +590,7 @@ else pushd ${SQLITE_SOURCE_DIR} >/dev/null - export CFLAGS="-fPIC" + export CFLAGS="-fPIC ${ARCH_TARGET}" ./configure --prefix=${PWD}/../sqlite-install/ make make install @@ -619,7 +633,7 @@ else pushd ${PROJ_SRC_DIR}/build >/dev/null cmake -G "Ninja" .. \ - -DCMAKE_CXX_FLAGS="-std=c++14 -fPIC" \ + -DCMAKE_CXX_FLAGS="-std=c++14 -fPIC ${ARCH_TARGET}" \ -DSQLITE3_INCLUDE_DIR=${SQLITE_INCLUDE_DIR} -DSQLITE3_LIBRARY=${SQLITE_LIB} \ -DEXE_SQLITE3=${SQLITE_EXE} \ -DENABLE_TIFF=OFF -DENABLE_CURL=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_PROJSYNC=OFF \ @@ -709,9 +723,10 @@ cat >${LIBSTDCPP_TOOLCHAIN_FILE}.gen <>${LIBCPP_TOOLCHAIN_FILE}.gen <${CMAKE_CONFIG_FILE}.gen <