import gradlecpp.RegamedllPlayTestPlugin import gradlecpp.RegamedllPlayTestTask 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 regamedll.testdemo.RegamedllDemoRunner import versioning.RegamedllVersionInfo import org.apache.commons.io.FilenameUtils import org.apache.commons.compress.archivers.ArchiveInputStream apply plugin: 'cpp' apply plugin: IccCompilerPlugin apply plugin: RegamedllPlayTestPlugin apply plugin: gradlecpp.CppUnitTestPlugin repositories { maven { url 'http://nexus.rehlds.org/nexus/content/repositories/regamedll-releases/' } } configurations { regamedll_tests } dependencies { regamedll_tests 'regamedll.testdemos:cstrike-basic:1.0' } project.ext.dep_cppunitlite = project(':dep/cppunitlite') void createIntergrationTestTask(NativeBinarySpec b) { boolean regamedllFixes = b.flavor.name.contains('regamedllFixes') boolean mpLib = b.name.toLowerCase().contains('mp') if (!(b instanceof SharedLibraryBinarySpec)) return if (!GradleCppUtils.windows) return if (regamedllFixes) return if (!mpLib) return String unitTestTask = b.hasProperty('cppUnitTestTask') ? b.cppUnitTestTask : null def demoItgTestTask = project.tasks.create(b.namingScheme.getTaskName('demoItgTest'), RegamedllPlayTestTask) demoItgTestTask.with { regamedllImageRoot = new File(project.projectDir, '_regamedllTestImg') regamedllTestLogs = new File(this.project.buildDir, "_regamedllTestLogs/${b.name}") testDemos = project.configurations.regamedll_tests testFor = b //inputs/outputs for up-to-date check inputs.files testDemos.files outputs.dir regamedllTestLogs //dependencies on test executable if (unitTestTask) { dependsOn unitTestTask } postExtractAction { def binaryOutFile = GradleCppUtils.getBinaryOutputFile(b) def binaryOutDir = new File(project.projectDir, '/_regamedllTestImg/cstrike/dlls') GradleCppUtils.copyFile(binaryOutFile, new File(binaryOutDir, binaryOutFile.name), true) } } b.buildTask.dependsOn demoItgTestTask } void postEvaluate(NativeBinarySpec b) { // attach generateAppVersion task to all 'compile source' tasks GradleCppUtils.getCompileTasks(b).each { Task t -> t.dependsOn project.generateAppVersion } createIntergrationTestTask(b) } void setupToolchain(NativeBinarySpec b) { boolean unitTestExecutable = b.component.name.endsWith('_tests') boolean mpLib = b.name.toLowerCase().contains('mp') boolean regamedllFixes = b.flavor.name.contains('regamedllFixes') ToolchainConfig cfg = rootProject.createToolchainConfig(b) cfg.projectInclude(project, '', '/engine', '/common', '/dlls', '/game_shared', '/pm_shared', '/regamedll', '/hookers', '/public', '/public/regamedll') if (unitTestExecutable) { cfg.projectInclude(dep_cppunitlite, '/include') b.lib LazyNativeDepSet.create(dep_cppunitlite, 'cppunitlite', b.buildType.name, true) } cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'REGAMEDLL_SELF', 'REGAMEDLL_API', 'CLIENT_WEAPONS' if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( enabled: true, pchHeader: 'precompiled.h', pchSourceSet: 'regamedll_pch' ); cfg.singleDefines('_CRT_SECURE_NO_WARNINGS') if (!regamedllFixes) { cfg.compilerOptions.floatingPointModel = FloatingPointModel.PRECISE cfg.compilerOptions.enhancedInstructionsSet = EnhancedInstructionsSet.DISABLED } else { cfg.compilerOptions.args '/Oi', '/GF', '/GS-', '/GR-' } if (mpLib) { cfg.linkerOptions.randomizedBaseAddress = false cfg.linkerOptions.baseAddress = '0x4970000' } } else if (cfg instanceof GccToolchainConfig) { cfg.compilerOptions.pchConfig = new GccToolchainConfig.PrecompilerHeaderOptions( enabled: true, pchSourceSet: 'regamedll_pch' ); cfg.compilerOptions.languageStandard = 'c++0x' cfg.defines([ '_stricmp': 'strcasecmp', '_strnicmp': 'strncasecmp', '_strdup': 'strdup', '_unlink': 'unlink', '_vsnprintf': 'vsnprintf', '_write' : 'write', '_close' : 'close', '_vsnwprintf' : 'vswprintf', '_access' : 'access' ]) cfg.linkerOptions.args '-no-opt-class-analysis' cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-g0', '-fno-rtti' cfg.extraLibs 'dl', 'm', 'stdc++' } if (mpLib && GradleCppUtils.windows && !unitTestExecutable) { cfg.linkerOptions.definitionFile = "${projectDir}\\msvc\\mp.def"; } if (unitTestExecutable) { cfg.singleDefines 'REGAMEDLL_UNIT_TESTS' } else if (!mpLib) { cfg.singleDefines 'HOOK_GAMEDLL' } if (regamedllFixes) { cfg.singleDefines 'REGAMEDLL_FIXES', 'REGAMEDLL_CHECKS', 'REGAMEDLL_ADD', 'NDEBUG' } else { cfg.singleDefines 'PLAY_GAMEDLL' } ToolchainConfigUtils.apply(project, cfg, b) GradleCppUtils.onTasksCreated(project, 'postEvaluate', { postEvaluate(b) }) } class RegamedllSrc { static void regamedll_src(def h) { h.regamedll_src(CppSourceSet) { source { srcDirs "engine", "dlls", "game_shared", "pm_shared", "regamedll", "public", "version" include "**/*.cpp" exclude "precompiled.cpp" exclude "tier0/dbg.cpp", "utlsymbol.cpp", "utlbuffer.cpp" if (GradleCppUtils.windows) { exclude "tier0/platform_linux.cpp" } else { exclude "tier0/platform_win32.cpp" exclude "classes_dummy.cpp" } } } } static void regamedll_pch(def h) { h.regamedll_pch(CppSourceSet) { source { srcDirs "regamedll" include "precompiled.cpp" } } } static void regamedll_hooker_src(def h) { h.regamedll_hooker_src(CppSourceSet) { source { srcDirs "hookers" include "main.cpp", "6153_hooker.cpp", "hooker.cpp", "memory.cpp", "hooker_impl.cpp", "RegameDLLRuntimeConfig.cpp" } } } static void regamedll_mp_src(def h) { h.regamedll_mp_src(CppSourceSet) { source { srcDirs "hookers" include "main_mp.cpp" } } } static void regamedll_tests_src(def h) { h.regamedll_tests_src(CppSourceSet) { source { srcDir "unittests" include "**/*.cpp" } } } } model { buildTypes { debug release } platforms { x86 { architecture "x86" } } toolChains { visualCpp(VisualCpp) { } icc(Icc) { } } flavors { regamedllNofixes regamedllFixes } components { regamedll_hooker_gamedll(NativeLibrarySpec) { targetPlatform 'x86' baseName 'filesystem_stdio' sources { RegamedllSrc.regamedll_pch(it) RegamedllSrc.regamedll_src(it) RegamedllSrc.regamedll_hooker_src(it) } binaries.all { NativeBinarySpec b -> project.setupToolchain(b) } } regamedll_mp_gamedll(NativeLibrarySpec) { targetPlatform 'x86' baseName GradleCppUtils.windows ? 'mp' : 'cs' sources { RegamedllSrc.regamedll_pch(it) RegamedllSrc.regamedll_src(it) RegamedllSrc.regamedll_mp_src(it) } binaries.all { NativeBinarySpec b -> project.setupToolchain(b) } } regamedll_hooker_gamedll_tests(NativeExecutableSpec) { targetPlatform 'x86' sources { RegamedllSrc.regamedll_pch(it) RegamedllSrc.regamedll_src(it) RegamedllSrc.regamedll_tests_src(it) } binaries.all { NativeBinarySpec b -> project.setupToolchain(b) } } regamedll_mp_gamedll_tests(NativeExecutableSpec) { targetPlatform 'x86' sources { RegamedllSrc.regamedll_pch(it) RegamedllSrc.regamedll_src(it) RegamedllSrc.regamedll_tests_src(it) } binaries.all { NativeBinarySpec b -> project.setupToolchain(b) } } } } task buildRelease { dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib -> blib.buildable && blib.buildType.name == 'release' && !blib.name.contains('Regamedll_hooker_gamedll') } } task buildFixes { dependsOn binaries.withType(SharedLibraryBinarySpec).matching { SharedLibraryBinarySpec blib -> blib.buildable && blib.buildType.name == 'release' && blib.flavor.name == 'regamedllFixes' && blib.component.name == 'regamedll_mp_gamedll' } } gradle.taskGraph.whenReady { graph -> if (!graph.hasTask(buildFixes)) { 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 regamedllTests = new File(project.projectDir, '_dev/testDemos') inputs.files configurations.regamedll_tests.files outputs.dir regamedllTests doLast { regamedllTests.mkdirs() configurations.regamedll_tests.files.each { File f -> def t = zipTree(f) copy { into new File(regamedllTests, FilenameUtils.getBaseName(f.absolutePath)) from t } } } } task prepareDevEnvGamedll << { ['_dev/regamedll', '_dev/regamedll_mp'].each { gamedllDir -> def regamedllImage = new File(project.projectDir, gamedllDir) regamedllImage.mkdirs() def demoRunner = new RegamedllDemoRunner(project.configurations.regamedll_playtest_image.getFiles(), regamedllImage, null) demoRunner.prepareEngine() //demoRunner.prepareDemo() } } task prepareDevEnv { dependsOn prepareDevEnvGamedll, prepareDevEnvTests } tasks.clean.doLast { project.file('version/appversion.h').delete() } task generateAppVersion { RegamedllVersionInfo verInfo = (RegamedllVersionInfo) rootProject.regamedllVersionInfo def tplFile = project.file('version/appversion.vm') def renderedFile = project.file('version/appversion.h') inputs.file tplFile inputs.file project.file('gradle.properties') outputs.file renderedFile inputs.property('version', verInfo.asMavenVersion()) inputs.property('lastCommitDate', verInfo.lastCommitDate.toString()) doLast { def templateCtx = [ verInfo: verInfo ] def content = VelocityUtils.renderTemplate(tplFile, templateCtx) renderedFile.delete() renderedFile.write(content, 'utf-8') println 'The current ReGameDLL version is ' + verInfo.asVersion().toString() + ', maven version is ' + verInfo.asMavenVersion().toString() + ', commit id: ' + verInfo.commitID.toString() + ', commit author: ' + verInfo.authorCommit.toString() + ', url: (' + verInfo.urlCommits.toString() + ')'; } }