Skip to content

Commit

Permalink
Removed Optimized build, improved gcc LTO support, add clang LTO supp…
Browse files Browse the repository at this point in the history
…ort.
  • Loading branch information
Pentarctagon authored and GregoryLundberg committed Nov 30, 2017
1 parent 0f38ce6 commit ba3e463
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 97 deletions.
145 changes: 68 additions & 77 deletions CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand All @@ -551,47 +507,82 @@ 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
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 "^/")
Expand Down
44 changes: 26 additions & 18 deletions SConstruct
Expand Up @@ -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),
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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"]
Expand Down
4 changes: 2 additions & 2 deletions src/SConscript
Expand Up @@ -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'

Expand All @@ -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'

Expand Down

0 comments on commit ba3e463

Please sign in to comment.