diff --git a/CMakeLists.txt b/CMakeLists.txt index 551bbca2..d88a6c1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,12 @@ ENDIF() option(ENABLE_FFMPEG "Enable ffmpeg A/V recording" ${FFMPEG_DEFAULT}) -SET(LTO_DEFAULT OFF) +SET(LTO_DEFAULT ON) + +IF(WIN32 AND CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) + # lto produces buggy binaries on gcc < 7 on win32 + SET(LTO_DEFAULT OFF) +ENDIF() OPTION(ENABLE_LTO "Compile with Link Time Optimization (gcc and clang only)" ${LTO_DEFAULT}) @@ -296,18 +301,18 @@ ENDIF() # Compiler flags IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) - SET(LTO_FLAG "") + SET(LTO_FLAGS "") IF(ENABLE_LTO) IF(CMAKE_COMPILER_IS_GNUCXX) - SET(LTO_FLAG -flto=10) + SET(LTO_FLAGS -flto=10 -ffat-lto-objects) ELSE() - SET(LTO_FLAG -flto) + SET(LTO_FLAGS -flto) ENDIF() ENDIF(ENABLE_LTO) # common optimization flags IF(NOT (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)) - SET(MY_C_OPT_FLAGS -O2 -fomit-frame-pointer ${LTO_FLAG}) + SET(MY_C_OPT_FLAGS -O2 -fomit-frame-pointer ${LTO_FLAGS}) ELSE() # LTO and -fomit-frame-pointer generate broken binaries on Lion with XCode 4.2 tools SET(MY_C_OPT_FLAGS -O2) diff --git a/cmake/HostCompile.cmake b/cmake/HostCompile.cmake new file mode 100644 index 00000000..bcba1167 --- /dev/null +++ b/cmake/HostCompile.cmake @@ -0,0 +1,29 @@ +function(host_compile src dst_cmd) + unset(link_flags) + + if(CMAKE_HOST_WIN32) + if(NOT dst MATCHES "\\.[Ee][Xx][Ee]\$") + set(dst "${dst_cmd}.exe") + endif() + + if(CMAKE_COMPILER_IS_GNUCXX) + set(link_flags -Wl,--subsystem,console) + endif() + else() + set(dst "${dst_cmd}") + endif() + + if(NOT MSVC) + # assume cc foo.c -o foo # will work on most hosts + set(compile_command cc ${src} -o ${dst} ${link_flags}) + else() + # special case for Visual Studio + set(compile_command cl ${src} /link "/out:${dst}") + endif() + + execute_process(COMMAND ${compile_command} OUTPUT_VARIABLE compile_out ERROR_VARIABLE compile_out RESULT_VARIABLE compile_result) + + if(NOT compile_result EQUAL 0) + message(FATAL_ERROR "Failed compiling ${src} for the host: ${compile_out}") + endif() +endfunction() diff --git a/cmake/PathRun.cmake b/cmake/PathRun.cmake new file mode 100644 index 00000000..2c4d6aa5 --- /dev/null +++ b/cmake/PathRun.cmake @@ -0,0 +1,71 @@ +function(make_path_run_wrapper cmd target) + get_filename_component(cmd_resolved "${cmd}" REALPATH) + get_filename_component(base_name "${cmd_resolved}" NAME) + get_filename_component(dir_name "${cmd_resolved}" DIRECTORY) + + set(source "${target}.c") + + file(WRITE "${source}" +" +#include +#include +#include + +#define BUF_SZ 4096 + +#ifdef _WIN32 + #include + #define PATH_SEP ';' + #define setenv(var, val, dummy) _putenv_s(var, val) + #define execvp my_execvp +#else + #include + #define PATH_SEP ':' +#endif + +char* dir_name = \"${dir_name}\"; +char* base_name = \"${base_name}\"; + +int main(int argc, char** argv) { + size_t dir_len = strlen(dir_name); + char* path = getenv(\"PATH\"); + size_t path_len = strlen(path); + char* new_path = malloc(dir_len + path_len + 2); + char** new_argv = malloc(sizeof(char*) * argc); + char** p; + char buf[BUF_SZ]; + + strcpy(new_path, dir_name); + new_path[dir_len] = PATH_SEP; + strcpy(new_path + dir_len + 1, path); + + setenv(\"PATH\", new_path, 1); + + free(new_path); + + p = new_argv; + *(p++) = base_name; + while (*(++argv)) *(p++) = *argv; + *p = NULL; + + execvp(base_name, new_argv); + + // this is only reached if exec failed + snprintf(buf, BUF_SZ, \"%s: exec failed\", argv[0]); + perror(buf); + + return EXIT_FAILURE; +} + +#ifdef _WIN32 +int my_execvp(char* cmd, char** argv) { + int ret = _spawnvp(_P_WAIT, cmd, argv); + if (ret == -1) return ret; + exit(ret); +} +#endif +") + + include(HostCompile) + host_compile("${source}" "${target}") +endfunction() diff --git a/cmake/UseGCCBinUtilsWrappers.cmake b/cmake/UseGCCBinUtilsWrappers.cmake index bae1a24b..43d6cad2 100644 --- a/cmake/UseGCCBinUtilsWrappers.cmake +++ b/cmake/UseGCCBinUtilsWrappers.cmake @@ -72,21 +72,32 @@ IF(NOT EXISTS ${GCC_RANLIB}) FIND_PROGRAM(GCC_RANLIB NAMES gcc-ranlib gcc-ranlib.exe GCC-RANLIB.EXE HINTS ${GCC_DIRNAME}) ENDIF() +INCLUDE(PathRun) + IF(EXISTS ${GCC_AR}) - SET(CMAKE_AR ${GCC_AR}) - MESSAGE("-- Found gcc-ar: ${CMAKE_AR}") + MESSAGE("-- Found gcc-ar: ${GCC_AR}") + + SET(target "${CMAKE_BINARY_DIR}/gcc-ar-wrap") + MAKE_PATH_RUN_WRAPPER("${GCC_AR}" "${target}") + SET(CMAKE_AR "${target}") ENDIF() IF(EXISTS ${GCC_NM}) - SET(CMAKE_NM ${GCC_NM}) - MESSAGE("-- Found gcc-nm: ${CMAKE_NM}") + MESSAGE("-- Found gcc-nm: ${GCC_NM}") + + SET(target "${CMAKE_BINARY_DIR}/gcc-nm-wrap") + MAKE_PATH_RUN_WRAPPER("${GCC_NM}" "${target}") + SET(CMAKE_NM "${target}") ENDIF() IF(EXISTS ${GCC_RANLIB}) - SET(CMAKE_RANLIB ${GCC_RANLIB}) - MESSAGE("-- Found gcc-ranlib: ${CMAKE_RANLIB}") + MESSAGE("-- Found gcc-ranlib: ${GCC_RANLIB}") + + SET(target "${CMAKE_BINARY_DIR}/gcc-ranlib-wrap") + MAKE_PATH_RUN_WRAPPER("${GCC_RANLIB}" "${target}") + SET(CMAKE_RANLIB "${target}") ENDIF() -FOREACH(VAR "GCC_AR" "GCC_NM" "GCC_RANLIB" "GCC_DIRNAME" "GCC_BASENAME" "GCC_EXE_SUFFIX") +FOREACH(VAR "GCC_AR" "GCC_NM" "GCC_RANLIB" "GCC_DIRNAME" "GCC_BASENAME" "GCC_EXE_SUFFIX" "target") UNSET(${VAR}) ENDFOREACH() diff --git a/dependencies b/dependencies index 76e2d57b..226f6601 160000 --- a/dependencies +++ b/dependencies @@ -1 +1 @@ -Subproject commit 76e2d57b891b11aeb203d906fc6c171d7d8b739e +Subproject commit 226f6601fab7f8c9e0920262cdb073c6a9279544 diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index cfe6a3c1..b024a588 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -369,19 +369,9 @@ SET(XRC_SOURCES SET(BIN2C ${CMAKE_BINARY_DIR}/bin2c) -IF(CMAKE_HOST_WIN32) - SET(BIN2C ${BIN2C}.exe) -ENDIF() +INCLUDE(HostCompile) -IF(MSVC) - ADD_CUSTOM_COMMAND(OUTPUT ${BIN2C} - COMMAND cl ${CMAKE_CURRENT_SOURCE_DIR}/bin2c.c /link "/out:${BIN2C}" - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin2c.c) -ELSE(MSVC) - ADD_CUSTOM_COMMAND(OUTPUT ${BIN2C} - COMMAND cc ${CMAKE_CURRENT_SOURCE_DIR}/bin2c.c -o ${BIN2C} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin2c.c) -ENDIF(MSVC) +HOST_COMPILE(${CMAKE_CURRENT_SOURCE_DIR}/bin2c.c ${BIN2C}) ADD_CUSTOM_COMMAND(OUTPUT wxvbam.xrs WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} @@ -389,12 +379,12 @@ ADD_CUSTOM_COMMAND(OUTPUT wxvbam.xrs DEPENDS ${XRC_SOURCES}) ADD_CUSTOM_COMMAND(OUTPUT builtin-xrc.h COMMAND ${BIN2C} wxvbam.xrs builtin-xrc.h builtin_xrs - DEPENDS ${BIN2C} wxvbam.xrs) + DEPENDS wxvbam.xrs) # use a built-in vba-over.ini if no config file present ADD_CUSTOM_COMMAND(OUTPUT builtin-over.h COMMAND ${BIN2C} ${CMAKE_CURRENT_SOURCE_DIR}/../vba-over.ini builtin-over.h builtin_over - DEPENDS ${BIN2C} ../vba-over.ini) + DEPENDS ../vba-over.ini) # I don't like duplicating/triplicating code, so I only declare # event handlers once, and copy them in other places they are needed