Commit fedd7460 authored by Ecklory's avatar Ecklory

Transition to C++ 14

parent 89be2166
import gradlecpp.RehldsPlayTestPlugin
import gradlecpp.RehldsPlayTestTask
import gradlecpp.VelocityUtils
import org.doomedsociety.gradlecpp.GradleCppUtils
import org.doomedsociety.gradlecpp.LazyNativeDepSet
import org.doomedsociety.gradlecpp.cfg.ToolchainConfig
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
import org.doomedsociety.gradlecpp.msvc.EnhancedInstructionsSet
import org.doomedsociety.gradlecpp.msvc.FloatingPointModel
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
import org.gradle.language.cpp.CppSourceSet
import org.gradle.nativeplatform.NativeBinarySpec
import org.gradle.nativeplatform.NativeExecutableSpec
import org.gradle.nativeplatform.NativeLibrarySpec
import org.gradle.nativeplatform.SharedLibraryBinarySpec
import rehlds.testdemo.RehldsDemoRunner
import versioning.RehldsVersionInfo
import org.apache.commons.io.FilenameUtils
apply plugin: 'cpp'
apply plugin: IccCompilerPlugin
apply plugin: GccCompilerPlugin
apply plugin: RehldsPlayTestPlugin
apply plugin: gradlecpp.CppUnitTestPlugin
repositories {
maven {
url 'http://nexus.rehlds.org/nexus/content/repositories/rehlds-releases/'
}
}
configurations {
rehlds_tests
}
dependencies {
rehlds_tests 'rehlds.testdemos:hl-phys-single1:1.1'
rehlds_tests 'rehlds.testdemos:crossfire-1-multiplayer-1:1.1'
rehlds_tests 'rehlds.testdemos:cstrike-muliplayer-1:1.1'
rehlds_tests 'rehlds.testdemos:shooting-hl-1:1.1'
}
project.ext.dep_bzip2 = project(':dep/bzip2')
project.ext.dep_cppunitlite = project(':dep/cppunitlite')
void createIntergrationTestTask(NativeBinarySpec b) {
boolean rehldsFixes = b.flavor.name.contains('rehldsFixes')
if (!(b instanceof SharedLibraryBinarySpec)) return
if (!GradleCppUtils.windows) return
if (rehldsFixes) return
def libLinkTask = GradleCppUtils.getLinkTask(b)
String unitTestTask = b.hasProperty('cppUnitTestTask') ? b.cppUnitTestTask : null
def depFiles = []
depFiles.addAll(libLinkTask.outputs.files.files)
def demoItgTestTask = project.tasks.create(b.namingScheme.getTaskName('demoItgTest'), RehldsPlayTestTask)
demoItgTestTask.with {
rehldsImageRoot = new File(project.projectDir, '_rehldsTestImg')
rehldsTestLogs = new File(this.project.buildDir, "_rehldsTestLogs/${b.name}")
testDemos = project.configurations.rehlds_tests
testFor = b
//inputs/outputs for up-to-date check
inputs.files depFiles
inputs.files testDemos.files
outputs.dir rehldsTestLogs
//dependencies on library and test executable
dependsOn libLinkTask
if (unitTestTask) {
dependsOn unitTestTask
}
postExtractAction {
def binaryOutFile = GradleCppUtils.getBinaryOutputFile(b)
GradleCppUtils.copyFile(binaryOutFile, new File(rehldsImageRoot, binaryOutFile.name), true)
}
}
b.buildTask.dependsOn demoItgTestTask
}
void setupUnitTests(NativeBinarySpec bin) {
boolean unitTestExecutable = bin.component.name.endsWith('_tests')
if (!unitTestExecutable) return
GradleCppUtils.getLinkTask(bin).doLast {
String srcPath = '' + projectDir + (GradleCppUtils.windows ? '/lib/steam_api.dll' : '/lib/linux32/libsteam_api.so')
String dstPath = bin.executableFile.parent + (GradleCppUtils.windows ? '/steam_api.dll' : '/libsteam_api.so')
GradleCppUtils.copyFile(srcPath, dstPath, true)
}
}
void postEvaluate(NativeBinarySpec b) {
// attach generateAppVersion task to all 'compile source' tasks
GradleCppUtils.getCompileTasks(b).each { Task t ->
t.dependsOn project.generateAppVersion
}
setupUnitTests(b)
createIntergrationTestTask(b)
}
void setupToolchain(NativeBinarySpec b) {
boolean useGcc = project.hasProperty("useGcc")
boolean unitTestExecutable = b.component.name.endsWith('_tests')
boolean swdsLib = b.name.toLowerCase().contains('swds')
boolean rehldsFixes = b.flavor.name.contains('rehldsFixes')
boolean release = b.buildType.name.toLowerCase() == 'release';
ToolchainConfig cfg = rootProject.createToolchainConfig(b)
cfg.projectInclude(project, '', '/public/rehlds', '/engine', '/common', '/pm_shared', '/rehlds', '/testsuite', '/hookers', '/public')
cfg.projectInclude(dep_bzip2, '/include')
if (unitTestExecutable) {
cfg.projectInclude(dep_cppunitlite, '/include')
b.lib LazyNativeDepSet.create(dep_cppunitlite, 'cppunitlite', b.buildType.name, true)
}
b.lib LazyNativeDepSet.create(dep_bzip2, 'bzip2', b.buildType.name, true)
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'SWDS', 'REHLDS_SELF', 'REHLDS_OPT_PEDANTIC', 'REHLDS_API'
if (cfg instanceof MsvcToolchainConfig) {
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
enabled: true,
pchHeader: 'precompiled.h',
pchSourceSet: 'rehlds_pch'
)
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
if (!rehldsFixes) {
cfg.compilerOptions.floatingPointModel = FloatingPointModel.PRECISE
cfg.compilerOptions.enhancedInstructionsSet = EnhancedInstructionsSet.DISABLED
} else {
cfg.compilerOptions.args '/Oi', '/GF', '/GR-', '/GS-'
}
if (swdsLib) {
cfg.linkerOptions.randomizedBaseAddress = false
cfg.linkerOptions.baseAddress = '0x4970000'
}
cfg.projectLibpath(project, '/lib')
cfg.extraLibs 'steam_api.lib', 'psapi.lib', 'ws2_32.lib', 'kernel32.lib', 'user32.lib', 'advapi32.lib', 'libacof32.lib'
} else if (cfg instanceof GccToolchainConfig) {
if (!useGcc) {
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
enabled: true,
pchSourceSet: 'rehlds_pch'
)
}
cfg.compilerOptions.languageStandard = 'c++11'
cfg.defines([
'_stricmp': 'strcasecmp',
'_strnicmp': 'strncasecmp',
'_strdup': 'strdup',
'_unlink': 'unlink',
'_vsnprintf': 'vsnprintf',
'_vsnwprintf' : 'vswprintf',
]);
if (useGcc) {
// Produce code optimized for the most common IA32/AMD64/EM64T processors.
// As new processors are deployed in the marketplace, the behavior of this option will change.
cfg.compilerOptions.args '-mtune=generic', '-Wno-write-strings', '-msse3'
} else {
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp'
}
cfg.compilerOptions.args '-ffunction-sections', '-fdata-sections' // Remove unused code and data
cfg.compilerOptions.args '-fno-rtti', '-fno-exceptions'
cfg.linkerOptions.args '-Wl,--version-script=../version_script.lds', '-Wl,--gc-sections'
cfg.projectLibpath(project, '/lib/linux32')
cfg.extraLibs 'rt', 'dl', 'm', 'steam_api', 'aelf32'
}
if (unitTestExecutable) {
cfg.singleDefines 'REHLDS_UNIT_TESTS', 'REHLDS_SSE', 'REHLDS_JIT'
}
if (rehldsFixes) {
cfg.singleDefines 'REHLDS_FIXES', 'REHLDS_SSE', 'REHLDS_JIT', 'REHLDS_CHECKS', 'HAVE_OPT_STRTOOLS'
}
if (!release) {
cfg.singleDefines 'REHLDS_FLIGHT_REC'
}
ToolchainConfigUtils.apply(project, cfg, b)
GradleCppUtils.onTasksCreated(project, 'postEvaluate', {
postEvaluate(b)
})
}
class RehldsSrc {
static void rehlds_src(def h) {
h.rehlds_engine(CppSourceSet) {
source {
srcDirs "engine", "rehlds", "version"
if (GradleCppUtils.windows) srcDirs "testsuite"
include "**/*.cpp"
exclude "precompiled.cpp"
}
}
h.rehlds_public(CppSourceSet) {
source {
srcDirs "public"
include "registry.cpp", "steamid.cpp", "utlbuffer.cpp", "tier0/dbg.cpp"
}
}
h.rehlds_memory(CppSourceSet) {
source {
srcDirs "hookers"
include "memory.cpp"
}
}
h.rehlds_common(CppSourceSet) {
source {
srcDirs "common"
include "BaseSystemModule.cpp", "ObjectList.cpp", "TokenLine.cpp"
}
}
}
static void rehlds_pch(def h) {
h.rehlds_pch(CppSourceSet) {
source {
srcDirs "rehlds"
include "precompiled.cpp"
}
}
}
static void rehlds_swds_main_src(def h) {
h.rehlds_swds_main_src(CppSourceSet) {
source {
srcDir "hookers"
include "engine/main_swds.cpp"
}
}
}
static void rehlds_tests_src(def h) {
h.rehlds_tests_src(CppSourceSet) {
source {
srcDir "unittests"
include "**/*.cpp"
}
}
}
}
model {
buildTypes {
debug
release
}
platforms {
x86 {
architecture "x86"
}
}
toolChains {
visualCpp(VisualCpp)
if (project.hasProperty("useGcc")) {
gcc(Gcc)
} else {
icc(Icc)
}
}
flavors {
rehldsNofixes
rehldsFixes
}
components {
rehlds_swds_engine(NativeLibrarySpec) {
targetPlatform 'x86'
baseName GradleCppUtils.windows ? 'swds' : 'engine_i486'
sources {
RehldsSrc.rehlds_pch(it)
RehldsSrc.rehlds_src(it)
RehldsSrc.rehlds_swds_main_src(it)
}
binaries.all { NativeBinarySpec b -> project.setupToolchain(b) }
}
rehlds_swds_engine_tests(NativeExecutableSpec) {
targetPlatform 'x86'
sources {
RehldsSrc.rehlds_pch(it)
RehldsSrc.rehlds_src(it)
RehldsSrc.rehlds_tests_src(it)
}
binaries.all { NativeBinarySpec b -> project.setupToolchain(b) }
}
}
}
task buildFinalize << {
if (GradleCppUtils.windows) {
return;
}
binaries.withType(SharedLibraryBinarySpec) {
def sharedBinary = it.getSharedLibraryFile();
if (sharedBinary.exists()) {
sharedBinary.renameTo(new File(sharedBinary.getParent() + "/" + sharedBinary.getName().replaceFirst("^lib", "")));
}
}
}
task buildRelease {
dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib ->
blib.buildable && blib.buildType.name == 'release'
}
}
task buildFixes {
dependsOn binaries.withType(SharedLibraryBinarySpec).matching {
SharedLibraryBinarySpec blib -> blib.buildable && blib.buildType.name == 'release' && blib.flavor.name == 'rehldsFixes' && blib.component.name == 'rehlds_swds_engine'
}
}
task buildEngine {
dependsOn binaries.withType(SharedLibraryBinarySpec).matching {
SharedLibraryBinarySpec blib -> blib.buildable && blib.buildType.name == 'release' && blib.flavor.name == 'rehldsFixes' && blib.component.name == 'rehlds_swds_engine'
}
}
buildFixes.finalizedBy(buildFinalize);
buildEngine.finalizedBy(buildFinalize);
buildRelease.finalizedBy(buildFinalize);
gradle.taskGraph.whenReady { graph ->
if (!graph.hasTask(buildFixes) && !graph.hasTask(buildEngine)) {
return;
}
// skip all tasks with the matched substrings in the name like "test"
def tasks = graph.getAllTasks();
tasks.findAll { it.name.toLowerCase().contains("test") }.each { task ->
task.enabled = false;
}
}
task prepareDevEnvTests {
def rehldsTests = new File(project.projectDir, '_dev/testDemos')
inputs.files configurations.rehlds_tests.files
outputs.dir rehldsTests
doLast {
rehldsTests.mkdirs()
configurations.rehlds_tests.files.each { File f ->
def t = zipTree(f)
copy {
into new File(rehldsTests, FilenameUtils.getBaseName(f.absolutePath))
from t
}
}
}
}
task prepareDevEnvEngine << {
['_dev/rehlds', '_dev/rehlds_swds'].each { engineDir ->
def rehldsImage = new File(project.projectDir, engineDir)
rehldsImage.mkdirs()
def demoRunner = new RehldsDemoRunner(project.configurations.rehlds_playtest_image.getFiles(), rehldsImage, null)
demoRunner.prepareEngine()
}
}
task prepareDevEnv {
dependsOn prepareDevEnvEngine, prepareDevEnvTests
}
tasks.clean.doLast {
project.file('version/appversion.h').delete()
}
task generateAppVersion {
RehldsVersionInfo verInfo = (RehldsVersionInfo) rootProject.rehldsVersionInfo
def tplFile = project.file('version/appversion.vm')
def renderedFile = project.file('version/appversion.h')
// check to up-to-date
inputs.file tplFile
inputs.file project.file('gradle.properties')
outputs.file renderedFile
// this will ensure that this task is redone when the versions change
inputs.property('version', rootProject.version)
inputs.property('commitDate', verInfo.asCommitDate())
println "##teamcity[buildNumber '" + verInfo.asMavenVersion(false) + "']";
doLast {
def templateCtx = [
verInfo : verInfo
]
def content = VelocityUtils.renderTemplate(tplFile, templateCtx)
renderedFile.delete()
renderedFile.write(content, 'utf-8')
println 'The current ReHLDS maven version is ' + rootProject.version + ', url: (' + verInfo.commitURL + '' + verInfo.commitSHA + ')';
}
}
import gradlecpp.RehldsPlayTestPlugin
import gradlecpp.RehldsPlayTestTask
import gradlecpp.VelocityUtils
import org.doomedsociety.gradlecpp.GradleCppUtils
import org.doomedsociety.gradlecpp.LazyNativeDepSet
import org.doomedsociety.gradlecpp.cfg.ToolchainConfig
import org.doomedsociety.gradlecpp.cfg.ToolchainConfigUtils
import org.doomedsociety.gradlecpp.gcc.GccToolchainConfig
import org.doomedsociety.gradlecpp.msvc.EnhancedInstructionsSet
import org.doomedsociety.gradlecpp.msvc.FloatingPointModel
import org.doomedsociety.gradlecpp.msvc.MsvcToolchainConfig
import org.doomedsociety.gradlecpp.toolchain.icc.Icc
import org.doomedsociety.gradlecpp.toolchain.icc.IccCompilerPlugin
import org.gradle.language.cpp.CppSourceSet
import org.gradle.nativeplatform.NativeBinarySpec
import org.gradle.nativeplatform.NativeExecutableSpec
import org.gradle.nativeplatform.NativeLibrarySpec
import org.gradle.nativeplatform.SharedLibraryBinarySpec
import rehlds.testdemo.RehldsDemoRunner
import versioning.RehldsVersionInfo
import org.apache.commons.io.FilenameUtils
apply plugin: 'cpp'
apply plugin: IccCompilerPlugin
apply plugin: GccCompilerPlugin
apply plugin: RehldsPlayTestPlugin
apply plugin: gradlecpp.CppUnitTestPlugin
repositories {
maven {
url 'http://nexus.rehlds.org/nexus/content/repositories/rehlds-releases/'
}
}
configurations {
rehlds_tests
}
dependencies {
rehlds_tests 'rehlds.testdemos:hl-phys-single1:1.1'
rehlds_tests 'rehlds.testdemos:crossfire-1-multiplayer-1:1.1'
rehlds_tests 'rehlds.testdemos:cstrike-muliplayer-1:1.1'
rehlds_tests 'rehlds.testdemos:shooting-hl-1:1.1'
}
project.ext.dep_bzip2 = project(':dep/bzip2')
project.ext.dep_cppunitlite = project(':dep/cppunitlite')
void createIntergrationTestTask(NativeBinarySpec b) {
boolean rehldsFixes = b.flavor.name.contains('rehldsFixes')
if (!(b instanceof SharedLibraryBinarySpec)) return
if (!GradleCppUtils.windows) return
if (rehldsFixes) return
def libLinkTask = GradleCppUtils.getLinkTask(b)
String unitTestTask = b.hasProperty('cppUnitTestTask') ? b.cppUnitTestTask : null
def depFiles = []
depFiles.addAll(libLinkTask.outputs.files.files)
def demoItgTestTask = project.tasks.create(b.namingScheme.getTaskName('demoItgTest'), RehldsPlayTestTask)
demoItgTestTask.with {
rehldsImageRoot = new File(project.projectDir, '_rehldsTestImg')
rehldsTestLogs = new File(this.project.buildDir, "_rehldsTestLogs/${b.name}")
testDemos = project.configurations.rehlds_tests
testFor = b
//inputs/outputs for up-to-date check
inputs.files depFiles
inputs.files testDemos.files
outputs.dir rehldsTestLogs
//dependencies on library and test executable
dependsOn libLinkTask
if (unitTestTask) {
dependsOn unitTestTask
}
postExtractAction {
def binaryOutFile = GradleCppUtils.getBinaryOutputFile(b)
GradleCppUtils.copyFile(binaryOutFile, new File(rehldsImageRoot, binaryOutFile.name), true)
}
}
b.buildTask.dependsOn demoItgTestTask
}
void setupUnitTests(NativeBinarySpec bin) {
boolean unitTestExecutable = bin.component.name.endsWith('_tests')
if (!unitTestExecutable) return
GradleCppUtils.getLinkTask(bin).doLast {
String srcPath = '' + projectDir + (GradleCppUtils.windows ? '/lib/steam_api.dll' : '/lib/linux32/libsteam_api.so')
String dstPath = bin.executableFile.parent + (GradleCppUtils.windows ? '/steam_api.dll' : '/libsteam_api.so')
GradleCppUtils.copyFile(srcPath, dstPath, true)
}
}
void postEvaluate(NativeBinarySpec b) {
// attach generateAppVersion task to all 'compile source' tasks
GradleCppUtils.getCompileTasks(b).each { Task t ->
t.dependsOn project.generateAppVersion
}
setupUnitTests(b)
createIntergrationTestTask(b)
}
void setupToolchain(NativeBinarySpec b) {
boolean useGcc = project.hasProperty("useGcc")
boolean unitTestExecutable = b.component.name.endsWith('_tests')
boolean swdsLib = b.name.toLowerCase().contains('swds')
boolean rehldsFixes = b.flavor.name.contains('rehldsFixes')
boolean release = b.buildType.name.toLowerCase() == 'release';
ToolchainConfig cfg = rootProject.createToolchainConfig(b)
cfg.projectInclude(project, '', '/public/rehlds', '/engine', '/common', '/pm_shared', '/rehlds', '/testsuite', '/hookers', '/public')
cfg.projectInclude(dep_bzip2, '/include')
if (unitTestExecutable) {
cfg.projectInclude(dep_cppunitlite, '/include')
b.lib LazyNativeDepSet.create(dep_cppunitlite, 'cppunitlite', b.buildType.name, true)
}
b.lib LazyNativeDepSet.create(dep_bzip2, 'bzip2', b.buildType.name, true)
cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'SWDS', 'REHLDS_SELF', 'REHLDS_OPT_PEDANTIC', 'REHLDS_API'
if (cfg instanceof MsvcToolchainConfig) {
cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig(
enabled: true,
pchHeader: 'precompiled.h',
pchSourceSet: 'rehlds_pch'
)
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
if (!rehldsFixes) {
cfg.compilerOptions.floatingPointModel = FloatingPointModel.PRECISE
cfg.compilerOptions.enhancedInstructionsSet = EnhancedInstructionsSet.DISABLED
} else {
cfg.compilerOptions.args '/Oi', '/GF', '/GR-', '/GS-'
}
if (swdsLib) {
cfg.linkerOptions.randomizedBaseAddress = false
cfg.linkerOptions.baseAddress = '0x4970000'
}
cfg.projectLibpath(project, '/lib')
cfg.extraLibs 'steam_api.lib', 'psapi.lib', 'ws2_32.lib', 'kernel32.lib', 'user32.lib', 'advapi32.lib', 'libacof32.lib'
} else if (cfg instanceof GccToolchainConfig) {
if (!useGcc) {
cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions(
enabled: true,
pchSourceSet: 'rehlds_pch'
)
}
cfg.compilerOptions.languageStandard = 'c++14'
cfg.defines([
'_stricmp': 'strcasecmp',
'_strnicmp': 'strncasecmp',
'_strdup': 'strdup',
'_unlink': 'unlink',
'_vsnprintf': 'vsnprintf',
'_vsnwprintf' : 'vswprintf',
]);
if (useGcc) {
// Produce code optimized for the most common IA32/AMD64/EM64T processors.
// As new processors are deployed in the marketplace, the behavior of this option will change.
cfg.compilerOptions.args '-mtune=generic', '-Wno-write-strings', '-msse3'
} else {
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp'
}
cfg.compilerOptions.args '-ffunction-sections', '-fdata-sections' // Remove unused code and data
cfg.compilerOptions.args '-fno-rtti', '-fno-exceptions'
cfg.linkerOptions.args '-Wl,--version-script=../version_script.lds', '-Wl,--gc-sections'
cfg.projectLibpath(project, '/lib/linux32')
cfg.extraLibs 'rt', 'dl', 'm', 'steam_api', 'aelf32'
}
if (unitTestExecutable) {
cfg.singleDefines 'REHLDS_UNIT_TESTS', 'REHLDS_SSE', 'REHLDS_JIT'
}
if (rehldsFixes) {
cfg.singleDefines 'REHLDS_FIXES', 'REHLDS_SSE', 'REHLDS_JIT', 'REHLDS_CHECKS', 'HAVE_OPT_STRTOOLS'
}
if (!release) {
cfg.singleDefines 'REHLDS_FLIGHT_REC'
}
ToolchainConfigUtils.apply(project, cfg, b)
GradleCppUtils.onTasksCreated(project, 'postEvaluate', {
postEvaluate(b)
})
}
class RehldsSrc {
static void rehlds_src(def h) {
h.rehlds_engine(CppSourceSet) {
source {
srcDirs "engine", "rehlds", "version"
if (GradleCppUtils.windows) srcDirs "testsuite"
include "**/*.cpp"
exclude "precompiled.cpp"
}
}
h.rehlds_public(CppSourceSet) {
source {
srcDirs "public"
include "registry.cpp", "steamid.cpp", "utlbuffer.cpp", "tier0/dbg.cpp"
}
}
h.rehlds_memory(CppSourceSet) {
source {
srcDirs "hookers"
include "memory.cpp"
}
}
h.rehlds_common(CppSourceSet) {
source {
srcDirs "common"
include "BaseSystemModule.cpp", "ObjectList.cpp", "TokenLine.cpp"
}
}
}
static void rehlds_pch(def h) {
h.rehlds_pch(CppSourceSet) {
source {
srcDirs "rehlds"
include "precompiled.cpp"
}
}
}
static void rehlds_swds_main_src(def h) {
h.rehlds_swds_main_src(CppSourceSet) {
source {
srcDir "hookers"
include "engine/main_swds.cpp"
}
}
}
static void rehlds_tests_src(def h) {
h.rehlds_tests_src(CppSourceSet) {