work around gcc lto wrappers bug with gcc 7.x
gcc lto wrapper commands such as `gcc-ar` will segfault with some versions of gcc 7.x when called via an absolute path, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80717 Generalize the mechanism for compiling a small C program on the host (currently used for bin2c for Wx resources) and use it to wrap the gcc wrappers in a little executable that prepends their dirname to PATH and runs them with `execvp()`. Make LTO default to ON again, except on win32 with gcc < 7, because those toolchains produce broken binaries with LTO enabled. Also add `-ffat-lto-objects` to compiler flags for gcc when LTO is enabled, this will increase the chances that the LTO build will succeed even if there are issues with the binutils wrappers. Clang does not support this.
This commit is contained in:
parent
b82cab14e2
commit
7f1fec88af
|
@ -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)
|
||||
|
|
|
@ -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()
|
|
@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define BUF_SZ 4096
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
#define PATH_SEP ';'
|
||||
#define setenv(var, val, dummy) _putenv_s(var, val)
|
||||
#define execvp my_execvp
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#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()
|
|
@ -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()
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 76e2d57b891b11aeb203d906fc6c171d7d8b739e
|
||||
Subproject commit 226f6601fab7f8c9e0920262cdb073c6a9279544
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue