From 68b3620bacc455f3fb7f1748e2abecfafe5e15bb Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 13 Sep 2015 13:10:58 -0400 Subject: [PATCH] Allow proper compiling of libjpeg for windows. This expands on #777 to work with jconfig.h properly. To facilitate these operations, a new macro was added for doing compile tests. Note that this commit does NOT bring in the other files associated with this version of libjpeg. At some point, it would be desirable to automatically get the files as part of the cmake configuration step, similar to ffmpeg. --- CMake/CMakeMacros.cmake | 26 +++++++ CMake/TestCode/test_broken.c | 3 + CMake/TestCode/test_external.c | 11 +++ CMake/TestCode/test_prototype.c | 17 ++++ StepmaniaCore.cmake | 30 ++++++- extern/CMakeLists.txt | 4 +- extern/CMakeProject-jpeg.cmake | 133 +++++++++++++++++++------------- extern/config.jpeg.in.h | 53 +++++++++++++ extern/libjpeg/jconfig.h | 54 ------------- src/CMakeLists.txt | 4 - src/RageSurface_Load_JPEG.cpp | 18 ++--- src/RageSurface_Save_JPEG.cpp | 9 --- 12 files changed, 221 insertions(+), 141 deletions(-) create mode 100644 CMake/TestCode/test_broken.c create mode 100644 CMake/TestCode/test_external.c create mode 100644 CMake/TestCode/test_prototype.c create mode 100644 extern/config.jpeg.in.h delete mode 100644 extern/libjpeg/jconfig.h diff --git a/CMake/CMakeMacros.cmake b/CMake/CMakeMacros.cmake index 7e85ddd870..9c3683f859 100644 --- a/CMake/CMakeMacros.cmake +++ b/CMake/CMakeMacros.cmake @@ -56,3 +56,29 @@ function(disable_project_warnings projectName) endif() endfunction() +macro(check_compile_features BIN_DIR SOURCE_FILE GREETER GREET_SUCCESS GREET_FAILURE TARGET_VAR ON_SUCCESS) + if(NOT DEFINED "${TARGET_VAR}") + message(STATUS "${GREETER}") + try_compile(${TARGET_VAR} "${BIN_DIR}" + SOURCES "${SOURCE_FILE}" + ) + if(${TARGET_VAR}) + if (${ON_SUCCESS}) + message(STATUS "${GREETER} - ${GREET_SUCCESS}") + set(${TARGET_VAR} 1 CACHE INTERNAL "${GREETER}") + else() + message(STATUS "${GREETER} - ${GREET_FAILURE}") + set(${TARGET_VAR} "" CACHE INTERNAL "${GREETER}") + endif() + else() + if(${ON_SUCCESS}) + message(STATUS "${GREETER} - ${GREET_FAILURE}") + set(${TARGET_VAR} 1 CACHE INTERNAL "${GREETER}") + else() + message(STATUS "${GREETER} - ${GREET_SUCCESS}") + set(${TARGET_VAR} "" CACHE INTERNAL "${GREETER}") + endif() + endif() + endif() +endmacro() + diff --git a/CMake/TestCode/test_broken.c b/CMake/TestCode/test_broken.c new file mode 100644 index 0000000000..5e8f8bb44c --- /dev/null +++ b/CMake/TestCode/test_broken.c @@ -0,0 +1,3 @@ +/* Borrowed from libjpeg. */ +typedef struct undefined_structure * undef_struct_ptr; + diff --git a/CMake/TestCode/test_external.c b/CMake/TestCode/test_external.c new file mode 100644 index 0000000000..f501c4e4f8 --- /dev/null +++ b/CMake/TestCode/test_external.c @@ -0,0 +1,11 @@ +#include + +int very_long_name_here_one() { return 0; } +int very_long_name_here_two() { return 1; } + +int main() { + printf("%d\n", very_long_name_here_one()); + printf("%d\n", very_long_name_here_two()); + return 0; +} + diff --git a/CMake/TestCode/test_prototype.c b/CMake/TestCode/test_prototype.c new file mode 100644 index 0000000000..4ad5c23064 --- /dev/null +++ b/CMake/TestCode/test_prototype.c @@ -0,0 +1,17 @@ +/* Borrowed from Wikipedia: Function prototype page. */ +#include + +int myfunction(int n); + +int main(void) { + printf("%d\n", myfunction()); /* Intentional: we want this to fail. */ + return 0; +} + +int myfunction(int n) { + if (n == 0) { + return 1; + } + return n * myfunction(n - 1); +} + diff --git a/StepmaniaCore.cmake b/StepmaniaCore.cmake index a5e6274005..f4027b478b 100644 --- a/StepmaniaCore.cmake +++ b/StepmaniaCore.cmake @@ -36,11 +36,11 @@ else() endif() # Allow for finding our libraries in a standard location. -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/CMake/Modules/") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" "${SM_CMAKE_DIR}/Modules/") -include("${CMAKE_CURRENT_LIST_DIR}/CMake/DefineOptions.cmake") +include("${SM_CMAKE_DIR}/DefineOptions.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/CMake/SMDefs.cmake") +include("${SM_CMAKE_DIR}/SMDefs.cmake") # Put the predefined targets in separate groups. set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -105,10 +105,16 @@ check_cxx_symbol_exists(roundf cmath HAVE_ROUNDF) check_cxx_symbol_exists(lrintf cmath HAVE_LRINTF) check_cxx_symbol_exists(strtof cstdlib HAVE_STRTOF) check_symbol_exists(M_PI math.h HAVE_M_PI) +check_symbol_exists(size_t stddef.h HAVE_SIZE_T_STDDEF) +check_symbol_exists(size_t stdlib.h HAVE_SIZE_T_STDLIB) +check_symbol_exists(size_t stdio.h HAVE_SIZE_T_STDIO) # Checks to make it easier to work with 32-bit/64-bit builds if required. include(CheckTypeSize) +check_type_size(char SIZEOF_CHAR) +check_type_size("unsigned char" SIZEOF_UNSIGNED_CHAR) check_type_size(short SIZEOF_SHORT) +check_type_size("unsigned short" SIZEOF_UNSIGNED_SHORT) check_type_size(int SIZEOF_INT) check_type_size(long SIZEOF_LONG) check_type_size("long long" SIZEOF_LONG_LONG) @@ -127,6 +133,24 @@ else() set(ENDIAN_LITTLE 1) endif() +check_compile_features("${SM_CMAKE_DIR}/TestCode" "${SM_CMAKE_DIR}/TestCode/test_prototype.c" "Checking for function prototype capabilities" "found" "not found" SM_IGNORED_PROTOTYPE_CALL FALSE) + +if(NOT SM_IGNORED_PROTOTYPE_CALL) + set(HAVE_PROTOTYPES TRUE) +endif() + +check_compile_features("${SM_CMAKE_DIR}/TestCode" "${SM_CMAKE_DIR}/TestCode/test_external.c" "Checking for external name shortening requirements" "not needed" "needed" SM_BUILT_LONG_NAME TRUE) + +if (NOT SM_BUILT_LONG_NAME) + set(NEED_SHORT_EXTERNAL_NAMES 1) +endif() + +check_compile_features("${SM_CMAKE_DIR}/TestCode" "${SM_CMAKE_DIR}/TestCode/test_broken.c" "Checking if incomplete types are broken." "not broken" "broken" SM_BUILT_INCOMPLETE_TYPE FALSE) + +if (SM_BUILT_INCOMPLETE_TYPE) + set(INCOMPLETE_TYPES_BROKEN 1) +endif() + if (WITH_VERSION_INFO) set(HAVE_VERSION_INFO 1) endif() diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 156882cb75..bc786a95f5 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -4,6 +4,7 @@ include(CMakeProject-json.cmake) if (APPLE OR MSVC) include(CMakeProject-mad.cmake) include(CMakeProject-zlib.cmake) + include(CMakeProject-jpeg.cmake) endif() if (NOT SYSTEM_PCRE_FOUND) include(CMakeProject-pcre.cmake) @@ -12,6 +13,3 @@ include(CMakeProject-tomcrypt.cmake) include(CMakeProject-tommath.cmake) include(CMakeProject-png.cmake) -if (APPLE) - include(CMakeProject-jpeg.cmake) -endif() diff --git a/extern/CMakeProject-jpeg.cmake b/extern/CMakeProject-jpeg.cmake index b315c9c8fb..757d7902b5 100644 --- a/extern/CMakeProject-jpeg.cmake +++ b/extern/CMakeProject-jpeg.cmake @@ -1,61 +1,81 @@ +set(JPEG_DIR "${SM_EXTERN_DIR}/libjpeg") + +configure_file("${SM_EXTERN_DIR}/config.jpeg.in.h" "${JPEG_DIR}/jconfig.h") + +if (NOT HAVE_PROTOTYPES) + list(APPEND JPEG_SRC "${JPEG_DIR}/ansi2knr.c") +endif() + list(APPEND JPEG_SRC - "libjpeg/ansi2knr.c" - "libjpeg/cdjpeg.c" - "libjpeg/cjpeg.c" - "libjpeg/ckconfig.c" - "libjpeg/djpeg.c" - "libjpeg/jaricom.c" - "libjpeg/jcapimin.c" - "libjpeg/jcapistd.c" - "libjpeg/jcarith.c" - "libjpeg/jccoefct.c" - "libjpeg/jccolor.c" - "libjpeg/jcdctmgr.c" - "libjpeg/jchuff.c" - "libjpeg/jcinit.c" - "libjpeg/jcmainct.c" - "libjpeg/jcmarker.c" - "libjpeg/jcmaster.c" - "libjpeg/jcomapi.c" - "libjpeg/jcparam.c" - "libjpeg/jcprepct.c" - "libjpeg/jcsample.c" - "libjpeg/jctrans.c" - "libjpeg/jdapimin.c" - "libjpeg/jdapistd.c" - "libjpeg/jdarith.c" - "libjpeg/jdatadst.c" - "libjpeg/jdcoefct.c" - "libjpeg/jdcolor.c" - "libjpeg/jddctmgr.c" - "libjpeg/jdhuff.c" - "libjpeg/jdinput.c" - "libjpeg/jdmainct.c" - "libjpeg/jdmarker.c" - "libjpeg/jdmaster.c" - "libjpeg/jdmerge.c" - "libjpeg/jdpostct.c" - "libjpeg/jdsample.c" - "libjpeg/jdtrans.c" - "libjpeg/jerror.c" - "libjpeg/jfdctflt.c" - "libjpeg/jfdctfst.c" - "libjpeg/jfdctint.c" - "libjpeg/jutils.c" - "libjpeg/jidctflt.c" - "libjpeg/jidctfst.c" - "libjpeg/jidctint.c" - "libjpeg/jmemansi.c" - "libjpeg/jmemmgr.c" - "libjpeg/jmemname.c" - "libjpeg/jmemnobs.c" - "libjpeg/jquant1.c" - "libjpeg/jquant2.c" + "${JPEG_DIR}/cdjpeg.c" + "${JPEG_DIR}/cjpeg.c" + "${JPEG_DIR}/ckconfig.c" + "${JPEG_DIR}/djpeg.c" + "${JPEG_DIR}/jaricom.c" + "${JPEG_DIR}/jcapimin.c" + "${JPEG_DIR}/jcapistd.c" + "${JPEG_DIR}/jcarith.c" + "${JPEG_DIR}/jccoefct.c" + "${JPEG_DIR}/jccolor.c" + "${JPEG_DIR}/jcdctmgr.c" + "${JPEG_DIR}/jchuff.c" + "${JPEG_DIR}/jcinit.c" + "${JPEG_DIR}/jcmainct.c" + "${JPEG_DIR}/jcmarker.c" + "${JPEG_DIR}/jcmaster.c" + "${JPEG_DIR}/jcomapi.c" + "${JPEG_DIR}/jcparam.c" + "${JPEG_DIR}/jcprepct.c" + "${JPEG_DIR}/jcsample.c" + "${JPEG_DIR}/jctrans.c" + "${JPEG_DIR}/jdapimin.c" + "${JPEG_DIR}/jdapistd.c" + "${JPEG_DIR}/jdarith.c" + "${JPEG_DIR}/jdatadst.c" + "${JPEG_DIR}/jdcoefct.c" + "${JPEG_DIR}/jdcolor.c" + "${JPEG_DIR}/jddctmgr.c" + "${JPEG_DIR}/jdhuff.c" + "${JPEG_DIR}/jdinput.c" + "${JPEG_DIR}/jdmainct.c" + "${JPEG_DIR}/jdmarker.c" + "${JPEG_DIR}/jdmaster.c" + "${JPEG_DIR}/jdmerge.c" + "${JPEG_DIR}/jdpostct.c" + "${JPEG_DIR}/jdsample.c" + "${JPEG_DIR}/jdtrans.c" + "${JPEG_DIR}/jerror.c" + "${JPEG_DIR}/jfdctflt.c" + "${JPEG_DIR}/jfdctfst.c" + "${JPEG_DIR}/jfdctint.c" + "${JPEG_DIR}/jutils.c" + "${JPEG_DIR}/jidctflt.c" + "${JPEG_DIR}/jidctfst.c" + "${JPEG_DIR}/jidctint.c" + "${JPEG_DIR}/jmemansi.c" + "${JPEG_DIR}/jmemmgr.c" + "${JPEG_DIR}/jmemname.c" + "${JPEG_DIR}/jmemnobs.c" + "${JPEG_DIR}/jquant1.c" + "${JPEG_DIR}/jquant2.c" ) -source_group("" FILES ${JPEG_SRC}) +list(APPEND JPEG_HPP + "${JPEG_DIR}/jconfig.h" + "${JPEG_DIR}/jdct.h" + "${JPEG_DIR}/jerror.h" + "${JPEG_DIR}/jinclude.h" + "${JPEG_DIR}/jmemsys.h" + "${JPEG_DIR}/jmorecfg.h" + "${JPEG_DIR}/jpegint.h" + "${JPEG_DIR}/jpeglib.h" + "${JPEG_DIR}/jversion.h" +) -add_library("jpeg" ${JPEG_SRC}) +source_group("Source Files" FILES ${JPEG_SRC}) +source_group("Header Files" FILES ${JPEG_HPP}) + +add_library("jpeg" ${JPEG_SRC} ${JPEG_HPP}) disable_project_warnings("jpeg") @@ -63,4 +83,7 @@ set_property(TARGET "jpeg" PROPERTY FOLDER "External Libraries") if(MSVC) sm_add_compile_definition("jpeg" _CRT_SECURE_NO_WARNINGS) -endif(MSVC) \ No newline at end of file +endif(MSVC) + +target_include_directories("jpeg" PUBLIC "${JPEG_DIR}") + diff --git a/extern/config.jpeg.in.h b/extern/config.jpeg.in.h new file mode 100644 index 0000000000..baff43631a --- /dev/null +++ b/extern/config.jpeg.in.h @@ -0,0 +1,53 @@ +/* Auto-generated config.h file powered by cmake. */ + +/* Defined to 1 if the compiler supports prototype functions. */ +#cmakedefine HAVE_PROTOTYPES 1 + +/* Defined to 1 if we have access to stddef.h */ +#cmakedefine HAVE_STDDEF_H 1 + +/* Defined to 1 if we have access to stdlib.h */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Defined to 1 if we only have the BSD style strings.h file. */ +#cmakedefine HAVE_STRING_H 1 +#cmakedefine HAVE_STRINGS_H 1 +#if defined(HAVE_STRINGS_H) && !defined(HAVE_STRING_H) +#define NEED_BSD_STRINGS 1 +#endif + +/* Defined to 1 if we have an unsigned char type. */ +#cmakedefine HAVE_SIZEOF_UNSIGNED_CHAR 1 +#if defined(HAVE_SIZEOF_UNSIGNED_CHAR) +#define HAVE_UNSIGNED_CHAR 1 +#endif + +/* Defined to 1 if we have an unsigned short type. */ +#cmakedefine HAVE_SIZEOF_UNSIGNED_SHORT 1 +#if defined(HAVE_SIZEOF_UNSIGNED_SHORT) +#define HAVE_UNSIGNED_SHORT 1 +#endif + +/* At some point, allow for defining CHAR_IS_UNSIGNED. */ + +/* Define to 1 if the sys types header is required. */ +/* TODO: Figure out the right way of using this with size_t. */ +#cmakedefine HAVE_SYS_TYPES_H 1 +#if defined(HAVE_SYS_TYPES_H) +#define NEED_SYS_TYPES_H 1 +#endif + +/* Defined to 1 if short external names are needed for linking. */ +#cmakedefine NEED_SHORT_EXTERNAL_NAMES 1 + +/* Defined to 1 if incomplete types are broken. */ +#cmakedefine INCOMPLETE_TYPES_BROKEN 1 + +/* Windows gets a special definition of boolean for some reason. */ +#if defined(WIN32) +#if !defined(__RPCNDR_H__) +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN +#endif + diff --git a/extern/libjpeg/jconfig.h b/extern/libjpeg/jconfig.h deleted file mode 100644 index 41391c3d7d..0000000000 --- a/extern/libjpeg/jconfig.h +++ /dev/null @@ -1,54 +0,0 @@ -/* jconfig.h. Generated from jconfig.cfg by configure. */ -/* jconfig.cfg --- source file edited by configure script */ -/* see jconfig.txt for explanations */ - -#define HAVE_PROTOTYPES 1 -#define HAVE_UNSIGNED_CHAR 1 -#define HAVE_UNSIGNED_SHORT 1 -/* #undef void */ -/* #undef const */ -/* #undef CHAR_IS_UNSIGNED */ - - - -/* #undef NEED_BSD_STRINGS */ -/* #undef NEED_SYS_TYPES_H */ -/* #undef NEED_FAR_POINTERS */ -/* #undef NEED_SHORT_EXTERNAL_NAMES */ -/* Define this if you get warnings about undefined structures. */ -/* #undef INCOMPLETE_TYPES_BROKEN */ - -/* Define "boolean" as unsigned char, not int, on Windows systems. */ -#ifdef _WIN32 -#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ -typedef unsigned char boolean; -#endif -#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ -#endif - -#ifdef JPEG_INTERNALS - -/* #undef RIGHT_SHIFT_IS_UNSIGNED */ -#define INLINE __inline__ -/* These are for configuring the JPEG memory manager. */ -/* #undef DEFAULT_MAX_MEM */ -/* #undef NO_MKTEMP */ - -#endif /* JPEG_INTERNALS */ - -#ifdef JPEG_CJPEG_DJPEG - -#define BMP_SUPPORTED /* BMP image file format */ -#define GIF_SUPPORTED /* GIF image file format */ -#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ -/* #undef RLE_SUPPORTED */ -#define TARGA_SUPPORTED /* Targa image file format */ - -/* #undef TWO_FILE_COMMANDLINE */ -/* #undef NEED_SIGNAL_CATCHER */ -/* #undef DONT_USE_B_MODE */ - -/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ -/* #undef PROGRESS_REPORT */ - -#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 742a0b483f..9b94b1a8f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -264,7 +264,6 @@ list(APPEND SM_WINDOWS_PROGRAM_DLLS "${SM_PROGRAM_DIR}/avcodec-53.dll" "${SM_PROGRAM_DIR}/avformat-53.dll" "${SM_PROGRAM_DIR}/avutil-51.dll" - "${SM_PROGRAM_DIR}/jpeg.dll" "${SM_PROGRAM_DIR}/msvcp100.dll" "${SM_PROGRAM_DIR}/msvcp110.dll" "${SM_PROGRAM_DIR}/msvcr100.dll" @@ -461,7 +460,6 @@ if (WIN32) sm_add_link_flag("${SM_EXE_NAME}" "/LIBPATH:\"${DIRECTX_LIBRARY_DIR}\"") sm_add_link_flag("${SM_EXE_NAME}" "/LIBPATH:\"${SM_EXTERN_DIR}/ffmpeg/lib\"") - sm_add_link_flag("${SM_EXE_NAME}" "/LIBPATH:\"${SM_EXTERN_DIR}/libjpeg\"") sm_add_link_flag("${SM_EXE_NAME}" "/LIBPATH:\"${SM_EXTERN_DIR}/vorbis/win32\"") sm_add_link_flag("${SM_EXE_NAME}" "/LIBPATH:\"${SM_SRC_DIR}/archutils/Win32/ddk\"") sm_add_link_flag("${SM_EXE_NAME}" "/ERRORREPORT:SEND") @@ -614,7 +612,6 @@ if(NOT APPLE) if(MSVC) list(APPEND SM_INCLUDE_DIRS "${SM_EXTERN_DIR}/ffmpeg/include" - "${SM_EXTERN_DIR}/libjpeg" ) else() list(APPEND SM_INCLUDE_DIRS @@ -675,7 +672,6 @@ if(NOT APPLE) install(FILES "${SM_PROGRAM_DIR}/avcodec-53.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") install(FILES "${SM_PROGRAM_DIR}/avformat-53.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") install(FILES "${SM_PROGRAM_DIR}/avutil-51.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") - install(FILES "${SM_PROGRAM_DIR}/jpeg.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") install(FILES "${SM_PROGRAM_DIR}/msvcp100.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") install(FILES "${SM_PROGRAM_DIR}/msvcp110.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") install(FILES "${SM_PROGRAM_DIR}/msvcr100.dll" DESTINATION "${SM_FULL_INSTALLATION_PATH}") diff --git a/src/RageSurface_Load_JPEG.cpp b/src/RageSurface_Load_JPEG.cpp index 4470555f8a..0cd8494a7d 100644 --- a/src/RageSurface_Load_JPEG.cpp +++ b/src/RageSurface_Load_JPEG.cpp @@ -7,28 +7,20 @@ #include +extern "C" { +#include "jpeglib.h" +#include "jerror.h" +} + #if defined(WIN32) && !defined(__MINGW32__) // work around namespace bugs in win32/libjpeg: #define XMD_H #undef FAR -#include "jpeglib.h" -#include "jerror.h" #if defined(_MSC_VER) -#pragma comment(lib, "jpeg.lib") #pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */ #endif -#else -extern "C" { -#if defined(MACOSX) -#include <../extern/libjpeg/jpeglib.h> -#include <../extern/libjpeg/jerror.h> -#else -#include "jpeglib.h" -#include "jerror.h" -#endif -} #endif struct my_jpeg_error_mgr diff --git a/src/RageSurface_Save_JPEG.cpp b/src/RageSurface_Save_JPEG.cpp index f0a07e6c86..10a995a8ac 100644 --- a/src/RageSurface_Save_JPEG.cpp +++ b/src/RageSurface_Save_JPEG.cpp @@ -12,19 +12,10 @@ namespace jpeg { extern "C" { -#if defined(MACOSX) -#include <../extern/libjpeg/jpeglib.h> -#else #include "jpeglib.h" -#endif } } -// Pull in JPEG library here. -#if defined _MSC_VER -#pragma comment(lib, "jpeg.lib") -#endif - #define OUTPUT_BUFFER_SIZE 4096 typedef struct {