From ab2738ca1b2a107068938178511e1c1928c7ddca Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Wed, 25 Oct 2017 16:57:25 +0200 Subject: [PATCH] Allow cross-compilation from Linux to macOS --- CMakeLists.txt | 22 +++++++--- README.md | 12 +++++- cmake/Download_GTest_CMakeLists.txt.in | 1 + cmake/FindCurl.cmake | 8 +++- cmake/FindFreetype.cmake | 10 +++-- cmake/FindGLEW.cmake | 8 +++- cmake/FindMySQL.cmake | 60 ++++++++++++++------------ cmake/FindOgg.cmake | 8 +++- cmake/FindOpus.cmake | 8 +++- cmake/FindOpusfile.cmake | 8 +++- cmake/FindSDL2.cmake | 8 +++- cmake/toolchains/darwin.toolchain | 9 ++++ ddnet-libs | 2 +- 13 files changed, 112 insertions(+), 52 deletions(-) create mode 100644 cmake/toolchains/darwin.toolchain diff --git a/CMakeLists.txt b/CMakeLists.txt index e273ab957..938418f66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,6 @@ function(set_extra_dirs_lib VARIABLE NAME) set("${TYPE}_${VARIABLE}_LIBDIR" "${DIR}" PARENT_SCOPE) set("EXTRA_${VARIABLE}_LIBDIR" "${DIR}" PARENT_SCOPE) endif() - set("${TYPE}_${VARIABLE}_INCLUDEDIR" "ddnet-libs/${NAME}/include" PARENT_SCOPE) endfunction() function(set_extra_dirs_include VARIABLE NAME LIBRARY) @@ -93,10 +92,16 @@ function(set_extra_dirs_include VARIABLE NAME LIBRARY) set("HINTS_${VARIABLE}_INCLUDEDIR" PARENT_SCOPE) is_bundled(IS_BUNDLED "${LIBRARY}") if(IS_BUNDLED) - set("HINTS_${VARIABLE}_INCLUDEDIR" "ddnet-libs/${NAME}/include" PARENT_SCOPE) + set("HINTS_${VARIABLE}_INCLUDEDIR" "ddnet-libs/${NAME}/include" "ddnet-libs/${NAME}/include/${TARGET_OS}" PARENT_SCOPE) endif() endfunction() +if(CMAKE_CROSSCOMPILING) + set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH NO_CMAKE_SYSTEM_PATH) +else() + set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH) +endif() + function(is_bundled VARIABLE PATH) if(PATH) string(FIND "${PATH}" "${PROJECT_SOURCE_DIR}" LOCAL_PATH_POS) @@ -110,9 +115,11 @@ function(is_bundled VARIABLE PATH) endif() endfunction() -# Check for PkgConfig once so all the other `find_package` calls can do it -# quietly. -find_package(PkgConfig) +if(NOT CMAKE_CROSSCOMPILING) + # Check for PkgConfig once so all the other `find_package` calls can do it + # quietly. + find_package(PkgConfig) +endif() find_package(Curl) find_package(Freetype) find_package(GTest) @@ -434,7 +441,7 @@ function(chash output_file) DEPENDS scripts/cmd5.py ${ARGN} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) -endfunction(chash) +endfunction() function(generate_source output_file script_parameter) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/${output_file} @@ -446,7 +453,7 @@ function(generate_source output_file script_parameter) datasrc/network.py WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) -endfunction(generate_source) +endfunction() file(MAKE_DIRECTORY "${PROJECT_SOURCE_DIR}/src/game/generated/") chash("src/game/generated/nethash.cpp" @@ -1111,6 +1118,7 @@ if(TARGET_OS AND TARGET_BITS) endif() elseif(TARGET_OS STREQUAL "mac") set(CPACK_SYSTEM_NAME "osx") + set(CPACK_GENERATOR DMG) endif() endif() diff --git a/README.md b/README.md index 52d70c201..fdc61378c 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,8 @@ Download and install some version of [Microsoft Visual Studio](https://www.visua Start CMake and select the source code folder (where DDNet resides, the directory with `CMakeLists.txt`). Additionally select a build folder, e.g. create a build subdirectory in the source code directory. Click "Configure" and select the Visual Studio generator (it should be pre-selected, so pressing "Finish" will suffice). After configuration finishes and the "Generate" reactivates, click it. When that finishes, click "Open Project". Visual Studio should open. You can compile the DDNet client by right-clicking the DDNet project (not the solution) and select "Select as StartUp project". Now you should be able to compile DDNet by clicking the green, triangular "Run" button. -Cross-compiling to Windows x86/x86\_64 --------------------------------------- +Cross-compiling on Linux to Windows x86/x86\_64 +----------------------------------------------- Install MinGW cross-compilers of the form `i686-w64-mingw32-gcc` (32 bit) or `x86_64-w64-mingw32-gcc` (64 bit). This is probably the hard part. ;) @@ -86,6 +86,14 @@ Install MinGW cross-compilers of the form `i686-w64-mingw32-gcc` (32 bit) or Then add `-DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/mingw64.toolchain` to the **initial** CMake command line. +Cross-compiling on Linux to macOS +--------------------------------- + +Install [osxcross](https://github.com/tpoechtrager/osxcross), then add +`-DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/darwin.toolchain` and +`-DCMAKE_OSX_SYSROOT=/path/to/osxcross/target/SDK/MacOSX10.11.sdk/` to the +**initial** CMake command line. + Importing the official DDNet Database ------------------------------------- diff --git a/cmake/Download_GTest_CMakeLists.txt.in b/cmake/Download_GTest_CMakeLists.txt.in index 11dc38306..315a3a367 100644 --- a/cmake/Download_GTest_CMakeLists.txt.in +++ b/cmake/Download_GTest_CMakeLists.txt.in @@ -12,4 +12,5 @@ ExternalProject_Add(googletest BUILD_COMMAND "" INSTALL_COMMAND "" TEST_COMMAND "" + TLS_VERIFY ON ) diff --git a/cmake/FindCurl.cmake b/cmake/FindCurl.cmake index 5aab5ecc0..355f0b607 100644 --- a/cmake/FindCurl.cmake +++ b/cmake/FindCurl.cmake @@ -1,16 +1,20 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_CURL libcurl) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_CURL libcurl) +endif() set_extra_dirs_lib(CURL curl) find_library(CURL_LIBRARY NAMES curl HINTS ${HINTS_CURL_LIBDIR} ${PC_CURL_LIBDIR} ${PC_CURL_LIBRARY_DIRS} PATHS ${PATHS_CURL_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(CURL curl "${CURL_LIBRARY}") find_path(CURL_INCLUDEDIR curl/curl.h HINTS ${HINTS_CURL_INCLUDEDIR} ${PC_CURL_INCLUDEDIR} ${PC_CURL_INCLUDE_DIRS} PATHS ${PATHS_CURL_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake index eafb019b1..306ca414a 100644 --- a/cmake/FindFreetype.cmake +++ b/cmake/FindFreetype.cmake @@ -1,11 +1,14 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_FREETYPE freetype2) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_FREETYPE freetype2) +endif() set_extra_dirs_lib(FREETYPE freetype) find_library(FREETYPE_LIBRARY - NAMES freetype + NAMES freetype freetype.6 HINTS ${HINTS_FREETYPE_LIBDIR} ${PC_FREETYPE_LIBDIR} ${PC_FREETYPE_LIBRARY_DIRS} PATHS ${PATHS_FREETYPE_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(FREETYPE freetype "${FREETYPE_LIBRARY}") find_path(FREETYPE_INCLUDEDIR @@ -13,6 +16,7 @@ find_path(FREETYPE_INCLUDEDIR PATH_SUFFIXES freetype2 HINTS ${HINTS_FREETYPE_INCLUDEDIR} ${PC_FREETYPE_INCLUDEDIR} ${PC_FREETYPE_INCLUDE_DIRS} PATHS ${PATHS_FREETYPE_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindGLEW.cmake b/cmake/FindGLEW.cmake index 3356062d2..c8a30c316 100644 --- a/cmake/FindGLEW.cmake +++ b/cmake/FindGLEW.cmake @@ -1,16 +1,20 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_GLEW libglew) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_GLEW libglew) +endif() set_extra_dirs_lib(GLEW glew) find_library(GLEW_LIBRARY NAMES GLEW glew32 HINTS ${HINTS_GLEW_LIBDIR} ${PC_GLEW_LIBDIR} ${PC_GLEW_LIBRARY_DIRS} PATHS ${PATHS_GLEW_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(GLEW glew "${GLEW_LIBRARY}") find_path(GLEW_INCLUDEDIR GL HINTS ${HINTS_GLEW_INCLUDEDIR} ${PC_GLEW_INCLUDEDIR} ${PC_GLEW_INCLUDE_DIRS} PATHS ${PATHS_GLEW_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindMySQL.cmake b/cmake/FindMySQL.cmake index 67b62d812..f4e451dcf 100644 --- a/cmake/FindMySQL.cmake +++ b/cmake/FindMySQL.cmake @@ -1,50 +1,54 @@ -find_program(MYSQL_CONFIG - NAMES mysql_config -) - -if(MYSQL_CONFIG) - exec_program(${MYSQL_CONFIG} - ARGS --include - OUTPUT_VARIABLE MY_TMP +if(NOT CMAKE_CROSSCOMPILING) + find_program(MYSQL_CONFIG + NAMES mysql_config ) - string(REGEX REPLACE "-I([^ ]*)( .*)?" "\\1" MY_TMP "${MY_TMP}") + if(MYSQL_CONFIG) + exec_program(${MYSQL_CONFIG} + ARGS --include + OUTPUT_VARIABLE MY_TMP + ) - set(MYSQL_CONFIG_INCLUDE_DIR ${MY_TMP} CACHE FILEPATH INTERNAL) + string(REGEX REPLACE "-I([^ ]*)( .*)?" "\\1" MY_TMP "${MY_TMP}") - exec_program(${MYSQL_CONFIG} - ARGS --libs_r - OUTPUT_VARIABLE MY_TMP - ) + set(MYSQL_CONFIG_INCLUDE_DIR ${MY_TMP} CACHE FILEPATH INTERNAL) - set(MYSQL_CONFIG_LIBRARIES "") + exec_program(${MYSQL_CONFIG} + ARGS --libs_r + OUTPUT_VARIABLE MY_TMP + ) - string(REGEX MATCHALL "-l[^ ]*" MYSQL_LIB_LIST "${MY_TMP}") - foreach(LIB ${MYSQL_LIB_LIST}) - string(REGEX REPLACE "[ ]*-l([^ ]*)" "\\1" LIB "${LIB}") - list(APPEND MYSQL_CONFIG_LIBRARIES "${LIB}") - endforeach(LIB ${MYSQL_LIBS}) + set(MYSQL_CONFIG_LIBRARIES "") - set(MYSQL_CONFIG_LIBRARY_PATH "") + string(REGEX MATCHALL "-l[^ ]*" MYSQL_LIB_LIST "${MY_TMP}") + foreach(LIB ${MYSQL_LIB_LIST}) + string(REGEX REPLACE "[ ]*-l([^ ]*)" "\\1" LIB "${LIB}") + list(APPEND MYSQL_CONFIG_LIBRARIES "${LIB}") + endforeach() - string(REGEX MATCHALL "-L[^ ]*" MYSQL_LIBDIR_LIST "${MY_TMP}") - foreach(LIB ${MYSQL_LIBDIR_LIST}) - string(REGEX REPLACE "[ ]*-L([^ ]*)" "\\1" LIB "${LIB}") - list(APPEND MYSQL_CONFIG_LIBRARY_PATH "${LIB}") - endforeach(LIB ${MYSQL_LIBS}) -endif(MYSQL_CONFIG) + set(MYSQL_CONFIG_LIBRARY_PATH "") + + string(REGEX MATCHALL "-L[^ ]*" MYSQL_LIBDIR_LIST "${MY_TMP}") + foreach(LIB ${MYSQL_LIBDIR_LIST}) + string(REGEX REPLACE "[ ]*-L([^ ]*)" "\\1" LIB "${LIB}") + list(APPEND MYSQL_CONFIG_LIBRARY_PATH "${LIB}") + endforeach() + endif() +endif() set_extra_dirs_lib(MYSQL mysql) find_library(MYSQL_LIBRARY NAMES "mysqlclient" "mysqlclient_r" "mariadbclient" HINTS ${HINTS_MYSQL_LIBDIR} ${MYSQL_CONFIG_LIBRARY_PATH} PATHS ${PATHS_MYSQL_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(MYSQL mysql "${MYSQL_LIBRARY}") find_path(MYSQL_INCLUDEDIR NAMES "mysql.h" HINTS ${HINTS_MYSQL_INCLUDEDIR} ${MYSQL_CONFIG_INCLUDE_DIR} PATHS ${PATHS_MYSQL_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_lib(MYSQL_CPPCONN mysql) @@ -52,12 +56,14 @@ find_library(MYSQL_CPPCONN_LIBRARY NAMES "mysqlcppconn" "mysqlcppconn-static" HINTS ${HINTS_MYSQL_CPPCONN_LIBDIR} ${MYSQL_CONFIG_LIBRARY_PATH} PATHS ${PATHS_MYSQL_CPPCONN_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(MYSQL_CPPCONN mysql "${MYSQL_CPPCONN_LIBRARY}") find_path(MYSQL_CPPCONN_INCLUDEDIR NAMES "mysql_connection.h" HINTS ${HINTS_MYSQL_CPPCONN_INCLUDEDIR} ${MYSQL_CONFIG_INCLUDE_DIR} PATHS ${PATHS_MYSQL_CPPCONN_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindOgg.cmake b/cmake/FindOgg.cmake index 1bcfdc52f..7a6705428 100644 --- a/cmake/FindOgg.cmake +++ b/cmake/FindOgg.cmake @@ -1,17 +1,21 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_OGG ogg) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_OGG ogg) +endif() set_extra_dirs_lib(OGG opus) find_library(OGG_LIBRARY NAMES ogg HINTS ${HINTS_OGG_LIBDIR} ${PC_OGG_LIBDIR} ${PC_OGG_LIBRARY_DIRS} PATHS ${PATHS_OGG_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(OGG opus "${OGG_LIBRARY}") find_path(OGG_INCLUDEDIR ogg.h PATH_SUFFIXES ogg HINTS ${HINTS_OGG_INCLUDEDIR} ${PC_OGG_INCLUDEDIR} ${PC_OGG_INCLUDE_DIRS} PATHS ${PATHS_OGG_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindOpus.cmake b/cmake/FindOpus.cmake index efa9ef498..fe117e98c 100644 --- a/cmake/FindOpus.cmake +++ b/cmake/FindOpus.cmake @@ -1,17 +1,21 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_OPUS opus) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_OPUS opus) +endif() set_extra_dirs_lib(OPUS opus) find_library(OPUS_LIBRARY NAMES opus HINTS ${HINTS_OPUS_LIBDIR} ${PC_OPUS_LIBDIR} ${PC_OPUS_LIBRARY_DIRS} PATHS ${PATHS_OPUS_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(OPUS opus "${OPUS_LIBRARY}") find_path(OPUS_INCLUDEDIR opus.h PATH_SUFFIXES opus HINTS ${HINTS_OPUS_INCLUDEDIR} ${PC_OPUS_INCLUDEDIR} ${PC_OPUS_INCLUDE_DIRS} PATHS ${PATHS_OPUS_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindOpusfile.cmake b/cmake/FindOpusfile.cmake index 0dd07a2cf..e3d9b01a0 100644 --- a/cmake/FindOpusfile.cmake +++ b/cmake/FindOpusfile.cmake @@ -1,17 +1,21 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_OPUSFILE opusfile) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_OPUSFILE opusfile) +endif() set_extra_dirs_lib(OPUSFILE opus) find_library(OPUSFILE_LIBRARY NAMES opusfile HINTS ${HINTS_OPUSFILE_LIBDIR} ${PC_OPUSFILE_LIBDIR} ${PC_OPUSFILE_LIBRARY_DIRS} PATHS ${PATHS_OPUSFILE_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) set_extra_dirs_include(OPUSFILE opus "${OPUSFILE_LIBRARY}") find_path(OPUSFILE_INCLUDEDIR opusfile.h PATH_SUFFIXES opus HINTS ${HINTS_OPUSFILE_INCLUDEDIR} ${PC_OPUSFILE_INCLUDEDIR} ${PC_OPUSFILE_INCLUDE_DIRS} PATHS ${PATHS_OPUSFILE_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake index b3d4f5880..3b7a2b28f 100644 --- a/cmake/FindSDL2.cmake +++ b/cmake/FindSDL2.cmake @@ -1,12 +1,16 @@ -find_package(PkgConfig QUIET) -pkg_check_modules(PC_SDL2 sdl2) +if(NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_SDL2 sdl2) +endif() set_extra_dirs_lib(SDL2 sdl) find_library(SDL2_LIBRARY NAMES SDL2 HINTS ${HINTS_SDL2_LIBDIR} ${PC_SDL2_LIBDIR} ${PC_SDL2_LIBRARY_DIRS} PATHS ${PATHS_SDL2_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} ) +set(CMAKE_FIND_FRAMEWORK FIRST) set_extra_dirs_include(SDL2 sdl "${SDL2_LIBRARY}") # Looking for 'SDL.h' directly might accidently find a SDL instead of SDL 2 # installation. Look for a header file only present in SDL 2 instead. diff --git a/cmake/toolchains/darwin.toolchain b/cmake/toolchains/darwin.toolchain new file mode 100644 index 000000000..33e9b0ef0 --- /dev/null +++ b/cmake/toolchains/darwin.toolchain @@ -0,0 +1,9 @@ +set(CMAKE_SYSTEM_NAME Darwin) + +set(CMAKE_C_COMPILER o64-clang) +set(CMAKE_CXX_COMPILER o64-clang++) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/ddnet-libs b/ddnet-libs index 9abb67a94..fd5c2cd28 160000 --- a/ddnet-libs +++ b/ddnet-libs @@ -1 +1 @@ -Subproject commit 9abb67a94170fbf177b1d22ca180c96bd065cab1 +Subproject commit fd5c2cd28c8e92e2b4b2f63f0ad2c02b837699fe