diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ba166269b58..5f1219f0577bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,40 +110,6 @@ if(NOT CMAKE_BUILD_TYPE) set( CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif(NOT CMAKE_BUILD_TYPE) -# Add additional build with optional LTO flags -MESSAGE("Adding Optimized build") -if("${ENABLE_LTO}" STREQUAL "yes") - MESSAGE("LTO is enabled for Optimized build") - set(CMAKE_CXX_FLAGS_OPTIMIZED "-O3 -march=native -flto -s" CACHE STRING "Flags for a more highly optimized build" FORCE) - set(CMAKE_C_FLAGS_OPTIMIZED "-O3 -march=native -flto -s" CACHE STRING "Flags for a more highly optimized build with LTO" FORCE) - set(CMAKE_EXE_LINKER_FLAGS_OPTIMIZED "-fuse-ld=gold" CACHE STRING "Flags for a more highly optimized build with LTO" FORCE) -else() - MESSAGE("LTO is not enabled for Optimized build") - set(CMAKE_CXX_FLAGS_OPTIMIZED "-O3 -march=native -s" CACHE STRING "Flags for a more highly optimized build without LTO" FORCE) - set(CMAKE_C_FLAGS_OPTIMIZED "-O3 -march=native -s" CACHE STRING "Flags for a more highly optimized build without LTO" FORCE) - set(CMAKE_EXE_LINKER_FLAGS_OPTIMIZED "" CACHE STRING "" FORCE) -endif() -set(CMAKE_SHARED_LINKER_FLAGS_OPTIMIZED "" CACHE STRING "Not used" FORCE) -MARK_AS_ADVANCED(CMAKE_CXX_FLAGS_OPTIMIZED CMAKE_C_FLAGS_OPTIMIZED - CMAKE_EXE_LINKER_FLAGS_OPTIMIZED CMAKE_SHARED_LINKER_FLAGS_OPTIMIZED) - -# set CMAKE_AR and CMAKE_RANLIB to use LTO-enabled variants if the build is -# Optimized and LTO is enabled -if("${CMAKE_BUILD_TYPE}" STREQUAL "Optimized" AND "${ENABLE_LTO}" STREQUAL "yes") - MESSAGE("Using gcc-ar and gcc-ranlib") - find_program(LTO_AR NAMES gcc-ar) - find_program(LTO_RANLIB NAMES gcc-ranlib) - set(CMAKE_AR "${LTO_AR}" CACHE STRING "Supports LTO" FORCE) - set(CMAKE_RANLIB "${LTO_RANLIB}" CACHE STRING "Supports LTO" FORCE) -else() - MESSAGE("Using ar and ranlib") - find_program(NON_LTO_AR NAMES ar) - find_program(NON_LTO_RANLIB NAMES ranlib) - set(CMAKE_AR "${NON_LTO_AR}" CACHE STRING "Does not support LTO" FORCE) - set(CMAKE_RANLIB "${NON_LTO_RANLIB}" CACHE STRING "Does not support LTO" FORCE) -endif() -MARK_AS_ADVANCED(LTO_AR LTO_RANLIB NON_LTO_AR NON_LTO_RANLIB) - if(NOT DEFINED ENABLE_DISPLAY_REVISION) # Test whether the code is used in a repository if not autorevision will # fail and should be disabled by default. If inside a repository enable @@ -520,16 +486,6 @@ add_definitions(-DLOCALEDIR=\\\"${LOCALEDIR}\\\") # -NDEBUG is automatically added to all release build types, so manually remove # this define from the related variables -MESSAGE ("removing NDEBUG flag from CMAKE_CXX_FLAGS_RELEASE") -separate_arguments(CMAKE_CXX_FLAGS_RELEASE) -list(REMOVE_ITEM CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG") -string(REPLACE ";" " " CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "removed NDEBUG flag" FORCE) -MESSAGE ("removing NDEBUG flag from CMAKE_C_FLAGS_RELEASE") -separate_arguments(CMAKE_C_FLAGS_RELEASE) -list(REMOVE_ITEM CMAKE_C_FLAGS_RELEASE "-DNDEBUG") -string(REPLACE ";" " " CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "removed NDEBUG flag" FORCE) MESSAGE ("removing NDEBUG flag from CMAKE_CXX_FLAGS_RELWITHDEBINFO") separate_arguments(CMAKE_CXX_FLAGS_RELWITHDEBINFO) list(REMOVE_ITEM CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG") @@ -551,40 +507,71 @@ list(REMOVE_ITEM CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG") string(REPLACE ";" " " CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}" CACHE STRING "removed NDEBUG flag" FORCE) -# add pentiumpro arch for windows builds with -O3, otherwise resulting executable may not work -if(WIN32) - separate_arguments(CMAKE_CXX_FLAGS_RELEASE) - list(APPEND CMAKE_CXX_FLAGS_RELEASE "-march=pentiumpro") - list(REMOVE_DUPLICATES CMAKE_CXX_FLAGS_RELEASE) - string(REPLACE ";" " " CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "added -march=pentiumpro" FORCE) - MESSAGE("added -march=pentiumpro to Release build") - - separate_arguments(CMAKE_C_FLAGS_RELEASE) - list(APPEND CMAKE_C_FLAGS_RELEASE "-march=pentiumpro") - list(REMOVE_DUPLICATES CMAKE_C_FLAGS_RELEASE) - string(REPLACE ";" " " CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "added -march=pentiumpro" FORCE) - MESSAGE("added -march=pentiumpro to Release build") - - separate_arguments(CMAKE_CXX_FLAGS_OPTIMIZED) - list(REMOVE_ITEM CMAKE_CXX_FLAGS_OPTIMIZED "-march=native") - list(APPEND CMAKE_CXX_FLAGS_OPTIMIZED "-march=pentiumpro") - list(REMOVE_DUPLICATES CMAKE_CXX_FLAGS_OPTIMIZED) - string(REPLACE ";" " " CMAKE_CXX_FLAGS_OPTIMIZED - "${CMAKE_CXX_FLAGS_OPTIMIZED}") - set(CMAKE_CXX_FLAGS_OPTIMIZED "${CMAKE_CXX_FLAGS_OPTIMIZED}" CACHE STRING "added -march=pentiumpro" FORCE) - MESSAGE("added -march=pentiumpro to Optimized build") +# # +# Start determining options for Release build +# # + +# reset the base Release build option +MESSAGE("Replacing default flags used for Release build with -O3") +set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "Release build flags" FORCE) +set(CMAKE_C_FLAGS_RELEASE "-O3" CACHE STRING "Release build flags" FORCE) +# set the arch to use for Release build if provided +if(ARCH) + MESSAGE("adding -march=${ARCH} to Release build") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=${ARCH}" CACHE STRING "Release build flags" FORCE) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=${ARCH}" CACHE STRING "Release build flags" FORCE) +endif(ARCH) +# add pentiumpro arch for windows builds with -O3 if no other arch provided, otherwise resulting executable may not work +if(WIN32 AND NOT ARCH) + MESSAGE("WIN32 and no arch provided, defaulting to pentiumpro") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=pentiumpro" CACHE STRING "Release build flags" FORCE) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=pentiumpro" CACHE STRING "Release build flags" FORCE) +endif(WIN32 AND NOT ARCH) + +# if compiling with LTO +if("${ENABLE_LTO}" STREQUAL "yes") +# clang and gcc require different parallelization options and linkers + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + MESSAGE("added -flto=thin to Release build") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=thin" CACHE STRING "Release build flags with LTO" FORCE) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto=thin" CACHE STRING "Release build flags with LTO" FORCE) + + MESSAGE("Using Clang LLD linker") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s -fuse-ld=lld" CACHE STRING "Linker flag for building with LTO and clang" FORCE) + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + if(NOT LTO_JOBS) + MESSAGE("LTO_JOBS not set, defaulting to 1") + set(LTO_JOBS "1" CACHE STRING "Number of threads to use for LTO with gcc" FORCE) + endif(NOT LTO_JOBS) + + MESSAGE("added -flto=${LTO_JOBS} to Release build") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=${LTO_JOBS}" CACHE STRING "Release build flags with LTO" FORCE) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto=${LTO_JOBS}" CACHE STRING "Release build flags with LTO" FORCE) + + MESSAGE("Using GCC gold linker") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s -fuse-ld=gold" CACHE STRING "Linker flag for building with LTO and gcc" FORCE) + endif() - separate_arguments(CMAKE_C_FLAGS_OPTIMIZED) - list(REMOVE_ITEM CMAKE_C_FLAGS_OPTIMIZED "-march=native") - list(APPEND CMAKE_C_FLAGS_OPTIMIZED "-march=pentiumpro") - list(REMOVE_DUPLICATES CMAKE_C_FLAGS_OPTIMIZED) - string(REPLACE ";" " " CMAKE_C_FLAGS_OPTIMIZED - "${CMAKE_C_FLAGS_OPTIMIZED}") - set(CMAKE_C_FLAGS_OPTIMIZED "${CMAKE_C_FLAGS_OPTIMIZED}" CACHE STRING "added -march=pentiumpro" FORCE) - MESSAGE("added -march=pentiumpro to Optimized build") -endif(WIN32) +# set CMAKE_AR and CMAKE_RANLIB to use LTO-enabled variants if LTO is enabled + MESSAGE("Using gcc-ar and gcc-ranlib") + find_program(LTO_AR NAMES gcc-ar) + find_program(LTO_RANLIB NAMES gcc-ranlib) + set(CMAKE_AR "${LTO_AR}" CACHE STRING "Supports LTO" FORCE) + set(CMAKE_RANLIB "${LTO_RANLIB}" CACHE STRING "Supports LTO" FORCE) +else() + MESSAGE("Using ar, ranlib, and default linker") + find_program(NON_LTO_AR NAMES ar) + find_program(NON_LTO_RANLIB NAMES ranlib) + set(CMAKE_AR "${NON_LTO_AR}" CACHE STRING "Does not support LTO" FORCE) + set(CMAKE_RANLIB "${NON_LTO_RANLIB}" CACHE STRING "Does not support LTO" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE STRING "Default linker" FORCE) +endif() +MARK_AS_ADVANCED(LTO_AR LTO_RANLIB NON_LTO_AR NON_LTO_RANLIB) + +# # +# End determining options for Release build +# Start setting options for Debug build +# # # replace the default Debug flag of -g with -O0 -DDEBUG -ggdb3 # this matches the flags of scons' debug build @@ -592,6 +579,10 @@ MESSAGE("Replacing flags used for Debug build") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG -ggdb3" CACHE STRING "change cmake's Debug flags to match scons' flags" FORCE) set(CMAKE_C_FLAGS_DEBUG "-O0 -DDEBUG -ggdb3" CACHE STRING "change cmake's Debug flags to match scons' flags" FORCE) +# # +# End setting options for Debug build +# # + # When the path starts with a / on a Unix system it's an absolute path. # This means that on Windows the path used is always relative. if(LOCALEDIR MATCHES "^/") diff --git a/SConstruct b/SConstruct index 3fd895c758ed0..3e0da8555645a 100755 --- a/SConstruct +++ b/SConstruct @@ -47,15 +47,15 @@ def OptionalPath(key, val, env): opts.AddVariables( ListVariable('default_targets', 'Targets that will be built if no target is specified in command line.', "wesnoth,wesnothd", Split("wesnoth wesnothd campaignd test")), - EnumVariable('build', 'Build variant: debug, release profile or base (no subdirectory)', "release", ["optimized", "release", "debug", "glibcxx_debug", "profile", "base"]), + EnumVariable('build', 'Build variant: debug, release profile or base (no subdirectory)', "release", ["release", "debug", "glibcxx_debug", "profile", "base"]), PathVariable('build_dir', 'Build all intermediate files(objects, test programs, etc) under this dir', "build", PathVariable.PathAccept), ('extra_flags_config', "Extra compiler and linker flags to use for configuration and all builds. Whether they're compiler or linker is determined by env.ParseFlags. Unknown flags are compile flags by default. This applies to all extra_flags_* variables", ""), ('extra_flags_base', 'Extra compiler and linker flags to use for release builds', ""), ('extra_flags_release', 'Extra compiler and linker flags to use for release builds', ""), ('extra_flags_debug', 'Extra compiler and linker flags to use for debug builds', ""), ('extra_flags_profile', 'Extra compiler and linker flags to use for profile builds', ""), - ('extra_flags_optimized', 'Extra compiler and linker flags to use for optimized builds', ""), - BoolVariable('enable_lto', 'Whether to enable Link Time Optimization', False), + BoolVariable('enable_lto', 'Whether to enable Link Time Optimization for build=release', False), + ('arch', 'What -march option to use for build=release, will default to pentiumpro on Windows', ""), PathVariable('bindir', 'Where to install binaries', "bin", PathVariable.PathAccept), ('cachedir', 'Directory that contains a cache of derived files.', ''), PathVariable('datadir', 'read-only architecture-independent game data', "$datarootdir/$datadirname", PathVariable.PathAccept), @@ -172,6 +172,8 @@ if env.get('cxxtool',""): if env['jobs'] > 1: SetOption("num_jobs", env['jobs']) +else: + env['jobs'] = 1 if env['distcc']: env.Tool('distcc') @@ -479,22 +481,29 @@ for env in [test_env, client_env, env]: if env['sanitize']: env.AppendUnique(CCFLAGS = ["-fsanitize=" + env["sanitize"]], LINKFLAGS = ["-fsanitize=" + env["sanitize"]]) - env["OPT_FLAGS"] = "-O3" env["DEBUG_FLAGS"] = Split("-O0 -DDEBUG -ggdb3") -# because apparently telling the compiler, linker, AND windres to be 32-bit just isn't enough - if env["PLATFORM"] == 'win32': - env["ARCH"] = "-march=pentiumpro" - env["OPT_FLAGS"] = env["OPT_FLAGS"] + " " + env["ARCH"] - else: - env["ARCH"] = "-march=native" + env["OPT_COMP_FLAGS"] = "-O3" + if env["arch"]: + env["arch"] = " -march=" + env["arch"] +# without setting to pentiumpro, compiling on Windows with 64-bit tdm-gcc and -O3 currently fails +# therefore, set to pentiumpro if nothing else has been specified + if env["PLATFORM"] == "win32" and not env["arch"]: + env["arch"] = " -march=pentiumpro" + +# set the -march option if windows or something was passed in + env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + env["arch"] + +# if building with LTO enabled if env["enable_lto"] == True: - env["HIGH_OPT_COMP_FLAGS"] = "-O3 " + env["ARCH"] + " -flto -s" - env["HIGH_OPT_LINK_FLAGS"] = env["HIGH_OPT_COMP_FLAGS"] + " -fuse-ld=gold" - else: - env["HIGH_OPT_COMP_FLAGS"] = "-O3 " + env["ARCH"] + " -s" - env["HIGH_OPT_LINK_FLAGS"] = "" +# gcc and clang need different LTO options and linkers + if env["CC"] == "gcc": + env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -flto=" + str(env["jobs"]) + env["OPT_LINK_FLAGS"] = env["OPT_COMP_FLAGS"] + " -s -fuse-ld=gold" + elif "clang" in env["CXX"]: + env["OPT_COMP_FLAGS"] = env["OPT_COMP_FLAGS"] + " -flto=thin" + env["OPT_LINK_FLAGS"] = env["OPT_COMP_FLAGS"] + " -s -fuse-ld=lld" if "clang" in env["CXX"]: # Silence warnings about unused -I options and unknown warning switches. @@ -540,9 +549,8 @@ builds = { "base" : dict(CCFLAGS = Split("$OPT_FLAGS")), # Don't build in subdirectory "debug" : dict(CCFLAGS = Split("$DEBUG_FLAGS")), "glibcxx_debug" : dict(CPPDEFINES = Split("_GLIBCXX_DEBUG _GLIBCXX_DEBUG_PEDANTIC")), - "release" : dict(CCFLAGS = Split("$OPT_FLAGS")), - "profile" : dict(CCFLAGS = "-pg", LINKFLAGS = "-pg"), - "optimized" : dict(CCFLAGS = Split("$HIGH_OPT_COMP_FLAGS"), LINKFLAGS=Split("$HIGH_OPT_LINK_FLAGS")) + "release" : dict(CCFLAGS = Split("$OPT_COMP_FLAGS"), LINKFLAGS=Split("$OPT_LINK_FLAGS")), + "profile" : dict(CCFLAGS = "-pg", LINKFLAGS = "-pg") } builds["glibcxx_debug"].update(builds["debug"]) build = env["build"] diff --git a/src/SConscript b/src/SConscript index f750843c95917..1e96aa9c4d8f3 100644 --- a/src/SConscript +++ b/src/SConscript @@ -105,7 +105,7 @@ env_lua = env.Clone( CPPPATH = ["$CPPPATH", Dir(".").srcnode()], CPPDEFINES = ["$CPPDEFINES", env["PLATFORM"] != "win32" and "LUA_USE_POSIX" or []]) -if env_lua["build"] == "optimized" and env_lua["enable_lto"] == True: +if env_lua["enable_lto"] == True: env_lua["AR"] = 'gcc-ar' env_lua["RANLIB"] = 'gcc-ranlib' @@ -127,7 +127,7 @@ def error_action(target, source, env): raise UserError("Target disabled because its prerequisites are not met") def WesnothProgram(env, target, source, can_build, **kw): - if env["build"] == "optimized" and env["enable_lto"] == True: + if env["enable_lto"] == True: env["AR"] = 'gcc-ar' env["RANLIB"] = 'gcc-ranlib'