diff --git a/CMakeLists.txt b/CMakeLists.txt index cb16a3f4df..e0a44bcff2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,55 @@ else (DISABLE_NETWORK) endif (WIN32) endif (DISABLE_NETWORK) +option(STATIC "Create a static build.") + +# Handle creating the rct2 text and data files on OS X and Linux +# See details in src/openrct2.c:openrct2_setup_rct2_segment for how the values +# were derived. +if (UNIX) + add_custom_command( + OUTPUT openrct2_text + COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_text bs=4096 skip=1 count=1187 + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe + ) + add_custom_command( + OUTPUT openrct2_data + COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 skip=1188 count=318 + COMMAND dd if=/dev/zero of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 seek=318 count=2630 conv=notrunc + COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 skip=1506 seek=2948 count=1 conv=notrunc + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe + ) + add_custom_target(segfiles DEPENDS openrct2_text openrct2_data) + if (APPLE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sectcreate rct2_text __text ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_text -sectcreate rct2_data __data ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x401000 -segprot rct2_text rwx rwx -fno-pie -read_only_relocs suppress") + else (APPLE) + # For Linux we have to use objcopy to wrap regular binaries into a linkable + # format. We use specific section names which are then referenced in a + # bespoke linker script so they can be placed at predefined VMAs. + add_custom_command( + OUTPUT openrct2_text_section.o + COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 openrct2_text openrct2_text_section.o --rename-section .data=.rct2_text,contents,alloc,load,readonly,code + DEPENDS segfiles + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + add_custom_command( + OUTPUT openrct2_data_section.o + COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 openrct2_data openrct2_data_section.o --rename-section .data=.rct2_data,contents,alloc,load,readonly,data + DEPENDS segfiles + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + add_custom_target(linkable_sections DEPENDS openrct2_text_section.o openrct2_data_section.o) + SET_SOURCE_FILES_PROPERTIES( + openrct2_text_section.o openrct2_data_section.o + PROPERTIES + EXTERNAL_OBJECT true + GENERATED true + ) + # can't use GLOB here, as the files don't exist yet at cmake-time + set(RCT2_SECTIONS "${CMAKE_BINARY_DIR}/openrct2_data_section.o" "${CMAKE_BINARY_DIR}/openrct2_text_section.o") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-T,\"${CMAKE_CURRENT_SOURCE_DIR}/distribution/linux/ld_script.xc\"") + endif (APPLE) +endif (UNIX) set(DEBUG_LEVEL 0 CACHE STRING "Select debug level for compilation. Use value in range 0–3.") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=${DEBUG_LEVEL}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG=${DEBUG_LEVEL}") @@ -56,24 +105,49 @@ if (APPLE) set_source_files_properties(${ORCT2_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c -fmodules") endif (APPLE) -if (UNIX) - # force 32bit build for now and set necessary flags to compile code as is - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -std=gnu99 -fno-omit-frame-pointer -fno-pie") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer -fno-pie") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") - set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}) -endif (UNIX) +# force 32bit build for now and set necessary flags to compile code as is +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -std=gnu99 -fno-omit-frame-pointer -fno-pie") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer -fno-pie") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}") + +if (MINGW) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpack-struct=1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpack-struct=1") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++") +endif () + +if (STATIC) + if (WIN32) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static") + else (WIN32) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + endif (WIN32) +endif () # find and include SDL2 PKG_CHECK_MODULES(SDL2 REQUIRED sdl2 SDL2_ttf) +if (STATIC) + # FreeType is required by SDL2_ttf, but not wired up properly in package + PKG_CHECK_MODULES(FREETYPE REQUIRED freetype2) + SET(SDL2LIBS ${SDL2_STATIC_LIBRARIES} ${FREETYPE_STATIC_LIBRARIES}) +else (STATIC) + SET(SDL2LIBS ${SDL2_LIBRARIES}) +endif (STATIC) if (NOT DISABLE_HTTP_TWITCH) PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl) - PKG_CHECK_MODULES(JANSSON REQUIRED jansson) - SET(HTTPLIBS ${LIBCURL_LIBRARIES} ${JANSSON_LIBRARIES}) + PKG_CHECK_MODULES(JANSSON REQUIRED jansson>=2.7) if (WIN32) - SET(HTTPLIBS ${HTTPLIBS} ssl crypto winmm.lib ws2_32) + # Curl depends on openssl and ws2 in mingw builds, but is not wired up in pkg-config + PKG_CHECK_MODULES(SSL REQUIRED openssl) + set(WSLIBS ws2_32) endif (WIN32) + if (STATIC) + SET(HTTPLIBS ${LIBCURL_STATIC_LIBRARIES} ${JANSSON_STATIC_LIBRARIES} ${SSL_STATIC_LIBRARIES} ${WSLIBS}) + else (STATIC) + SET(HTTPLIBS ${LIBCURL_LIBRARIES} ${JANSSON_LIBRARIES} ${SSL_LIBRARIES} ${WSLIBS}) + endif (STATIC) endif (NOT DISABLE_HTTP_TWITCH) # speex v1.1.15 is supplied in our zipped library, but distributions provide @@ -99,7 +173,11 @@ if (WIN32) # build as library for now, replace with add_executable add_library(${PROJECT} SHARED ${ORCT2_SOURCES} ${SPEEX_SOURCES}) else (WIN32) - add_executable(${PROJECT} ${ORCT2_SOURCES} ${ORCT2_MM_SOURCES}) + add_executable(${PROJECT} ${ORCT2_SOURCES} ${ORCT2_MM_SOURCES} ${RCT2_SECTIONS}) + add_dependencies(${PROJECT} segfiles) + if (NOT APPLE) + add_dependencies(${PROJECT} linkable_sections) + endif () add_custom_command( OUTPUT g2.dat COMMAND ./openrct2 sprite build ${CMAKE_BINARY_DIR}/g2.dat ${CMAKE_CURRENT_SOURCE_DIR}/resources/g2/ @@ -108,11 +186,6 @@ else (WIN32) add_custom_target(g2 DEPENDS ${PROJECT} g2.dat) endif (WIN32) -if (APPLE) - FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) - TARGET_LINK_LIBRARIES(${PROJECT} ${ICONV_LIBRARIES}) -endif (APPLE) - if (UNIX AND NOT APPLE) # FontConfig for TrueType fonts. PKG_CHECK_MODULES(FONTCONFIG REQUIRED fontconfig) @@ -120,55 +193,6 @@ if (UNIX AND NOT APPLE) TARGET_LINK_LIBRARIES(${PROJECT} ${FONTCONFIG_LIBRARIES}) endif (UNIX AND NOT APPLE) -# Handle creating the rct2 text and data files on OS X and Linux -# See details in src/openrct2.c:openrct2_setup_rct2_segment for how the values -# were derived. -if (UNIX) - add_custom_command( - OUTPUT openrct2_text - COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_text bs=4096 skip=1 count=1187 - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe - ) - add_custom_command( - OUTPUT openrct2_data - COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 skip=1188 count=318 - COMMAND dd if=/dev/zero of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 seek=318 count=2630 conv=notrunc - COMMAND dd if=${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe of=${CMAKE_BINARY_DIR}/openrct2_data bs=4096 skip=1506 seek=2948 count=1 conv=notrunc - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe - ) - add_custom_target(segfiles DEPENDS openrct2_text openrct2_data) - add_dependencies(${PROJECT} segfiles) - if (APPLE) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sectcreate rct2_text __text ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_text -sectcreate rct2_data __data ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x401000 -segprot rct2_text rwx rwx -fno-pie -read_only_relocs suppress") - else (APPLE) - # For Linux we have to use objcopy to wrap regular binaries into a linkable - # format. We use specific section names which are then referenced in a - # bespoke linker script so they can be placed at predefined VMAs. - add_custom_command( - OUTPUT openrct2_text_section.o - COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 openrct2_text openrct2_text_section.o --rename-section .data=.rct2_text,contents,alloc,load,readonly,code - DEPENDS segfiles - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - add_custom_command( - OUTPUT openrct2_data_section.o - COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 openrct2_data openrct2_data_section.o --rename-section .data=.rct2_data,contents,alloc,load,readonly,data - DEPENDS segfiles - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - add_custom_target(linkable_sections DEPENDS openrct2_text_section.o openrct2_data_section.o) - add_dependencies(${PROJECT} linkable_sections) - SET_SOURCE_FILES_PROPERTIES( - openrct2_text_section.o openrct2_data_section.o - PROPERTIES - EXTERNAL_OBJECT true - GENERATED true - ) - # can't use GLOB here, as the files don't exist yet at cmake-time - list(APPEND RCT2_SECTIONS "${CMAKE_BINARY_DIR}/openrct2_data_section.o" "${CMAKE_BINARY_DIR}/openrct2_text_section.o") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-T,\"${CMAKE_CURRENT_SOURCE_DIR}/distribution/linux/ld_script.xc\"") - endif (APPLE) -endif (UNIX) # install into ${CMAKE_INSTALL_PREFIX}/bin/ #install (TARGETS ${PROJECT} DESTINATION bin) @@ -176,7 +200,13 @@ endif (UNIX) # libopenrct2.dll -> openrct2.dll set_target_properties(${PROJECT} PROPERTIES PREFIX "") -TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2_LIBRARIES} ${ORCTLIBS_LIB} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${RCT2_SECTIONS}) +TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${ORCTLIBS_LIB} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB}) + +if (APPLE OR STATIC) + FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) + TARGET_LINK_LIBRARIES(${PROJECT} ${ICONV_LIBRARIES}) +endif (APPLE OR STATIC) + # CMake does not allow specifying a dependency chain which includes built-in # targets, like `install`, so we have to trick it and execute dependency ourselves. diff --git a/CMakeLists_mingw.txt b/CMakeLists_mingw.txt index d4817994d1..f633585f43 100644 --- a/CMakeLists_mingw.txt +++ b/CMakeLists_mingw.txt @@ -1,4 +1,3 @@ -SET(ACTUAL_SYSTEM ${CMAKE_SYSTEM_NAME}) SET(CMAKE_SYSTEM_NAME Windows) SET(COMPILER_PREFIX i686-w64-mingw32) @@ -8,17 +7,6 @@ SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres) SET(CMAKE_PKGCONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config) SET(PKG_CONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config) -# potential flags to make code more similar to MSVC: -# -fshort-wchar -fshort-enums -mms-bitfields -# -set(CMAKE_C_FLAGS "-std=gnu99 -fpack-struct=1" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS "-std=c++0x -std=gnu++0x -fpack-struct=1" CACHE STRING "" FORCE) -if(${ACTUAL_SYSTEM} MATCHES "Linux") - set(CMAKE_SHARED_LINKER_FLAGS "-O3 -static-libgcc -static-libstdc++ -static -lpthread" CACHE STRING "" FORCE) -else() - set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++" CACHE STRING "" FORCE) -endif(${ACTUAL_SYSTEM} MATCHES "Linux") - if(APPLE) SET(TARGET_ENVIRONMENT /usr/local/mingw-w32-bin_i686-darwin/i686-w64-mingw32) else() diff --git a/src/platform/windows.c b/src/platform/windows.c index e44a357f2b..d1443b762a 100644 --- a/src/platform/windows.c +++ b/src/platform/windows.c @@ -58,6 +58,11 @@ utf8 **windows_get_command_line_args(int *outNumArgs); // return 0; // } +/* DllMain is already defined in one of static libraries we implicitly depend + * on (libcrypto), which is their bug really, but since we don't do anything in + * here, just comment it out. + */ +#ifndef __MINGW32__ /** * Entry point for when the DLL is loaded. This will be removed when OpenRCT2 can be built as a stand alone application. */ @@ -65,6 +70,7 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { return TRUE; } +#endif // __MINGW32__ /** * The function that is called directly from the host application (rct2.exe)'s WinMain. This will be removed when OpenRCT2 can