From e025e62445913bf1ec9cf075eaaf1dc7374da83c Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Thu, 12 Apr 2018 19:31:53 +0200 Subject: [PATCH] cmake: Fix PLATFORM_WEB build Did this ever work? Surely, doesn't look like it... --- .travis.yml | 36 +++++---- cmake/emscripten.cmake | 15 ++++ cmake/utils.cmake | 12 ++- src/CMakeLists.txt | 165 +++++++++++++++++++---------------------- src/CMakeOptions.txt | 29 ++++++-- src/audio.c | 1 + src/config.h.in | 2 + src/textures.c | 1 + src/utils.c | 10 +-- 9 files changed, 150 insertions(+), 121 deletions(-) create mode 100644 cmake/emscripten.cmake diff --git a/.travis.yml b/.travis.yml index 82f73e8d..2fd73c18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,8 @@ git: depth: 3 # TODO we could use a 32 bit Docker container for running true 32-bit tests -# services: - docker +services: + - docker matrix: include: @@ -16,10 +17,10 @@ matrix: env: ARCH=amd64 sudo: required - os: linux - env: ARCH=amd64 GLFW=SYSTEM + env: ARCH=amd64 GLFW=SYSTEM RELEASE=NO sudo: required - os: linux - env: USE_WAYLAND=ON ARCH=amd64 + env: USE_WAYLAND=ON ARCH=amd64 RELEASE=NO sudo: required addons: apt: @@ -30,13 +31,15 @@ matrix: - os: osx env: ARCH=universal - os: linux - env: ARCH=arm64-android + env: ARCH=arm64-android RELEASE=NO + sudo: required + - os: linux + env: ARCH=html5 RELEASE=NO sudo: required before_script: before_install: - - export PLATFORM=Desktop - if [ "$TRAVIS_OS_NAME" == "linux" ]; then if [[ "$ARCH" == *-android ]]; then export RAYLIB_PACKAGE_SUFFIX="-Android-arm64"; @@ -44,9 +47,14 @@ before_install: unzip -qq android-ndk*.zip; android-ndk*/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 --install-dir /tmp/android-toolchain; export PATH=/tmp/android-toolchain/bin:$PATH; - export PLATFORM=Android; + export CMAKE_ARCH_ARGS='-DPLATFORM=Android'; export CC=aarch64-linux-android-clang; export CXX=aarch64-linux-android-clang++; + elif [ "$ARCH" == "html5" ]; then + export RAYLIB_PACKAGE_SUFFIX="-html5"; + docker run --privileged=true -dit --name emscripten -v $(pwd):/src trzeci/emscripten:sdk-incoming-64bit bash; + export CMAKE_ARCH_ARGS='-DPLATFORM=Web -DCMAKE_TOOLCHAIN_FILE=../cmake/emscripten.cmake'; + export RUNNER='docker exec -it emscripten cmake -E chdir build'; else sudo apt-get install -y gcc-multilib libasound2-dev:$ARCH @@ -68,10 +76,10 @@ before_install: export RAYLIB_PACKAGE_SUFFIX="-macOS"; if [ "$GLFW" == "SYSTEM" ]; then brew update; brew install glfw; fi; fi - - "$CC --version" + - mkdir build + - $RUNNER $CC --version script: - - mkdir build - cd build - if test -n "${USE_WAYLAND}"; then wget https://mirrors.kernel.org/ubuntu/pool/universe/e/extra-cmake-modules/extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb; @@ -81,12 +89,12 @@ script: git checkout 1.12 && ./autogen.sh --prefix=/usr && make && sudo make install; popd; fi - - cmake $CMAKE_ARCH_ARGS -DMACOS_FATLIB=ON -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=ON -DBUILD_GAMES=ON -DUSE_EXTERNAL_GLFW=IF_POSSIBLE -DUSE_WAYLAND=${USE_WAYLAND} -DPLATFORM=${PLATFORM} .. - - make VERBOSE=1 - - if [ "$GLFW" != "SYSTEM" ]; then make package; fi; - - sudo make install - - pkg-config --static --libs raylib - - if [[ "$ARCH" != *-android ]]; then + - $RUNNER cmake $CMAKE_ARCH_ARGS -DMACOS_FATLIB=ON -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=ON -DBUILD_GAMES=ON -DUSE_EXTERNAL_GLFW=IF_POSSIBLE -DUSE_WAYLAND=${USE_WAYLAND} .. + - $RUNNER make VERBOSE=1 + - if [ "$RELEASE" != "NO" ]; then $RUNNER make package; fi; + - sudo $RUNNER make install + - if [[ "$ARCH" != *-android && "$ARCH" != html5 ]]; then + pkg-config --static --libs raylib; nm -g release/libraylib.a | grep glfwGetProcAddress || (echo "libraylib.a doesn't contain GLFW symbols! Aborting..." && false); fi diff --git a/cmake/emscripten.cmake b/cmake/emscripten.cmake new file mode 100644 index 00000000..621ae787 --- /dev/null +++ b/cmake/emscripten.cmake @@ -0,0 +1,15 @@ +SET(CMAKE_SYSTEM_NAME Linux) + +SET(CMAKE_C_COMPILER emcc) +SET(CMAKE_CXX_COMPILER em++) +if(NOT DEFINED CMAKE_AR) + find_program(CMAKE_AR NAMES emar) +endif() +if(NOT DEFINED CMAKE_RANLIB) + find_program(CMAKE_RANLIB NAMES emranlib) +endif() + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index a3e60fb5..fc75ef4f 100755 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -5,7 +5,11 @@ add_definitions("-DRAYLIB_CMAKE=1") # Linking for OS X -framework options # Will do nothing on other OSes -if(APPLE) +if(${PLATFORM} MATCHES "Android") + find_library(OPENGL_LIBRARY OpenGL) + set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c) +elseif(${PLATFORM} MATCHES "Web") +elseif(APPLE) find_library(OPENGL_LIBRARY OpenGL) find_library(COCOA_LIBRARY Cocoa) find_library(IOKIT_LIBRARY IOKit) @@ -16,9 +20,6 @@ if(APPLE) ${IOKIT_LIBRARY} ${COREFOUNDATION_LIBRARY} ${COREVIDEO_LIBRARY}) elseif(WIN32) # no pkg-config --static on Windows yet... -elseif(${PLATFORM} MATCHES "Android") - find_library(OPENGL_LIBRARY OpenGL) - set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c) else() find_library(pthread NAMES pthread) find_package(OpenGL QUIET) @@ -87,6 +88,9 @@ function(link_libraries_to_executable executable) # Link raylib if (TARGET raylib_shared) target_link_libraries(${executable} raylib_shared) + elseif(${PLATFORM} MATCHES "Web") + target_link_libraries(${executable} ${__PKG_CONFIG_LIBS_PRIVATE}) + target_link_libraries(${executable} raylib) else() target_link_libraries(${executable} raylib ${__PKG_CONFIG_LIBS_PRIVATE}) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 41b417a0..7e94d97d 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ # Setup the project and settings -project(raylib) +project(raylib C) include(GNUInstallDirs) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") @@ -13,14 +13,6 @@ configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h) include_directories(${CMAKE_BINARY_DIR}) include_directories(SYSTEM .) -if(MACOS_FATLIB) - if (CMAKE_OSX_ARCHITECTURES) - message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON") - else() - SET(CMAKE_OSX_ARCHITECTURES "x86_64;i386") - endif() -endif() - # Get the sources together file(GLOB raylib_sources *.c) list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/rglfw.c) @@ -72,9 +64,9 @@ if(${PLATFORM} MATCHES "Desktop") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") endif() - # Need to force OpenGL 3.3 on OS X - # See: https://github.com/raysan5/raylib/issues/341 if(APPLE) + # Need to force OpenGL 3.3 on OS X + # See: https://github.com/raysan5/raylib/issues/341 set(GRAPHICS "GRAPHICS_API_OPENGL_33") link_libraries("${LIBS_PRIVATE}") elseif(WIN32) @@ -85,12 +77,9 @@ elseif(${PLATFORM} MATCHES "Web") set(PLATFORM "PLATFORM_WEB") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") - # Need to use `emcc` - set(CMAKE_C_COMPILER "emcc") - set(CMAKE_CXX_COMPILER "em++") + set(CMAKE_C_FLAGS "-s USE_GLFW=3 -s ASSERTIONS=1 --profiling") # Change the name of the output library - set(RAYLIB "libraylib.bc") elseif(${PLATFORM} MATCHES "Android") set(PLATFORM "PLATFORM_ANDROID") @@ -110,89 +99,87 @@ elseif(${PLATFORM} MATCHES "Raspberry Pi") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") endif() -# Which platform? -if(${PLATFORM} MATCHES "PLATFORM_WEB") - # For the web. - add_executable(${RAYLIB} ${sources}) +if(${SHARED}) + add_library(${RAYLIB}_shared SHARED ${sources}) -else() - if(${SHARED}) - add_library(${RAYLIB}_shared SHARED ${sources}) + target_compile_definitions(${RAYLIB}_shared + PUBLIC ${PLATFORM} + PUBLIC ${GRAPHICS} + ) - target_compile_definitions(${RAYLIB}_shared - PUBLIC ${PLATFORM} - PUBLIC ${GRAPHICS} - ) + set_property(TARGET ${RAYLIB}_shared PROPERTY POSITION_INDEPENDENT_CODE ON) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + set(CMAKE_MACOSX_RPATH ON) - set_property(TARGET ${RAYLIB}_shared PROPERTY POSITION_INDEPENDENT_CODE ON) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") - set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - set(CMAKE_MACOSX_RPATH ON) - - target_link_libraries(${RAYLIB}_shared ${LIBS_PRIVATE}) - if (${PLATFORM} MATCHES "Desktop") - target_link_libraries(${RAYLIB}_shared glfw ${GLFW_LIBRARIES}) - endif() - if (UNIX AND ${FILESYSTEM_LACKS_SYMLINKS}) - MESSAGE(WARNING "Can't version UNIX shared library on file system without symlink support") - else() - set_target_properties(${RAYLIB}_shared PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${API_VERSION} - ) - endif() - set_target_properties(${RAYLIB}_shared PROPERTIES - PUBLIC_HEADER "raylib.h" - ) - if(WIN32) - install( - TARGETS ${RAYLIB}_shared - RUNTIME DESTINATION lib - PUBLIC_HEADER DESTINATION include - ) - else() # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows - set_target_properties(${RAYLIB}_shared PROPERTIES OUTPUT_NAME ${RAYLIB}) - install( - TARGETS ${RAYLIB}_shared - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + target_link_libraries(${RAYLIB}_shared ${LIBS_PRIVATE}) + if (${PLATFORM} MATCHES "Desktop") + target_link_libraries(${RAYLIB}_shared glfw ${GLFW_LIBRARIES}) + endif() + if (UNIX AND ${FILESYSTEM_LACKS_SYMLINKS}) + MESSAGE(WARNING "Can't version UNIX shared library on file system without symlink support") + else() + set_target_properties(${RAYLIB}_shared PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${API_VERSION} ) - endif() - endif(${SHARED}) - - if(${STATIC}) - add_library(${RAYLIB} STATIC ${sources}) - - target_compile_definitions(${RAYLIB} - PUBLIC ${PLATFORM} - PUBLIC ${GRAPHICS} + endif() + set_target_properties(${RAYLIB}_shared PROPERTIES + PUBLIC_HEADER "raylib.h" + ) + if(WIN32) + install( + TARGETS ${RAYLIB}_shared + RUNTIME DESTINATION lib + PUBLIC_HEADER DESTINATION include ) - - set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE}) - if (${PLATFORM} MATCHES "Desktop") - target_link_libraries(${RAYLIB} glfw ${GLFW_LIBRARIES}) - endif() - - if (WITH_PIC) - set_property(TARGET ${RAYLIB} PROPERTY POSITION_INDEPENDENT_CODE ON) - endif() - set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h") - install(TARGETS ${RAYLIB} - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + else() # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows + set_target_properties(${RAYLIB}_shared PROPERTIES OUTPUT_NAME ${RAYLIB}) + install( + TARGETS ${RAYLIB}_shared + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) - endif(${STATIC}) + endif() +endif(${SHARED}) - configure_file(../raylib.pc.in raylib.pc @ONLY) - install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +if(${STATIC}) + if(${PLATFORM} MATCHES "PLATFORM_WEB") + set(CMAKE_STATIC_LIBRARY_SUFFIX ".bc") + endif() + + add_library(${RAYLIB} STATIC ${sources}) + + set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE}) + if (${PLATFORM} MATCHES "Desktop") + target_link_libraries(${RAYLIB} glfw ${GLFW_LIBRARIES}) + endif() + + if (WITH_PIC) + set_property(TARGET ${RAYLIB} PROPERTY POSITION_INDEPENDENT_CODE ON) + endif() + set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h") + install(TARGETS ${RAYLIB} + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) +endif(${STATIC}) + +configure_file(../raylib.pc.in raylib.pc @ONLY) +install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + +# Copy the header files to the build directory +file(COPY "raylib.h" DESTINATION ".") +file(COPY "rlgl.h" DESTINATION ".") +file(COPY "physac.h" DESTINATION ".") +file(COPY "raymath.h" DESTINATION ".") +file(COPY "audio.h" DESTINATION ".") + +target_compile_definitions(${RAYLIB} + PUBLIC ${PLATFORM} + PUBLIC ${GRAPHICS} +) - # Copy the header files to the build directory - file(COPY "raylib.h" DESTINATION ".") - file(COPY "rlgl.h" DESTINATION ".") - file(COPY "physac.h" DESTINATION ".") - file(COPY "raymath.h" DESTINATION ".") - file(COPY "audio.h" DESTINATION ".") -endif() # Print the flags for the user message(STATUS "Compiling with the flags:") diff --git a/src/CMakeOptions.txt b/src/CMakeOptions.txt index 00fc7904..4ed1a375 100644 --- a/src/CMakeOptions.txt +++ b/src/CMakeOptions.txt @@ -1,13 +1,24 @@ ### Config options ### include(CMakeDependentOption) +set(PLATFORM "Desktop" CACHE STRING "Platform to build for.") +set_property(CACHE PLATFORM PROPERTY STRINGS "Desktop" "Web" "Android" "Raspberry Pi") + +set(OPENGL_VERSION "3.3" CACHE STRING "OpenGL Version to build raylib with") +set_property(CACHE OPENGL_VERSION PROPERTY STRINGS "3.3" "2.1" "1.1" "ES 2.0") + # Shared library is always PIC. Static library should be PIC too if linked into a shared library option(WITH_PIC "Compile static library as position-independent code" OFF) option(SHARED "Build raylib as a dynamic library" OFF) option(STATIC "Build raylib as a static library" ON) option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" ON) option(USE_AUDIO "Build raylib with audio module" ON) -cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" OFF "USE_AUDIO" OFF) +if(${PLATFORM} MATCHES "Web") + cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" ON "USE_AUDIO" OFF) +else() + cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" OFF "USE_AUDIO" OFF) +endif() + set(USE_EXTERNAL_GLFW OFF CACHE STRING "Link raylib against system GLFW instead of embedded one") set_property(CACHE USE_EXTERNAL_GLFW PROPERTY STRINGS ON OFF IF_POSSIBLE) if(UNIX AND NOT APPLE) @@ -15,12 +26,6 @@ if(UNIX AND NOT APPLE) endif() -set(PLATFORM "Desktop" CACHE STRING "Platform to build for.") -set_property(CACHE PLATFORM PROPERTY STRINGS "Desktop" "Web" "Android" "Raspberry Pi") - -set(OPENGL_VERSION "3.3" CACHE STRING "OpenGL Version to build raylib with") -set_property(CACHE OPENGL_VERSION PROPERTY STRINGS "3.3" "2.1" "1.1" "ES 2.0") - # core.c option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" ON) option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON) @@ -88,4 +93,14 @@ if(DEFINED STATIC_RAYLIB) message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.") endif() +if(${PLATFORM} MATCHES "Desktop" AND APPLE) + if(MACOS_FATLIB) + if (CMAKE_OSX_ARCHITECTURES) + message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON") + else() + set(CMAKE_OSX_ARCHITECTURES "x86_64;i386") + endif() + endif() +endif() + # vim: ft=cmake diff --git a/src/audio.c b/src/audio.c index 4e18df26..53f5814f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -73,6 +73,7 @@ * **********************************************************************************************/ +#include "config.h" #if !defined(USE_OPENAL_BACKEND) #define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL. #endif diff --git a/src/config.h.in b/src/config.h.in index 651024c1..d767560b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -1,5 +1,7 @@ /* config.h.in */ +#cmakedefine USE_OPENAL_BACKEND 1 + // core.c /* Camera module is included (camera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital */ #cmakedefine SUPPORT_CAMERA_SYSTEM 1 diff --git a/src/textures.c b/src/textures.c index 46867aab..3a1934b9 100644 --- a/src/textures.c +++ b/src/textures.c @@ -568,6 +568,7 @@ void ExportImage(const char *fileName, Image image) // NOTE: Getting Color array as RGBA unsigned char values unsigned char *imgData = (unsigned char *)GetImageData(image); SavePNG(fileName, imgData, image.width, image.height, 4); + // FIXME ^ this fails on PLATFORM_WEB, what should we do? free(imgData); } diff --git a/src/utils.c b/src/utils.c index cd75e695..74780680 100644 --- a/src/utils.c +++ b/src/utils.c @@ -143,31 +143,27 @@ void TraceLog(int msgType, const char *text, ...) va_end(args); if (msgType == LOG_ERROR) exit(1); // If LOG_ERROR message, exit program - + #endif // SUPPORT_TRACELOG } -#if defined(SUPPORT_SAVE_BMP) // Creates a BMP image file from an array of pixel data void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize) { -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) +#if defined(SUPPORT_SAVE_BMP) && (defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)) stbi_write_bmp(fileName, width, height, compSize, imgData); TraceLog(LOG_INFO, "BMP Image saved: %s", fileName); #endif } -#endif -#if defined(SUPPORT_SAVE_PNG) // Creates a PNG image file from an array of pixel data void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize) { -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) +#if defined(SUPPORT_SAVE_PNG) && (defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)) stbi_write_png(fileName, width, height, compSize, imgData, width*compSize); TraceLog(LOG_INFO, "PNG Image saved: %s", fileName); #endif } -#endif // Keep track of memory allocated // NOTE: mallocType defines the type of data allocated